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


31

Il titolo praticamente dice tutto, voglio disabilitare una singola casella di controllo di un elemento FAPI di tipo caselle di controllo .

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

Pensieri?


C'è un refuso nella tua domanda: "disabilita"
FR6

Risposte:


36

Un modo pulito esiste 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 la funzione #access su FALSE, per nascondere completamente la casella di controllo.


3
Con l'errore corretto corretto, questo codice funziona assolutamente per me in D7. Grazie!
Bet

1
Ottima cattura! Sono contento che abbia funzionato per te.
timofey.com

2
Se si utilizza #access, quindi se la casella di controllo è impostata in #default_values, non verrà impostata nei valori dello stato del modulo al momento dell'invio.
Nick,

Funziona bene.
David Meister,

Non funzionerà con le caselle di controllo (è possibile selezionare più di un elemento) utilizzando i filtri Better Exposed (BEF) nelle viste, AFAICT.
1kenthomas,

22

Sfortunatamente non c'è un modo davvero pulito per farlo in FAPI. La tua scommessa migliore - se sei determinato - è quella di modificare una funzione #process aggiuntiva sull'elemento checkboxes.

La funzione predefinita aggiunta agli elementi di tipo 'checkboxes' è 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;
    }
  }
}

Sembra migliore dell'approccio che ho adottato, che era quello di collegare una funzione tema all'elemento ed eseguire un preg_replace()over sull'output.
Decifrare il

È possibile aggiungere una "pausa"; all'interno dell'istruzione if sopra per un po 'più di efficienza, a meno che non ti aspetti di vedere due volte la stessa chiave dell'elemento.
Chris Cohen,

Buona cattura, Chris, ho cambiato lo snippet di codice. Grazie!
Eaton,

2
La risposta accettata sembra un po 'eccessiva rispetto alla risposta di @ timofey.
Citricguy,

6

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

3

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

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 certa 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:

inserisci qui la descrizione dell'immagine


2

Non sono riuscito a far funzionare la risposta di Eaton come scritto (il callback #process non restituisce nulla ed è chiamato prima che le caselle di controllo siano espanse) e volevo anche che il valore fosse restituito dalla casella di controllo disabilitata (volevo che fosse permanentemente controllato ). 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!


Fatal error: Call to undefined function expand_checkboxes()
leymannx,

1
@koivo Questa era una risposta D6, la funzione non esiste più in D7
Andy il

1

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

In Drupal 7, per disabilitare le opzioni in una selezione in un'entità fieldable, ho scoperto che dovevo installare una #processfunzione. Sfortunatamente, questo ha disabilitato la funzione di processo integrata, form_process_checkboxesquindi è necessario aggiungere nuovamente (o richiamare dalla funzione di processo). Inoltre, disabilitando le caselle di controllo già selezionate, ho scoperto che il valore incorporato callback ( 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

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 su Drupal 7.


Drupal 6

È possibile utilizzare la seguente funzione ( sorgente ):

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

D7: Lo stesso qui, usando #after_build funziona come desiderato. Confermando anche l'impostazione disabilitata con #attribute.
SGhosh,

0

Sto usando questo seguente codice 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 in base a "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;
}

Benvenuto su drupal.stackexchange.com! Correggi la formattazione del codice. I commenti prima della funzione legal_process_checkboxes () sono stati lasciati fuori dal formato "code". Grazie.
ermannob,

0

Una cosa importante da considerare è che le caselle di controllo disabilitate non vengono inviate, quindi potresti scoprire che devi forzare anche #valuela 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 della casella di controllo (che era abilitato per impostazione predefinita, ma disabilitato).


0

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 ° Strumenti 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

Se stai costruendo il tuo modulo, invece di eseguire funzioni separate form_alter / # process / # pre_render, puoi semplicemente passare da "caselle di controllo" a generare 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' => TRUEfornisce la stessa struttura ad albero della versione delle caselle di controllo quando l'array $ form_state ['valori'] arriva alla convalida / invio / ricostruzione. Se non è possibile o non si desidera utilizzare #tree per qualche motivo, assegnare a ciascuna casella di controllo una '#parents' => array('my_element', $key)proprietà per impostare esplicitamente la propria posizione nella struttura dei valori.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.