it-swarm-es.com

¿Cómo puedo deshabilitar una sola casilla de verificación en un elemento FAPI de 'casillas de verificación'?

El título básicamente lo dice todo, quiero deshabilitar una sola casilla de verificación de un elemento casillas de verificación tipo FAPI.

No quiero hacer si con JavaScript, ni cambiarlo de casillas de verificación a múltiples casilla de verificación elementos una opción ya que el elemento es proporcionado por otro módulo.

Pensamientos?

31
Decipher

Existe una forma limpia en Drupal 7! Aparentemente, por esta publicación , aún no está documentado.

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#disabled'] = TRUE; //disables all options
  $form['checkboxes_element'][abc]['#disabled'] = TRUE; //disables option, called abc
}

Otro ejemplo .

También puede establecer la función # acceso en FALSO, para ocultar completamente la casilla de verificación.

36
timofey.com

Desafortunadamente, no hay una forma realmente limpia de hacerlo en FAPI. Su mejor opción, si está decidido, es alterar una función de proceso adicional # en el elemento de casillas de verificación.

La función predeterminada agregada a los elementos del tipo 'casillas de verificación' es en realidad una función ( expand_checkboxes () ) divide el elemento individual en múltiples elementos del tipo 'casilla de verificación 'que luego se fusionan de nuevo en uno. Si tuviera que aprovechar su segunda función de proceso, podría alcanzar el grupo expandido de elementos de 'casilla de verificación' y desactivar el en cuestión.

El siguiente código no se ha probado por completo, por lo que se debe advertir:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#process'][] = 'mymodule_disable_element';
}

function mymodule_disable_element($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#disabled'] = TRUE;
      return;
    }
  }
}
23
Eaton

Aquí está mi código para Drupal 7, para cambiar el elemento Roles en la página Editar usuario.

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#pre_render'][] = 'form_process_checkboxes'; // I had to add this one, or it will return the first role only with my callback bellow
  $form['checkboxes_element']['#pre_render'][] = 'mymodule_disable_element';
}

function mymodule_disable_element(($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#attributes']['disabled'] = 'disabled';
    }
  }
  return $element;
}
6
aFeijo

Estoy usando casillas de verificación como "asignar" y "no asignar". El cliente me ha pedido que desactive "desasignar", pero aún es importante representar "asignación". Teniendo en cuenta que las casillas de verificación DESACTIVADAS se envían como "falsas" y, si no se manejan correctamente, se desasignarán, divido mis casillas de verificación en "procesarlas" e "ignorar estas deshabilitadas". Así es cómo:

// Provide LIVE checkboxes only for un-assigned Partners
$form['partner']['partners'] = array(
  '#type' => 'checkboxes',
  '#options' => array_diff($partners, $assignments),
  '#title' => t($partnername),
);
// Provide DISABLED checkboxes for assigned Partners (but with a different variable, so it doesn't get processed as un-assignment)
$form['partner']['partner_assignments'] = array(
  '#type' => 'checkboxes',
  '#options' => $assignments,
  '#default_value' => array_keys($assignments),
  '#disabled' => TRUE,
  '#title' => t($partnername),
);

Tenga en cuenta que 'partner_assignments' es su propia matriz/variable y no se procesará como "unassign", en mi caso de uso. Gracias por publicar, me llevó a esta solución.

3
texas-bronius

D7 Aquí teníamos que asegurarnos de que al agregar un nodo, una determinada opción de referencia de término de taxonomía siempre no se puede marcar y siempre se guardará en el nodo. Así que entramos en #after_build y deshabilitamos esa determinada opción, pero tuvimos que asegurarnos de que al final esa opción se pasará. Porque solo deshabilitarlo habría detenido el viaje de esa opción a ganchos futuros.

// a constant
define('MYTERM', 113);

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
    if ($form_id == 'MYCONTENTTYPE_node_form') {
    $form['#after_build'][] = 'MYMODULE_MYCONTENTTYPE_node_form_after_build';
    }
}

/**
 * Implements custom after_build_function()
 */
function MYMODULE_MYCONTENTTYPE_node_form_after_build($form, &$form_state) {
  foreach (element_children($form['field_MYFIELD'][LANGUAGE_NONE]) as $tid) {
    if ($tid == MYTERM) {
      $element = &$form['field_MYFIELD'][LANGUAGE_NONE][$tid];
      $element['#checked'] = TRUE;
      $element['#attributes']['disabled'] = 'disabled';
    }
  }
  // here's ensured the term's travel goes on
  $form['field_MYFIELD'][LANGUAGE_NONE]['#value'] += drupal_map_assoc(array(MYTERM));
  return $form;
}

Así es como se ve la opción deshabilitada:

enter image description here

3
leymannx

No pude conseguir que la respuesta de Eaton funcionara tal como está escrita (la devolución de llamada #process no devuelve nada, y se llama antes de que se expandan las casillas de verificación) y también quería que el valor regresara de la casilla deshabilitada (quería que estuviera marcada permanentemente ) Esto funcionó para mí (D6).

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#process'][] = 'mymodule_disable_element';
}

