Wie kann ich ein einzelnes Kontrollkästchen in einem 'checkboxes'-FAPI-Element deaktivieren?

31

Titel sagt eigentlich schon alles, ich möchte ein einzelnes Kontrollkästchen eines Kontrollkästchens vom Typ FAPI-Element deaktivieren .

Ich möchte weder mit JavaScript arbeiten noch es von Kontrollkästchen auf mehrere Kontrollkästchenelemente umstellen, da das Element von einem anderen Modul bereitgestellt wird.

Gedanken?

Entziffern
quelle
Ihre Frage enthält einen Tippfehler: "disable"
FR6

Antworten:

36

Ein sauberer Weg existiert in Drupal 7! Anscheinend ist dieser Beitrag noch nicht dokumentiert.

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
}

Ein weiteres Beispiel .

Sie können auch die #access- Funktion auf FALSE setzen, um das Kontrollkästchen vollständig auszublenden.

timofey.com
quelle
3
Mit dem korrigierten Tippfehler funktioniert dieser Code in D7 absolut für mich. Vielen Dank!
beth
1
Großer Fang! Ich bin froh, dass es für dich funktioniert hat.
timofey.com
2
Wenn Sie #access verwenden, wird das Kontrollkästchen bei #default_values ​​nicht in den Formularstatuswerten beim Senden festgelegt.
Nick
Das funktioniert gut.
David Meister
Funktioniert nicht mit Kontrollkästchen (kann mehr als ein Element auswählen) unter Verwendung von BEF (Better Exposed Filters) in Ansichten, AFAICT.
1kenthomas
22

Leider gibt es in FAPI keine wirklich saubere Möglichkeit, dies zu tun. Wenn Sie fest entschlossen sind, ändern Sie am besten eine zusätzliche #Prozessfunktion für das Kontrollkästchen-Element.

Die Standardfunktion, die Elementen vom Typ 'Checkboxes' hinzugefügt wird, ist eine Funktion ( expand_checkboxes () ), die das einzelne Element in mehrere Elemente vom Typ 'Checkbox' aufteilt , die später wieder zu einem zusammengeführt werden. Wenn Sie Ihre zweite Prozessfunktion huckepack nehmen, könnte sie in die erweiterte Gruppe der 'Checkbox'-Elemente eingreifen und die betreffende deaktivieren.

Der folgende Code ist völlig ungetestet, daher Vorbehalt:

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;
    }
  }
}
Eaton
quelle
Klingt besser als der von mir gewählte Ansatz, dem Element eine Designfunktion zuzuweisen und preg_replace()die Ausgabe zu überfliegen.
Entschlüsselung am
Sie könnten eine "Pause" hinzufügen; in der obigen if-Anweisung für ein bisschen mehr Effizienz, es sei denn, Sie erwarten, dass derselbe Elementschlüssel zweimal angezeigt wird.
Chris Cohen
Guter Fang, Chris, ich habe das Code-Snippet geändert. Vielen Dank!
Eaton
2
Die akzeptierte Antwort scheint im Vergleich zu @ timofeys Antwort etwas übertrieben.
Citricguy
6

Hier ist mein Code für Drupal 7, um das Roles-Element auf der Edit User-Seite zu ändern.

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;
}
aFeijo
quelle
3

Ich verwende Kontrollkästchen als "zuweisen" und "nicht zuweisen". Der Client hat mich gebeten, die Zuweisung aufzuheben, aber es ist immer noch wichtig, die Zuweisung darzustellen. Unter Berücksichtigung der Tatsache, dass deaktivierte Kontrollkästchen als "falsch" gesendet werden und bei falscher Behandlung die Zuweisung aufgehoben wird, teile ich meine Kontrollkästchen in "Diese verarbeiten" und "Diese deaktivierten ignorieren" auf. Hier ist wie:

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

Beachten Sie, dass 'partner_assignments' ein eigenes Array / eine eigene Variable ist und in meinem Anwendungsfall nicht als "unassign" verarbeitet wird. Vielen Dank für die Veröffentlichung - es führte mich zu dieser Lösung.

Texas-Bronius
quelle
3

D7. Hier mussten wir sicherstellen, dass beim Hinzufügen eines Knotens eine bestimmte Referenzoption für Taxonomiebegriffe immer deaktiviert ist und immer auf dem Knoten gespeichert wird. Also gingen wir in #after_build und deaktivierten diese bestimmte Option, mussten aber sicherstellen, dass am Ende diese bestimmte Option weitergegeben wird. Das Deaktivieren dieser Option hätte die Weiterleitung an zukünftige Hooks gestoppt.

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

