Як уникнути "виявлено незаконний вибір" під час оновлення значень списку через ajax?


10

У мене у формі є чотири посилання на сутність користувача. Форма хоста - це форма редагування вузла. Три з них є списками вибору, останній - Inline Entry 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 ['відновити'] = ІСТИНА нічого не робити ...
Codium

@Jimajamma, так що пов'язані рішення не працюють
Codium

Я відповів на ваше запитання тут, оскільки це повторне
Sina

Відповіді:


15

--- Оригінальна відповідь. Невірно, перевірте оновлення нижче.

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

$bla['#validated'] = TRUE

На вибір, який буде оновлений AJAX.

Оформити замовлення "Нелегальний вибір виявлено"

--- Оновлення 17 грудня 2019 ---

Насправді це була не гарна порада, це було давно, тепер я знаю краще.

Функція зворотного виклику Ajax повинна повертати лише фрагмент форми, який змінився, або деякі команди ajax.

У цьому випадку модифікація форми повинна бути здійснена за допомогою функції форми або гачка зміни форми. Функції побудови форми та перевірки виконуються щоразу, коли викликається зворотний виклик ajax. Просто перевірте $ form_state на форму формування або змінення форми та відповідно відрегулюйте значення.

Див. Розділ Вирішення помилки "Незаконній вибір виявлено ..."


1
Якщо я добре пам’ятаю, я спробував це, не маючи успіху в моєму випадку, дякую
Codium

1
Боюся, що і це не працює для мене.
kevin.coyle

Це не робить форму менш захищеною?
Бінні

Так, всі попередні коментарі вірні. Відповідь оновлено.
jaimealsilva

3

Я не раз стикався з цією проблемою в Drupal 6, змінюючи значення списку Select через Ajax.

Ось що ви можете зробити - це

  1. Якщо це можливо, спробуйте вставити всі можливі значення в API поля, вам потрібно відредагувати це поле, і тоді, коли ви зміните значення, вам доведеться переконатися, що в списку є лише перелічені значення.
  2. Вирішене нами рішення було: ви можете змінити тип поля зі списку "Вибрати" на текстове поле, з API API та попросити Drupal зберегти значення таким, яким воно є. Тепер, під час виконання форми, вам доведеться змінити форму, змінити тип для вибору списку та ввести варіанти, які ви хочете. Під час подання також вам доведеться призначити правильне значення, яке вимагає поле, яке буде збережено в БД як є. Переконайтесь, що ваш обробник подачі викликається перед типовим обробником форми подання, який ви можете використовуватиarray_merge

Якщо перше рішення працює для вас, ви заощадите багато часу на кодування та тестування речей. АЛЕ якщо список у спадному списку динамічний і ви не маєте контролю над ним, можливо, доведеться перейти з другим рішенням.

Займіться публікацією, якщо у вас виникли якісь проблеми, я зробив досить багато роботи над цією проблемою, для свого проекту, і я зробив для ~ 50 форм, PHEW !!! :)


3

Я знайшов найкращий спосіб це встановити #valueсписок у списку вибору.

Якщо у нас є значення у форматі, і воно є в наших варіантах, ми не отримаємо помилку. Якщо наше значення не в опціях, тоді виберіть перший варіант в наших опціях і скористайтеся цим.

$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

Додайте:

...

drupal_get_messages();
form_get_errors();

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

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


Повідомлення про помилку відсутнє, але елемент вибору все ще містить клас помилок. Як видалити чи запобігти цьому?
Техас Вайдя

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