function mymodule_disable_element($element) {
  $expanded = expand_checkboxes($element);
  $checkbox =& $expanded[YOUR_CHECK_VALUE];
  $checkbox['#disabled'] = TRUE;
  $checkbox['#value_callback'] = 'mymodule_element_value_callback';
  return $expanded;
}

function mymodule_element_value_callback($element, $edit = FALSE) {
  // Return whatever value you'd like here, otherwise the element will return
  // FALSE because it's disabled.
  return 'VALUE';
}

Si alguien conoce una forma más ordenada, ¡me encantaría escucharla!

2
Andy

En Drupal 7, para deshabilitar las opciones en una selección en una entidad de campo, descubrí que tenía que instalar un #process función. Desafortunadamente, esto deshabilitó la función de proceso incorporada, form_process_checkboxes, por lo que debe agregarse nuevamente (o llamarse desde la función de proceso). Además, al deshabilitar las casillas de verificación que ya están marcadas, descubrí que el valor de devolución de llamada incorporado (form_type_checkboxes_value) ignora los valores predeterminados al recuperar resultados de la entrada.

$field_lang_form = &$your_form[$field][LANGUAGE_NONE];
$field_lang_form['#process'][] = 'form_process_checkboxes';
$field_lang_form['#process'][] = 'YOURMODULE_YOURFUNCTION_process';
$field_lang_form['#value_callback'] = 'YOURMODULE_form_type_checkboxes_value';

Entonces algo como esto:

function YOURMODULE_YOURFUNCTION_process($element) {
  // Disallow access YOUR REASON, but show as disabled if option is set.
  foreach (element_children($element) as $field) {
    if (REASON TO DISABLE HERE) {
      if (!empty($element[$field]['#default_value'])) {
        $element[$field]['#disabled'] = TRUE;
      } else {
        $element[$club]['#access'] = FALSE;
      }
    }
  }
  return $element;
}

Y finalmente:

function YOURMODULE_form_type_checkboxes_value($element, $input = FALSE) {
  if ($input !== FALSE) {
    foreach ($element['#default_value'] as $value) {
      if (THIS OPTION WAS SET AND DISABLED - YOUR BUSINESS LOGIC) {
        // This option was disabled and was not returned by the browser. Set it manually.
        $input[$value] = $value;
      }
    }
  }
  return form_type_checkboxes_value($element, $input);
}

No encontré que ninguna de las otras respuestas en esta página funcionó en este caso.

1
Dan Chadwick

Aquí está mi ejemplo (usando #after_build):

$form['legal']['legal_accept']['#type'] = 'checkboxes';
$form['legal']['legal_accept']['#options'] = $options;
$form['legal']['legal_accept']['#after_build'][] = '_process_checkboxes';

Además de la siguiente devolución de llamada de función:

function _process_checkboxes($element) {
  foreach (element_children($element) as $key) {
    if ($key == 0) { // value of your checkbox, 0, 1, etc.
      $element[$key]['#attributes'] = array('disabled' => 'disabled');
      // $element[$key]['#theme'] = 'hidden'; // hide completely
    }
  }
  return $element;
}

Probado en Drupal 6, pero debería funcionar para Drupal 7 también.


Drupal 6

Puede usar la siguiente función ( fuente ):

/*
 * Change options for individual checkbox or radio field in the form
 * You can use this function using form_alter hook.
 * i.e. _set_checkbox_option('field_tier_level', 'associate', array('#disabled' => 'disabled'), $form);
 *
 * @param $field_name (string)
 *    Name of the field in the form
 * @param $checkbox_name (string)
 *    Name of checkbox to change options (if it's null, set to all)
 * @param $options (array)
 *    Custom options to set
 * @param $form (array)
 *    Form to change
 *
 * @author kenorb at gmail.com
 */
function _set_checkbox_option($field_name, $checkbox_name = NULL, $options, &$form) {
    if (isset($form[$field_name]) && is_array($form[$field_name])) {
        foreach ($form[$field_name] as $key => $value) {
            if (isset($form[$field_name][$key]['#type'])) {
                $curr_arr = &$form[$field_name][$key]; // set array as current
                $type = $form[$field_name][$key]['#type'];
                break;
            }
        }
        if (isset($curr_arr) && is_array($curr_arr['#default_value'])) {
            switch ($type) { // changed type from plural to singular
                case 'radios':
                    $type = 'radio';
                    break;
                case 'checkboxes':
                    $type = 'checkbox';
                    break;
            }

            foreach ($curr_arr['#default_value'] as $key => $value) {
                foreach($curr_arr as $old_key => $old_value) { // copy existing options for to current option
                    $new_options[$old_key] = $old_value;
                }
                $new_options['#type'] = $type;  // set type
                $new_options['#title'] = $value;  // set correct title of option
                $curr_arr[$key] = $new_options; // set new options

                if (empty($checkbox_name) || strcasecmp($checkbox_name, $value) == 0) { // check name or set for 
                    foreach($options as $new_key => $new_value) {
                        $curr_arr[$key][$new_key] = $value;
                    }
                }
            }
            unset($curr_arr['#options']); // delete old options settings
        } else {
            return NULL;
        }
    } else {
        return NULL;
    }
}

/*
 * Disable selected field in the form(whatever if it's textfield, checkbox or radio)
 * You can use this function using form_alter hook.
 * i.e. _disable_field('title', $form);
 *
 * @param $field_name (string)
 *    Name of the field in the form
 * @param $form (array)
 *    Form to change
 *
 * @author kenorb at gmail.com
 */
function _disable_field($field_name, &$form) {
    $keyname = '#disabled';

    if (!isset($form[$field_name])) { // case: if field doesn't exists, put keyname in the main array
        $form[$keyname] = TRUE;
    } else if (!isset($form[$field_name]['#type']) && is_array($form[$field_name])) { // case: if type not exist, find type from inside of array
        foreach ($form[$field_name] as $key => $value) {
            if (isset($form[$field_name][$key]['#type'])) {
                $curr_arr = &$form[$field_name][$key]; // set array as current
                break;
            }
        }
    } else {
        $curr_arr = &$form[$field_name]; // set field array as current
    }

    // set the value
    if (isset($curr_arr['#type'])) {
        switch ($curr_arr['#type']) {
            case 'textfield':
            default:
                $curr_arr[$keyname] = TRUE;
        }
    }
}
1
kenorb

Aquí está mi código para Drupal 7, para cambiar el elemento Roles en la página Editar usuario.

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#pre_render'][] = 'form_process_checkboxes'; // I had to add this one, or it will return the first role only with my callback bellow
  $form['checkboxes_element']['#pre_render'][] = 'mymodule_disable_element';
}

