Wie vermeide ich, dass beim Aktualisieren von Auswahllistenwerten über Ajax eine unzulässige Auswahl festgestellt wurde?

10

Ich habe vier Entitätsreferenzfelder für die Benutzerentität in einem Formular. Das Host-Formular ist ein Knotenbearbeitungsformular. Drei davon sind Auswahllisten, zuletzt das Inline-Entitätsformular .

Nach dem Hinzufügen einer Benutzerentität über IEF versuche ich, die Werte der Auswahllisten zu aktualisieren:

function ebep_users_feature_users_list_ajax($form, $form_state) {

  $ief = array_shift($form_state['inline_entity_form']);
  $options = array('_node' => t('- None -'));
  $commands = array();

  foreach($ief['entities'] as $data) {
    $options[$data['entity']->uid] = $data['entity']->name;
  }

  foreach(_ebep_users_feature_getUserListFieldNames() as $fieldName) {
    $form[$fieldName]['und']['#options'] = $options;
    $commands[] = ajax_command_replace('#'.$fieldName.'_wrapper', drupal_render($form[$fieldName]));
  }

  return array('#type' => 'ajax', '#commands' => $commands);
}

Es funktioniert, aber wenn ich versuche, einen anderen Benutzer über IEF hinzuzufügen, erhalte ich:

Eine illegale Auswahl wurde festgestellt. Bitte wenden Sie sich an den Site-Administrator.

Codium
quelle
Haben Sie eine der Relatedhier rechts aufgeführten Fragen gelöst?
Jimajamma
@ Jimajamma Es scheint, dass bei Ajax Callback Form Rebuild nicht funktioniert. Wie kann ich es aktivieren? $ form_state ['rebuild'] = TRUE nichts tun ...
Codium
@ Jimajamma so verwandte Lösungen funktioniert nicht
Codium
Ich habe Ihre Frage hier beantwortet, da es sich um eine doppelte Frage handelt. Drupal.stackexchange.com/questions/15989/…
Sina Salek

Antworten:

15

--- Ursprüngliche Antwort. Ist falsch, überprüfen Sie das Update unten.

Einfach einstellen

$bla['#validated'] = TRUE

Auf der Auswahl, die mit AJAX aktualisiert wird.

Kasse "Unzulässige Auswahl wurde erkannt"

--- Update 17. Dezember 2019 ---

Eigentlich war das kein guter Rat, das ist lange her, jetzt weiß ich es besser.

Die Ajax-Rückruffunktion soll nur das geänderte Formular oder einige Ajax-Befehle zurückgeben.

In diesem Fall muss eine Formularänderung an der Formularfunktion oder einem Formularänderungshaken vorgenommen werden. Formularerstellungs- und Validierungsfunktionen werden jedes Mal ausgeführt, wenn ein Ajax-Rückruf aufgerufen wird. Überprüfen Sie einfach $ form_state in Ihrer Formularerstellungs- oder Änderungsfunktion und passen Sie die Werte entsprechend an.

Siehe Beheben des Fehlers "Eine unzulässige Auswahl wurde erkannt ..."

jaimealsilva
quelle
1
Wenn ich mich gut erinnere, habe ich es versucht, ohne Erfolg in meinem Fall, danke
Codium
1
Ich fürchte, das funktioniert auch bei mir nicht.
kevin.coyle
Macht dies das Formular nicht weniger sicher?
Binny
Ja, alle vorherigen Kommentare sind richtig. Die Antwort wurde aktualisiert.
jaimealsilva
3

Ich bin in Drupal 6 mehrmals auf dieses Problem gestoßen und habe die Werte der Auswahlliste über Ajax geändert.

Folgendes können Sie tun:

  1. Versuchen Sie nach Möglichkeit, alle möglichen Werte in die Feld-API einzufügen. Sie müssen dieses Feld bearbeiten. Wenn Sie dann die Werte ändern, müssen Sie sicherstellen, dass nur die aufgelisteten Werte in der Liste enthalten sind.
  2. Die von mir implementierte Lösung war, dass Sie den Feldtyp von der Auswahlliste in das Textfeld der Feld-API ändern und Drupal bitten können, den Wert unverändert zu speichern. Zur Laufzeit des Formulars müssen Sie nun das Formular ändern, den Typ für die Auswahlliste ändern und die gewünschten Optionen eingeben. Auch bei der Übermittlung müssen Sie den korrekten Wert für das Feld zuweisen, der unverändert in der Datenbank gespeichert wird. Stellen Sie sicher, dass Ihr Submit-Handler vor dem Standard-Formular-Submit-Handler aufgerufen wird, den Sie verwenden könnenarray_merge

