Как избежать «Обнаружен неправильный выбор» при обновлении значений списка выбора через ajax?


10

У меня есть четыре поля ссылки на сущность пользователя в форме. Форма хоста - это форма редактирования узла. Три из них являются списками выбора, последний - Inline Entity Form .

После добавления пользовательского объекта через IEF я пытаюсь обновить значения списков выбора:

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

Это работает, но когда я пытаюсь добавить другого пользователя через IEF, я получаю:

Обнаружен незаконный выбор. Пожалуйста свяжитесь с администратором сайта.


Есть ли какие-либо из Relatedвопросов, перечисленных здесь, чтобы решить эту проблему?
Jimajamma

@Jimajamma кажется, что перестроение формы обратного вызова в ajax не работает. Как я могу включить это? $ form_state ['rebuild'] = TRUE ничего не делать ...
Codium

@Jimajamma, поэтому связанные решения не работают
Codium

Я ответил на ваш вопрос здесь, так как это дублирующий вопрос drupal.stackexchange.com/questions/15989/…
Сина Салек

Ответы:


15

--- Оригинальный ответ. Неправильно, проверьте обновление ниже.

Просто установите

$bla['#validated'] = TRUE

На выбор, который будет обновлен с AJAX.

Оформить заказ "Незаконный выбор был обнаружен"

--- Обновление 17 декабря 2019 года ---

На самом деле это был не очень хороший совет, это было давно, теперь я знаю лучше.

Функция обратного вызова Ajax должна возвращать только часть измененной формы или некоторые команды ajax.

В этом случае необходимо изменить форму в функции формы или в хуке изменения формы. Функции построения и проверки форм выполняются каждый раз, когда вызывается обратный вызов ajax. Просто проверьте $ form_state в вашей сборке формы или измените функцию и измените значения соответствующим образом.

См. Устранение ошибки «Обнаружен незаконный выбор ...»


1
Если я хорошо помню, я попробовал это, но безуспешно в моем случае, спасибо
Codium

1
Боюсь, это тоже не работает для меня.
kevin.coyle

Разве это не делает форму менее безопасной?
Бинни

Да, все предыдущие комментарии верны. Ответ был обновлен.
Jaimealsilva

3

Я сталкивался с этой проблемой несколько раз в Drupal 6, меняя значения списка выбора через Ajax.

Вот что вы можете сделать, это

  1. Если возможно, попробуйте вставить все возможные значения в поле API поля, вам нужно отредактировать это поле, а затем при изменении значений вам нужно будет убедиться, что в списке присутствуют только перечисленные значения.
  2. Решение, которое я реализовал, состояло в том, что вы можете изменить тип поля с Select list на textfield, с Field API и попросить Drupal сохранить значение как есть. Теперь во время выполнения формы вам нужно будет изменить форму, изменить тип, чтобы выбрать список, и нажать опции, которые вы хотите. Во время отправки вам также нужно будет указать правильное значение, необходимое для поля, которое будет сохранено в БД как есть. Убедитесь, что ваш обработчик отправки вызывается перед обработчиком отправки формы по умолчанию, для этого вы можете использоватьarray_merge

Если первое решение работает для вас, вы сэкономите много времени на программировании и тестировании. НО, если список в раскрывающемся списке является динамическим, и вы не можете его контролировать, возможно, вам придется использовать второе решение.

Пишите, если у вас возникнут какие-либо проблемы, я проделал довольно много работы над этой проблемой для своего проекта, и я сделал для ~ 50 форм, PHEW !!! :)


3

Я нашел лучший способ обойти это, чтобы установить #valueв списке выбора.

Если у нас есть значение в formtate и оно есть в наших параметрах, мы не получим ошибку. Если наше значение отсутствует в параметрах, выберите первый вариант в наших параметрах и используйте его.

$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

Мое решение:

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

В ваш обратный вызов ajax добавьте:

...

drupal_get_messages();
form_get_errors();

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

В качестве меры безопасности основная _form_validate()функция проверяет, изменился ли ключ элемента #options по сравнению с тем, что было установлено в исходной сборке (которая у них есть). Позвонив drupal_get_messages()и form_get_errors()мы в основном сказать Drupal , чтобы игнорировать любые ошибки / сообщения во время работы нашего AJAX запроса. :)


Сообщение об ошибке исчезло, но элемент select по-прежнему содержит класс ошибки. Как это устранить или предотвратить?
Теджас Вайдья

Это эквивалент Drupal, который наносит ленту поверх сигнальной лампы на приборной панели вашего автомобиля.
Фрэнк Роберт Андерсон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.