web-dev-qa-db-fra.com

Comment puis-je désactiver une seule case à cocher dans un élément FAPI «cases à cocher»?

Le titre dit tout, je veux désactiver une seule case à cocher d'un élément FAPI de type cases à cocher.

Je ne veux pas faire si avec JavaScript, ni le changer de cases à cocher à plusieurs éléments checkbox une option car l'élément est fourni par un autre module.

Pensées?

31
Decipher

Une manière propre existe dans Drupal 7! Apparemment, par ce post , ce n'est pas encore documenté.

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
}

Un autre exemple .

Vous pouvez également définir la fonction # access sur FALSE, pour masquer complètement la case à cocher.

36
timofey.com

Malheureusement, il n'y a pas de moyen vraiment propre de le faire dans FAPI. Votre meilleur pari - si vous êtes déterminé - est de modifier un # fonction de processus supplémentaire sur l'élément cases à cocher.

La fonction par défaut ajoutée aux éléments de type `` cases à cocher '' est en fait une fonction ( expand_checkboxes () ) divise l'élément unique en plusieurs éléments de type `` case à cocher '' qui sont ensuite fusionnés en un seul. Si vous deviez superposer votre deuxième fonction de processus, elle pourrait atteindre le groupe étendu d'éléments de "case à cocher" et désactiver celui en question.

Le code suivant est totalement non testé, donc mettez en garde emptor:

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

Voici mon code pour Drupal 7, pour changer l'élément Roles dans la page Edit User.

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

J'utilise des cases à cocher comme "attribuer" et "annuler l'attribution". Le client a demandé que je désactive "annuler l'attribution", mais il est toujours important de représenter "l'affectation". Gardant à l'esprit que les cases à cocher DÉSACTIVÉES sont soumises comme "fausses" et si elles ne sont pas gérées correctement, je les désaffecterai, je divise mes cases à cocher en "traiter celles-ci" et "ignorer celles désactivées". Voici comment:

// 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),
);

Notez que "partner_assignments" est son propre tableau/variable et ne sera pas traité comme "unassign", dans mon cas d'utilisation. Merci d'avoir posté - cela m'a conduit à cette solution.

3
texas-bronius

D7. Ici, nous devions nous assurer que lors de l'ajout d'un nœud, une certaine option de référence de terme de taxonomie est toujours incontrôlable et sera toujours enregistrée dans le nœud. Nous sommes donc allés dans #after_build et avons désactivé cette certaine option, mais nous avons dû nous assurer qu'à la fin, cette option sera transmise. Parce que la désactiver uniquement aurait arrêté le déplacement de cette option vers les futurs crochets.

// 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;
}

Voilà à quoi ressemble l'option désactivée:

enter image description here

3
leymannx

Je n'ai pas pu faire fonctionner la réponse d'Eaton telle qu'elle est écrite (le rappel #process ne renvoie rien, et il est appelé avant que les cases à cocher ne soient développées) et je voulais également que la valeur soit renvoyée par la case à cocher désactivée (je voulais qu'elle soit vérifiée en permanence ). Cela a fonctionné pour moi (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 quelqu'un connaît une manière plus nette, j'aimerais l'entendre!

2
Andy

Dans Drupal 7, afin de désactiver les options dans une sélection dans une entité champable, j'ai constaté que je devais installer un #process une fonction. Malheureusement, cela a désactivé la fonction de processus intégrée, form_process_checkboxes, qui doit donc être ajouté (ou appelé à partir de votre fonction de processus). De plus, lors de la désactivation des cases à cocher qui sont déjà cochées, j'ai découvert que le rappel de la valeur intégrée (form_type_checkboxes_value) ignore les valeurs par défaut lors de la récupération des résultats de l'entrée.

$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';

Alors quelque chose comme ça:

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;
}

Et enfin:

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);
}

Je n'ai trouvé aucune des autres réponses sur cette page fonctionnant dans ce cas.

1
Dan Chadwick

Voici mon exemple (en utilisant #after_build):

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

Plus le rappel de fonction suivant:

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;
}

Testé sur Drupal 6, mais cela devrait également fonctionner pour Drupal 7.


Drupal 6

Vous pouvez utiliser la fonction suivante ( source ):

/*
 * 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

Voici mon code pour Drupal 7, pour changer l'élément Roles dans la page Edit User.

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

Accrochez le champ de texte et créez une zone de texte dynamique avec les informations de la base de données

1 ° obtenir l'assoc. tableau de la base de données par exemple

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

2 ° Implémente hook_form_alter()

/ ** * Implémente hook_form_alter (). * form id = vues-exposés-forme * /

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 ° plusieurs champs seront vérifiables!

0
Mathieu Dierckx

Si vous créez votre propre formulaire, au lieu d'exécuter des fonctions form_alter/# process/# pre_render distinctes, vous pouvez simplement passer des `` cases à cocher '' à la génération d'éléments de `` cases à cocher '' individuels.

$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 Vous donne la même structure arborescente que la version des cases à cocher lorsque le tableau $ form_state ['values'] arrive lors de la validation/soumission/reconstruction. Si vous ne pouvez pas ou ne voulez pas utiliser #tree pour une raison quelconque, donnez à chaque case à cocher une propriété '#parents' => array('my_element', $key) pour définir explicitement sa position dans la structure des valeurs.

0
KingAndy

J'utilise ce code suivant à drupal 6: -

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

et la fonction de rappel est ici: -

/ ** * Traiter chaque case à cocher en fonction de 'feture' est déjà utilisé par un sous-domaine ou non. * @param Array $ element tableau de cases à cocher de formulaire * /

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

Une chose importante à prendre en compte est que les cases à cocher désactivées ne sont pas soumises, vous pouvez donc constater que vous devez forcer le #value de la case à cocher aussi. Par exemple:

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

Dans mon cas, sans cela, le $form_state['values'] ne contenait pas ma valeur de case à cocher (qui était activée par défaut, mais désactivée).

0
Nick