it-swarm.it

Come posso disabilitare una singola casella di controllo in un elemento FAPI 'checkboxes'?

Il titolo in pratica dice tutto, voglio disabilitare una singola casella di controllo di un elemento FAPI .

Non voglio farlo se con JavaScript, né lo sto cambiando da caselle di controllo a più casella di controllo elementi un'opzione poiché l'elemento è fornito da un altro modulo.

Pensieri?

31
Decipher

Esiste un modo chiaro in Drupal 7! Apparentemente, per questo post , non è ancora documentato.

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 altro esempio .

Puoi anche impostare # access su FALSE, per nascondere completamente la casella di controllo.

36
timofey.com

Sfortunatamente non c'è un modo davvero pulito per farlo in FAPI. La tua scommessa migliore - se sei determinato - è quella di modificare un ulteriore # funzione di processo sull'elemento delle caselle di controllo.

La funzione predefinita aggiunta agli elementi di tipo "caselle di controllo" è in realtà una funzione ( expand_checkboxes () ) suddivide il singolo elemento in più elementi di tipo "checkbox" che vengono successivamente riuniti in uno. Se dovessi trasferire sulle spalle la tua seconda funzione di processo, potrebbe raggiungere il gruppo espanso di elementi "checkbox" e disabilitare quello in questione.

Il seguente codice è completamente non testato, quindi avvertimento 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

Ecco il mio codice per Drupal 7, per modificare l'elemento Ruoli nella pagina Modifica utente.

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

Sto usando le caselle di controllo come "Assegna" e "Annulla assegnazione". Il client mi ha chiesto di disabilitare "unassign", ma è comunque importante rappresentare "assegnazione". Tenendo presente che le caselle di controllo DISABILITATE vengono inviate come "false" e se non gestite correttamente verranno annullate, ho diviso le caselle di controllo in "elabora" e "ignora quelle disabilitate". Ecco come:

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

Si noti che "partner_assignments" è la propria matrice/variabile e non verrà elaborato come "unassign", nel mio caso d'uso. Grazie per la pubblicazione-- mi ha portato a questa soluzione.

3
texas-bronius

D7. Qui dovevamo assicurarci che quando si aggiunge un nodo una certa opzione di riferimento del termine tassonomia è sempre deselezionabile e verrà sempre salvata sul nodo. Quindi siamo entrati in #after_build e disabilitato quella determinata opzione, ma dovevamo assicurarci che alla fine tale opzione venisse trasmessa. Perché solo disabilitarlo avrebbe fermato il viaggio di quell'opzione verso futuri hook.

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

Ecco come appare l'opzione disabilitata:

enter image description here

3
leymannx

Non sono riuscito a far funzionare la risposta di Eaton come scritto (il callback #process non restituisce nulla ed è chiamato prima dell'espansione delle caselle di controllo) e volevo anche che il valore fosse restituito dalla casella di controllo disabilitata (volevo che fosse controllato in modo permanente ). Questo ha funzionato per me (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';
}

Se qualcuno conosce un modo più ordinato, mi piacerebbe ascoltarlo!

2
Andy

In Drupal 7, per disabilitare le opzioni in una selezione in un'entità fieldable, ho scoperto che dovevo installare un #process funzione. Sfortunatamente, questo ha disabilitato la funzione di processo integrata, form_process_checkboxes, quindi è necessario aggiungere nuovamente (o richiamare dalla funzione di processo). Inoltre, disabilitando le caselle di controllo già selezionate, ho scoperto che il callback del valore incorporato (form_type_checkboxes_value) ignora i valori predefiniti durante il recupero dei risultati dall'input.

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

Quindi qualcosa del genere:

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

E infine:

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

Non ho trovato che nessuna delle altre risposte in questa pagina ha funzionato in questo caso.

1
Dan Chadwick

Ecco il mio esempio (usando #after_build):

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

Più la seguente funzione di richiamata:

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

Testato su Drupal 6, ma dovrebbe funzionare anche per Drupal 7).


Drupal 6

È possibile utilizzare la seguente funzione ( fonte ):

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

Ecco il mio codice per Drupal 7, per modificare l'elemento Ruoli nella pagina Modifica utente.

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

Aggancia il campo di testo e crea una casella di testo dinamica con informazioni dal database

1 ° prendi l'assoc. array dal database ad es

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

2 ° Implementa hook_form_alter()

/ ** * Implementa hook_form_alter (). * id modulo = views-Exposed-Form * /

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 ° campi multipli saranno verificabili!

0
Mathieu Dierckx

Se stai costruendo il tuo modulo, invece di eseguire funzioni separate form_alter/# process/# pre_render puoi semplicemente passare da "caselle di controllo" alla generazione di singoli elementi di "casella di controllo".

$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 Offre la stessa struttura ad albero della versione delle caselle di controllo quando l'array $ form_state ['valori'] arriva alla convalida/invio/ricostruzione. Se per qualche motivo non puoi o non vuoi usare #tree, dai a ciascuna casella di controllo una proprietà '#parents' => array('my_element', $key) per impostare esplicitamente la sua posizione nella struttura dei valori.

0
KingAndy

Sto usando questo codice seguente a drupal 6: -

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

e la funzione di richiamata è qui: -

/ ** * Elaborare ogni casella di controllo basata su "feture" è già utilizzata da un sottodominio o meno. * @param Array $ element array of form checkboxes * /

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 da considerare è che le caselle di controllo disabilitate non vengono inviate, quindi potresti scoprire che devi forzare il #value anche della casella di controllo .. Ad esempio:

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

Nel mio caso, senza questo, il $form_state['values'] non conteneva il mio valore di casella di controllo (che era abilitato per impostazione predefinita, ma disabilitato).

0
Nick