Jak uniknąć „Wykryto nielegalny wybór” podczas aktualizacji wybranych wartości listy za pośrednictwem ajax?


10

Mam cztery pola odniesienia encji do encji użytkownika w formularzu. Formularz hosta to formularz edycji węzła. Trzy z nich to wybrane listy, ostatnia to formularz podmiotu wbudowanego .

Po dodaniu encji użytkownika za pośrednictwem IEF próbuję zaktualizować wartości wybranych list:

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

Działa, ale kiedy próbuję dodać innego użytkownika za pośrednictwem IEF, otrzymuję:

Wykryto nielegalny wybór. Proszę skontaktować się z administratorem serwisu.


czy którekolwiek z Relatedpytań tutaj wymienionych po prawej stronie rozwiązało to?
— Jimajamma,

@Jimajamma wygląda na to, że w przypadku oddzwaniania formularza ajax odbudowanie nie działa. Jak mogę to włączyć? $ form_state ['rebuild'] = PRAWDA nic nie rób ...
— Codium

@Jajajamma, więc powiązane rozwiązania nie działają
— Codium

Odpowiedziałem tutaj na twoje pytanie, ponieważ jest to duplikat pytania drupal.stackexchange.com/questions/15989/…
— Sina Salek

Odpowiedzi:


15

--- Oryginalna odpowiedź. Jest źle, sprawdź aktualizację poniżej.

Właśnie ustawiłem

$bla['#validated'] = TRUE

Na wybranych, które będą aktualizowane za pomocą AJAX.

Kasa „Wykryto nielegalny wybór”

--- Aktualizacja 17 grudnia 2019 ---

Właściwie to nie była dobra rada, dawno temu, teraz wiem lepiej.

Funkcja wywołania zwrotnego Ajax ma zwracać tylko zmieniony formularz lub niektóre komendy ajax.

W takim przypadku należy zmodyfikować formularz w funkcji formularza lub haka do zmiany formularza. Funkcje budowania formularzy i sprawdzania poprawności są uruchamiane za każdym razem, gdy wywoływane jest wywołanie zwrotne ajax. Po prostu sprawdź $ form_state w funkcji budowania lub zmieniania formularzy i odpowiednio dostosuj wartości.

Zobacz Rozwiązywanie błędu „Wykryto nielegalny wybór ...”


1
Jeśli dobrze pamiętam, próbowałem tego, bez powodzenia w moim przypadku, dzięki
— Codium

1
Obawiam się, że to też nie działa dla mnie.
— kevin.coyle

Czy to nie czyni formularza mniej bezpiecznym?
— Binny

Tak, wszystkie poprzednie komentarze są prawidłowe. Odpowiedź została zaktualizowana.
— jaimealsilva,

3

Wiele razy napotykałem ten problem w Drupal 6, zmieniając wartości listy Select przez Ajax.

Oto, co możesz zrobić

  1. Jeśli to możliwe, spróbuj wstawić wszystkie możliwe wartości w interfejsie API pola, musisz edytować to pole, a następnie, gdy zmienisz wartości, musisz upewnić się, że tylko wymienione wartości znajdują się na liście.
  2. Rozwiązaniem, które wdrożyłem było, możesz zmienić typ pola z Wybierz listę na pole tekstowe, z Field API i poprosić Drupala o zapisanie wartości bez zmian. Teraz w środowisku wykonawczym formularza będziesz musiał zmienić formularz, zmienić typ, aby wybrać listę, i wcisnąć opcje, które chcesz. Podczas przesyłania również będziesz musiał przypisać poprawną wartość wymaganą przez pole, która zostanie zapisana w DB bez zmian. Upewnij się, że program obsługi przesyłania jest wywoływany przed domyślnym programem obsługi przesyłania formularza, którego możesz użyćarray_merge

Jeśli pierwsze rozwiązanie zadziała, zaoszczędzisz dużo czasu na kodowaniu i testowaniu. ALE jeśli lista rozwijana jest dynamiczna i nie masz nad nią kontroli, być może będziesz musiał wybrać drugie rozwiązanie.

Napisz, jeśli napotkasz jakiekolwiek problemy, wykonałem sporo pracy nad tym problemem, w moim projekcie i wykonałem ~ 50 formularzy, PHEW !!! :)


3

Znalazłem najlepszy sposób, aby to ustawić #valuena liście wyboru.

Jeśli mamy wartość w formstate i jest ona w naszych opcjach, nie otrzymamy błędu. Jeśli naszej wartości nie ma w opcjach, wybierz pierwszą opcję w naszych opcjach i skorzystaj z niej.

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

2

Moje rozwiązanie:

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

-1

W wywołaniu zwrotnym ajax dodaj:

...

drupal_get_messages();
form_get_errors();

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

Ze względów bezpieczeństwa _form_validate()funkcja podstawowa sprawdza, czy klucz #options elementu zmienił się w stosunku do tego, co ustawiono w oryginalnej kompilacji (którą mają). Dzwoniąc drupal_get_messages()i po form_get_errors()prostu mówimy Drupalowi, aby ignorował wszelkie błędy / komunikaty podczas uruchamiania naszego żądania ajax. :)


Komunikat o błędzie zniknął, ale element select nadal zawiera klasę błędu. Jak usunąć lub zapobiec?
— Tejas Vaidya,

Jest to odpowiednik Drupala nakładania taśmy na lampkę ostrzegawczą na desce rozdzielczej pojazdu.
— Frank Robert Anderson
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.