Ajaxを介して選択リストの値を更新するときに「不正な選択が検出されました」を回避するにはどうすればよいですか?


10

フォームにユーザーエンティティへのエンティティ参照フィールドが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を介して別のユーザーを追加しようとすると、次のようになります。

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


Related右にリストされているここの質問のいずれかがこれを解決しましたか?
Jimajamma 2013

@Jimajammaはajaxコールバックでフォームの再構築が機能しないようです。どうすれば有効にできますか?$ form_state ['rebuild'] = TRUE何もしない...
Codium

@Jimajammaの関連ソリューションが機能しない
Codium

それが重複質問ですので、私はここにあなたの質問に答えましたdrupal.stackexchange.com/questions/15989/...
シーナSalek

回答:


15

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

設定するだけ

$bla['#validated'] = TRUE

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

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

--- 2019年12月17日更新---

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

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

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

エラーの解決「不正な選択が検出されました...」を参照してください


1
私がよく覚えているなら、私の場合は成功せずに、これを試しました。ありがとう
Codium

1
これは私にとってもうまくいきません。
kevin.coyle 2015

これによりフォームの安全性が低下しませんか?
Binny

はい、以前のコメントはすべて正しいです。回答を更新しました。
jaimealsilva

3

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

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

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

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

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


3

これを回避する最良の方法は#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),
  );

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要素にはまだエラークラスが含まれています。
Tejas Vaidya、2016年

これは、Drupalで車両のダッシュボードの警告灯にテープを貼るのと同じです。
フランクロバートアンダーソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.