Beheben Sie den Fehler "Eine illegale Auswahl wurde erkannt ..."

7

Ich habe Code wie unten geschrieben und alles funktioniert einwandfrei, aber beim Absenden des Formulars wird der folgende Fehler angezeigt. Ich versuche, das zweite Dropdown basierend auf der ersten Dropdown-Auswahl zu filtern.

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

Wie überwinde ich diesen Fehler?

function dynamic_location_dropdown_form_alter(&$form, $form_state, $form_id) {
  if($form_id == 'product_node_form') {

  $location_options = array();

  if(isset($form['field_destination']['und']['#default_value'][0])) {
    $destination = $form['field_destination']['und']['#default_value'][0];
  }
  else {
    $destination = 0;
  }

  $location_options = dynamic_location_dropdown_locations($destination);

  $form['field_destination']['und']['#ajax'] = array(
    'event' => 'change',
    'wrapper' => 'squadron-wrapper',
    'callback' => 'dynamic_location_dropdown_ajax_callback',
    'method' => 'replace',
  );
  $form['field_product_location']['#validated'] = true;
  $form['field_product_location']['und']['#prefix'] = '<div id="squadron-wrapper">';
  $form['field_product_location']['und']['#suffix'] = '</div>';
  $form['field_product_location']['und']['#options'] = $location_options;
  }
}

function dynamic_location_dropdown_ajax_callback($form, $form_state) {
  $country_id = $form['field_destination']['und']['#value'];
  $form['field_product_location']['#validated'] = true;
  $form['field_product_location']['und']['#options'] =  dynamic_location_dropdown_locations($country_id);

  return $form['field_product_location'];
}

function dynamic_location_dropdown_locations($destination_id) {
  $nodes = array();
  $nodes[''] = '- None -';
  if($destination_id != '') {
    $select = db_query("
      SELECT node.title AS node_title, node.nid AS nid, node.created AS node_created
      FROM {node} node
      LEFT JOIN {field_data_field_location_country} field_data_field_location_country 
      ON node.nid = field_data_field_location_country.entity_id 
      AND (field_data_field_location_country.entity_type = 'node' 
      AND field_data_field_location_country.deleted = '0')
      WHERE (( (node.status = '1') 
      AND (node.type IN  ('location')) 
      AND (field_data_field_location_country.field_location_country_nid = $destination_id)))
      ORDER BY node_title ASC
    ");
    $nodes[''] = '- None -';
    foreach ($select as $node) {
      $nodes[$node->nid] = $node->node_title;
    }
  }

  return $nodes;
}
Hacker
quelle
Nun, Sie verwenden bereits, '#validated' => TRUEwas sich darum kümmern sollte. Ich vermute also, dass Sie in einigen Eigenschaften den Schlüssel 'und' haben und nicht in dem Formulararray, in dem Sie den Schlüssel '#validated' verwenden ...?
30equals

Antworten:

8

Das Problem ist höchstwahrscheinlich auf eine Anforderung für FAPI AJAX zurückzuführen, die in AJAX Forms in Drupal 7 dokumentiert ist, jedoch leicht übersehen werden kann.

Änderungen am Formular dürfen nur in der Form Builder-Funktion (ajax_example_autocheckboxes () im Beispiel hier) vorgenommen werden. Andernfalls schlägt die Validierung fehl. Die Rückruffunktion darf weder das Formular noch einen anderen Status ändern.

Die Tatsache, dass Sie das Formularelement [#options]im AJAX-Rückruf festlegen, ist definitiv ein Problem. Der AJAX-Rückruf sollte nur das zu druckende Array oder HTML zurückgeben, nicht das Formular ändern. Dieser Rückruf sollte nur die returnAnweisung enthalten .

Die Änderungen an Ihrem Formular sollten im form_alter vorgenommen werden. Außerdem sollten Sie das Array form_state verwenden, um zu überprüfen, ob für Ihre erste Dropdown-Liste ein Wert ausgewählt wurde. Dies wird während einer AJAX-Anfrage aktualisiert.

Ich empfehle, das Beispielmodul sowie diese Seiten zu lesen, um weitere Informationen zu AJAX in FAPI zu erhalten. Es kann definitiv schwierig sein.

Goron
quelle
Ein Beispiel finden Sie unter Dynamische Auswahlliste im Formular (abhängige Dropdown-Liste) (verwenden Sie jedoch " return $form['squadron_wrapper']", um die AJAX-Antwort zu verkleinern).
Top-Master
2

Die folgende Methode kann verwendet werden, um Fehler nur für die Felder zu vernachlässigen, in die durch Ajax ein Wert hinzugefügt wurde. Gemäß
dem unten angegebenen Code können Sie das Feldelement eingeben, das einen Fehler ausgibt, sodass sich der Wert in der zweiten Dropdown-Liste aufgrund einer Änderung in ändert Das erste Dropdown-Menü aufgrund der Verwendung von Ajax zeigt keinen Fehler an.

/**
 * Custom Form Validation.
 * Removes all form validation errors caused by a 'foo][bar' form element.
 */
function my_module_form_validate($form, &$form_state) {
  $errors = form_get_errors();
  if ($errors) {
    // Clear errors.
    form_clear_error();
    // Clear error messages.
    $error_messages = drupal_get_messages('error');
    // Initialize an array where removed error messages are stored.
    $removed_messages = array();


// Remove all errors originated by the 'foo][bar' element.
    foreach ($errors as $name => $error_message) {
      if ($name == 'foo][bar') {
        $removed_messages[] = $error_message;
        unset($errors[$name]);
      }
    }


// Reinstate remaining errors.
    foreach ($errors as $name => $error) {
      form_set_error($name, $error);
      // form_set_error() calls drupal_set_message(), so we have to filter out
      // these from the error messages as well.
      $removed_messages[] = $error;
    }


// Reinstate remaining error messages (which, at this point, are messages that
    // were originated outside of the validation process).
    foreach (array_diff($error_messages['error'], $removed_messages) as $message) {
      drupal_set_message($message, 'error');      
    }
  }
}
Harshal
quelle
1

Dies scheint ein Kernfehler zu sein https://www.drupal.org/node/153774 und die hier erwähnten Lösungen verursachen tatsächlich mehr Probleme.

Wenn #ajax für ein Auswahlelement verwendet wird und mehr als eine Option ausgewählt ist, wird ein "unzulässiger Auswahlfehler" generiert. Aber warum? Nach einigem Nachforschen stellte sich heraus, dass das aktivierte Element bei Aktivierung von #ajax Werte wie Array (200.250) anstelle von Array (200 => 200, 250 => 250) übermittelt. Dies führt also zu Problemen mit dem darin enthaltenen Optionsvalidierungscode _form_validate Funktion und es kann ausgewählte Optionen nicht mehr mit verfügbaren Optionen vergleichen. Hier ist der Code: Dies geschieht nur, wenn mehr als eine Option ausgewählt ist und #ajax verwendet wird. Der Fix besteht darin, den übermittelten Wert vor der Validierung zu korrigieren

Ich habe ein Modul geschrieben, um diesen Fehler automatisch zu umgehen. Es funktioniert möglicherweise nicht in allen Fällen, aber es ist eine klare Problemumgehung, die Sie als Ausgangspunkt verwenden können.

https://www.drupal.org/sandbox/sinasalek/2312751

Sina Salek
quelle