function mymodule_disable_element(($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#attributes']['disabled'] = 'disabled';
      return $element;
    }
  }
  return $element;
}
1
jrockowitz

Enganche el campo de texto y cree un cuadro de texto dinámico con información de la base de datos

1 ° obtener la asociación. matriz de la base de datos, por ejemplo

$blah = array('test1' => 'Choose for test1', 'test2' => 'Choose for test2', ...)

2 ° Implementa hook_form_alter()

/ ** * Implementa hook_form_alter (). * id de formulario = vistas-expuestas-formulario * /

function test_form_alter(&$form, &$form_state, $form_id)
{
  //only for this particular form
  if ($form['#id'] == "views-exposed-form-advanced-search-page-2")
    {
       $form['phases'] = array(
           '#type' => 'checkboxes',
           '#options' => $blah,
      );
    }
}

¡3 ° campos múltiples serán verificables!

0
Mathieu Dierckx

Si está creando su propio formulario, en lugar de ejecutar funciones separadas de form_alter/# process/# pre_render, puede cambiar de 'casillas de verificación' a generar elementos 'checkbox' individuales.

$options = array(
   1 => t('Option one'),
   2 => t('Option two'),
);

// Standard 'checkboxes' method:
$form['my_element'] = array(
  '#type' => 'checkboxes',
  '#title' => t('Some checkboxes'),
  '#options' => $options,
);

// Individual 'checkbox' method:
$form['my_element'] = array(
  '#type' => 'container',
  '#attributes' => array('class' => array('form-checkboxes')),
  '#tree' => TRUE,
  'label' => array('#markup' => '<label>' . t('Some checkboxes') . '</label>',
);
foreach ($options as $key => $label) {
  $form['my_element'][$key] = array(
    '#type' => 'checkbox',
    '#title' => $label,
    '#return_value' => $key,
  );
}
// Set whatever #disabled (etc) properties you need.
$form['my_element'][1]['#disabled'] = TRUE;

'#tree' => TRUE Le ofrece la misma estructura de árbol que la versión de casillas de verificación cuando la matriz $ form_state ['values'] llega a la validación/envío/reconstrucción. Si no puede o no quiere usar #tree por alguna razón, asigne a cada casilla de verificación una propiedad '#parents' => array('my_element', $key) para establecer explícitamente su posición en la estructura de valores.

0
KingAndy

Estoy usando el siguiente código en drupal 6: -

$form['statuses'] = array(
    '#type' => 'checkboxes',
    '#options' => $statuses,
    '#default_value' => $status_val,
    '#after_build' => array('legal_process_checkboxes')
    );

y la función de devolución de llamada está aquí: -

/ ** * Procesar cada casilla de verificación basada en 'feture' ya está siendo utilizada por un Subdominio o no. * @param Array $ element array de casillas de verificación de formulario * /

function legal_process_checkboxes($element) {

  foreach (element_children($element) as $key) {

    $feature_id = $key;
    $res_total = '';

    $total = feature_used($feature_id) ;

    if ($total) {
      $element[$key]['#attributes'] = array('disabled' => 'disabled');
    }
  }
  return $element;
}
0
Sandip Ghosh

Una cosa importante a tener en cuenta es que las casillas de verificación deshabilitadas no se envían, por lo que es posible que deba forzar el #value de la casilla de verificación también .. Por ejemplo:

$element['child1']['#disabled'] = TRUE;
$element['child1']['#value'] = 'child1';

En mi caso, sin esto, el $form_state['values'] no contenía el valor de mi casilla de verificación (que estaba habilitado de forma predeterminada, pero deshabilitado).

0
Nick