web-dev-qa-db-ja.com

Ajaxを介して選択リストの値を更新するときに「不正な選択が検出されました」を回避する方法

フォームにユーザーエンティティへのエンティティ参照フィールドが4つあります。ホストフォームはノード編集フォームです。 3つは選択リストで、最後は インラインエンティティフォーム です。

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を介して別のユーザーを追加しようとすると、次のようになります。

違法な選択が検出されました。サイト管理者に連絡してください。

10
Codium

私の解決策:

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

---元の答え。間違っています。以下の更新を確認してください。

設定するだけ

$bla['#validated'] = TRUE

AJAXで更新される選択について。

チェックアウト "不正な選択が検出されました"

---アップデート2019年12月17日---

実はそれは良いアドバイスではなかった、それはずっと前のことだった。

Ajaxコールバック関数は、変更されたフォームの一部または一部のajaxコマンドのみを返すことになっています。

この場合、フォームの変更は、フォーム関数またはフォーム変更フックで行う必要があります。フォームの構築および検証関数は、ajaxコールバックが呼び出されるたびに実行されます。フォームのビルドまたは変更機能で$ form_stateを確認し、それに応じて値を調整するだけです。

参照 エラーを解決します "不正な選択が検出されました..."

15
jaimealsilva

これを回避する最良の方法は、選択リストに#valueを設定することです。

Formstateに値があり、それがオプションにある場合、エラーは発生しません。オプションに値がない場合は、オプションの最初のオプションを選択して使用します。

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

Drupal 6)でこの問題に何度も直面しました。Ajaxを介して選択リストの値を変更します。

これがあなたができることです

  1. 可能であれば、Field APIのすべての可能な値を挿入してみてください。そのフィールドを編集する必要があります。値を変更するときは、リストされた値のみがリストにあることを確認する必要があります。
  2. 私が実装したソリューションは、フィールドタイプを選択リストからテキストフィールドに、フィールドAPIから変更し、Drupalに値をそのまま保存するように要求することです。今、フォームランタイムでは、フォームを変更するには、タイプを選択リストに変更し、必要なオプションをプッシュインします。送信時にも、フィールドに必要な正しい値を割り当て、DBにそのまま保存する必要があります。 array_mergeを使用できるように、デフォルトのフォーム送信ハンドラの前に送信ハンドラが呼び出されていることを確認してください

最初の解決策がうまくいけば、コーディングやテストにかかる時間を大幅に節約できます。しかし、ドロップダウンのリストが動的であり、それを制御できない場合は、2番目のソリューションを使用する必要があります。

問題が発生した場合は投稿してください。このプロジェクトでは、この問題についてかなりの作業を行ってきました。私は50フォームまで処理しました。PHEW!!! :)

3
Vaibhav Jain