So sieht die deaktivierte Option aus:

Bildbeschreibung hier eingeben

leymannx
quelle
2

Ich konnte nicht erreichen, dass Eatons Antwort so funktioniert, wie sie geschrieben wurde (der # Process Callback gibt nichts zurück und wird aufgerufen, bevor die Kontrollkästchen erweitert werden), und ich wollte auch, dass der Wert aus dem deaktivierten Kontrollkästchen zurückgegeben wird (ich wollte, dass er permanent aktiviert wird ). Das hat bei mir geklappt (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';
}

Wenn jemand einen besseren Weg kennt, würde ich ihn gerne hören!

Andy
quelle
Fatal error: Call to undefined function expand_checkboxes()
Leymannx
1
@koivo Dies war eine D6-Antwort, die Funktion ist in D7 nicht mehr vorhanden
Andy
1

Hier ist mein Code für Drupal 7, um das Roles-Element auf der Edit User-Seite zu ändern.

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;
}
jrockowitz
quelle
1

In Drupal 7 musste ich eine #processFunktion installieren, um die Optionen in einer Auswahl in einer feldfähigen Entität zu deaktivieren . Leider hat dies die eingebaute Prozessfunktion deaktiviert form_process_checkboxes, so dass diese wieder hinzugefügt (oder von Ihrer Prozessfunktion aufgerufen) werden muss. Beim Deaktivieren von Kontrollkästchen, die bereits aktiviert sind, wurde festgestellt, dass der integrierte Wert callback ( form_type_checkboxes_value) beim Abrufen von Ergebnissen aus der Eingabe die Standardwerte ignoriert.

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

Dann etwa so:

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

Und schlussendlich:

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

Ich habe in diesem Fall keine der anderen Antworten auf dieser Seite gefunden.

Dan Chadwick
quelle
1

Hier ist mein Beispiel (mit #after_build):

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

Dazu der folgende Funktionsrückruf:

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

Getestet auf Drupal 6, sollte aber auch auf Drupal 7 funktionieren.


Drupal 6

Sie können die folgende Funktion ( Quelle ) verwenden:

/*
 * 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;
        }
    }
}
Kenorb
quelle
D7: Hier funktioniert die Verwendung von #after_build wie gewünscht. Bestätigen Sie die deaktivierte Einstellung auch mit #attribute.
SGhosh
0

Ich benutze diesen folgenden Code bei Drupal 6: -

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

und die Rückruffunktion ist hier: -

/ ** * Jedes Kontrollkästchen basierend auf 'feture' wird bereits von einer Subdomain verwendet oder nicht. * @param Array $ element Array von Formular-Checkboxen * /

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;
}
Sandip Ghosh
quelle
Willkommen bei drupal.stackexchange.com! Bitte korrigieren Sie Ihre Code-Formatierung. Kommentare vor der legal_process_checkboxes () -Funktion wurden außerhalb des "Code" -Formats gelassen. Vielen Dank.
Ermannob
0

Es ist wichtig zu berücksichtigen, dass deaktivierte Kontrollkästchen nicht #valuegesendet werden. Daher müssen Sie möglicherweise auch das Aktivieren des Kontrollkästchens erzwingen . Beispiel:

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

In meinem Fall $form_state['values']enthielt das ohne dieses Kontrollkästchen nicht meinen Kontrollkästchenwert (der standardmäßig aktiviert, aber deaktiviert war).

Nick
quelle
0

Haken Sie das Textfeld ein und erstellen Sie ein dynamisches Textfeld mit Informationen aus der Datenbank

1 ° bekommen die assoc. Array aus Datenbank zB

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

2 ° Anbaugeräte hook_form_alter()

/ ** * Implementiert hook_form_alter (). * form id = 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 ° mehrere Felder werden ankreuzbar sein!

Mathieu Dierckx
quelle
0

Wenn Sie ein eigenes Formular erstellen, können Sie statt der separaten form_alter / # process / # pre_render-Funktionen einfach von 'checkboxes' zu einzelnen 'checkbox'-Elementen wechseln.

$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' => TRUEGibt Ihnen die gleiche Baumstruktur wie die Version der Kontrollkästchen, wenn das Array $ form_state ['values'] bei validation / submit / rebuild eintrifft. Wenn Sie #tree aus irgendeinem Grund nicht verwenden können oder möchten, geben Sie jedem Kontrollkästchen eine '#parents' => array('my_element', $key)Eigenschaft, mit der die Position in der Wertestruktur explizit festgelegt wird.

KingAndy
quelle