Bagaimana cara menghindari "Pilihan ilegal telah terdeteksi" ketika memperbarui nilai daftar pilih melalui ajax?

10

Saya memiliki empat bidang referensi entitas ke entitas pengguna dalam formulir. Bentuk host adalah bentuk edit simpul. Tiga di antaranya adalah daftar pilih, terakhir adalah Formulir Entitas Inline .

Setelah menambahkan entitas pengguna melalui IEF saya mencoba untuk memperbarui nilai daftar pilih:

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

Ini berfungsi, tetapi ketika saya mencoba menambahkan pengguna lain melalui IEF saya mendapatkan:

Pilihan ilegal telah terdeteksi. Silakan hubungi administrator situs.

Natrium
sumber
apakah ada Relatedpertanyaan di sini yang terdaftar di sebelah kanan untuk menyelesaikan ini?
Jimajamma
@Jimajamma tampaknya pada ajax callback form rebuild tidak berfungsi. Bagaimana saya bisa mengaktifkannya? $ form_state ['rebuild'] = BENAR-BENAR tidak melakukan apa-apa ...
Codium
@Jimajamma sehingga solusi terkait tidak berfungsi
Codium
Saya telah menjawab pertanyaan Anda di sini karena ini adalah pertanyaan duplikat drupal.stackexchange.com/questions/15989/…
Sina Salek
Kemungkinan duplikat dari daftar pilih Dinamis dalam bentuk (dropdown dependen)
Top-Master

Jawaban:

15

--- Jawaban asli. Apakah salah, periksa pembaruan di bawah ini.

Baru diatur

$bla['#validated'] = TRUE

Pada pilih yang akan diperbarui dengan AJAX.

Checkout "Pilihan Ilegal telah terdeteksi"

--- Perbarui 17 Des 2019 ---

Sebenarnya itu bukan nasihat yang baik, itu sudah lama sekali, sekarang saya lebih tahu.

Fungsi panggilan balik Ajax seharusnya hanya mengembalikan potongan formulir yang telah berubah atau beberapa perintah ajax.

Dalam hal ini modifikasi bentuk harus dilakukan pada fungsi formulir atau bentuk alter hook. Form building dan fungsi validasi dijalankan setiap kali panggilan balik ajax dipanggil. Cukup periksa $ form_state pada form build Anda atau ubah fungsi dan sesuaikan nilainya.

Lihat Mengatasi kesalahan "Pilihan ilegal telah terdeteksi ..."

jaimealsilva
sumber
1
Jika saya ingat dengan baik saya mencoba ini, tanpa berhasil dalam kasus saya, terima kasih
Codium
1
Saya khawatir ini juga tidak berhasil untuk saya.
kevin.coyle
Apakah ini tidak membuat formulir kurang aman?
Binny
Ya, semua komentar sebelumnya benar. Jawaban telah diperbarui.
jaimealsilva
3

Saya telah menghadapi masalah ini beberapa kali dalam Drupal 6, mengubah nilai daftar Pilih melalui Ajax.

Inilah yang dapat Anda lakukan

  1. Jika memungkinkan, cobalah untuk memasukkan semua nilai yang mungkin di dalam API Bidang, Anda perlu mengedit bidang itu, dan kemudian ketika Anda mengubah nilai-nilai, Anda harus memastikan bahwa hanya nilai-nilai yang tercantum dalam daftar.
  2. Solusi yang saya terapkan adalah, Anda dapat mengubah jenis bidang dari daftar Pilih ke bidang teks, dari API Bidang, dan meminta Drupal untuk menyimpan nilai apa adanya. Sekarang, pada runtime formulir, Anda harus mengubah formulir, mengubah jenis untuk memilih daftar, dan mendorong opsi, yang Anda inginkan. Sementara pengiriman juga, Anda harus menetapkan nilai yang benar yang diperlukan oleh bidang, yang akan disimpan dalam DB apa adanya. Pastikan submit handler Anda dipanggil sebelum form default send handler, untuk itu Anda dapat menggunakannyaarray_merge

Jika solusi pertama berfungsi untuk Anda, Anda akan menghemat banyak waktu untuk pengkodean dan pengujian berbagai hal. TETAPI jika daftar di drop down dinamis dan Anda tidak memiliki kendali atasnya, Anda mungkin harus menggunakan solusi kedua.

Lakukan posting jika Anda menghadapi masalah, saya telah melakukan cukup banyak pekerjaan pada masalah ini, untuk proyek saya, dan saya lakukan untuk ~ 50 formulir, PHEW !!! :)

Vaibhav Jain
sumber
3

Saya telah menemukan cara terbaik untuk mengatur ini #valuepada daftar yang dipilih.

Jika kita memiliki nilai di formstate dan itu ada di opsi kita maka kita tidak akan mendapatkan kesalahan. Jika nilai kami tidak ada dalam opsi maka pilih opsi pertama dalam opsi kami dan gunakan itu.

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

Solusi saya:

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

Dalam panggilan balik ajax Anda, tambahkan:

...

drupal_get_messages();
form_get_errors();

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

Sebagai tindakan pencegahan keamanan, _form_validate()fungsi inti memeriksa apakah kunci #pilihan elemen telah berubah dari apa yang ditetapkan dalam bangunan asli (yang mereka miliki). Dengan menelepon drupal_get_messages()dan form_get_errors()pada dasarnya kami memberi tahu Drupal untuk mengabaikan kesalahan / pesan apa pun saat menjalankan permintaan ajax kami. :)

JC3
sumber
Pesan kesalahan hilang tetapi elemen pilih masih mengandung kelas kesalahan. Bagaimana menghapus atau mencegahnya?
Tejas Vaidya
Ini setara dengan Drupal dengan memasang selotip di atas lampu peringatan di papan dasbor kendaraan Anda.
Frank Robert Anderson