Wenn die erste Lösung für Sie funktioniert, sparen Sie viel Zeit beim Codieren und Testen. ABER wenn die Liste in der Dropdown-Liste dynamisch ist und Sie keine Kontrolle darüber haben, müssen Sie möglicherweise eine zweite Lösung wählen.

Schreiben Sie, wenn Sie auf Probleme stoßen. Ich habe für mein Projekt ziemlich viel an diesem Problem gearbeitet, und ich habe für ~ 50 Formulare gearbeitet, PHEW !!! :) :)

Vaibhav Jain
quelle
3

Ich habe den besten Weg gefunden, dies zu umgehen, #valueindem ich das auf die Auswahlliste setze .

Wenn wir den Wert in formstate haben und er in unseren Optionen ist, erhalten wir keinen Fehler. Wenn unser Wert nicht in den Optionen enthalten ist, wählen Sie die erste Option in unseren Optionen aus und verwenden Sie diese.

$form['example'] = array(
    '#type' => 'select',
    '#title' => t('Example'),
    '#options' => $options,
    '#value' => isset($form_state['values']['example']) && in_array($form_state['values']['example'],$options)?$form_state['values']['example']:key($options),
  );
Bob
quelle
2

Meine Lösung:

/**
 * Implements hook_form_FORM_ID_alter()
 */
function ebep_users_feature_form_ebep_exhibitor_profile_node_form_alter(&$form, &$form_state, $form_id) {

  foreach(_ebep_users_feature_getUserListFieldNames() as $fieldName) {
    $form[$fieldName]['und']['#prefix'] = '<div id="'.$fieldName . '_wrapper">';
    $form[$fieldName]['und']['#suffix'] = '</div>';
    $form[$fieldName]['und']['#options'] = _ebep_users_feature_getOptionsValuesFromIEFList($form_state);
  }

  $form['#attached']['css'] = array(
    drupal_get_path('module', 'ebep_users_feature') . '/assets/styles.css',
  );

  $form['#attached']['js'] = array(
    drupal_get_path('module', 'ebep_users_feature') . '/assets/scripts.js',
  );

  $form['users_refresh'] = array(
    '#type' => 'submit',
    '#value' => t('Refresh users list'),
    '#ajax' => array(
      'callback' => 'ebep_users_feature_users_list_ajax',
    ),
  );
}

function ebep_users_feature_users_list_ajax($form, $form_state) {

  $commands = array();

  foreach(_ebep_users_feature_getUserListFieldNames() as $fieldName) {
    $form[$fieldName]['und']['#options'] = _ebep_users_feature_getOptionsValuesFromIEFList($form_state);
    $commands[] = ajax_command_replace('#'.$fieldName.'_wrapper', drupal_render($form[$fieldName]));
  }

  return array('#type' => 'ajax', '#commands' => $commands);
}

function _ebep_users_feature_getOptionsValuesFromIEFList($form_state) {
  static $options = array();

  if (empty($options)) {
    $ief = array_shift($form_state['inline_entity_form']);
    $options['_node'] = t('- None -');

    foreach($ief['entities'] as $data) {
      $options[$data['entity']->uid] = $data['entity']->name;
    }
  }

  return $options;
}
Codium
quelle
-1

Fügen Sie in Ihrem Ajax-Rückruf Folgendes hinzu:

...

drupal_get_messages();
form_get_errors();

return array('#type' => 'ajax', '#commands' => $commands);

Aus Sicherheitsgründen _form_validate()prüft die Kernfunktion , ob sich der Schlüssel #options eines Elements von dem geändert hat, was im ursprünglichen Build festgelegt wurde (was sie haben). Durch den Aufruf drupal_get_messages()und form_get_errors()wir Drupal im Grunde sagen alle Fehler / Nachrichten zu ignorieren , während unsere Ajax - Anforderung ausgeführt wird . :) :)

JC3
quelle
Die Fehlermeldung ist verschwunden, aber das Auswahlelement enthält immer noch die Fehlerklasse. Wie kann man das entfernen oder verhindern?
Tejas Vaidya
Dies ist das Drupal-Äquivalent zum Anbringen von Klebeband über einer Warnleuchte am Armaturenbrett Ihres Fahrzeugs.
Frank Robert Anderson