วิธีการหลีกเลี่ยง“ ตรวจพบตัวเลือกที่ผิดกฎหมาย” เมื่ออัปเดตค่ารายการที่เลือกผ่าน ajax?


10

ฉันมีสี่ฟิลด์อ้างอิงเอนทิตีไปยังเอนทิตีผู้ใช้ในแบบฟอร์ม รูปแบบโฮสต์เป็นรูปแบบการแก้ไขโหนด สามของพวกเขาจะเลือกรายการสุดท้ายคือInline Entity แบบฟอร์ม

หลังจากเพิ่มเอนทิตีผู้ใช้ผ่าน 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/…
Sina Salek

คำตอบ:


15

--- คำตอบเดิม ไม่ถูกต้องตรวจสอบการอัปเดตด้านล่าง

เพิ่งตั้ง

$bla['#validated'] = TRUE

ในการเลือกที่จะอัปเดตด้วย AJAX

ชำระเงิน"ตรวจพบการเลือกผิดกฎหมาย"

--- อัปเดต 17 ธันวาคม 2019 ---

จริง ๆ แล้วนั่นไม่ใช่คำแนะนำที่ดีนั่นเป็นเวลานานแล้วตอนนี้ฉันรู้ดีกว่า

ฟังก์ชัน Ajax callback ควรส่งคืนเฉพาะส่วนของแบบฟอร์มที่มีการเปลี่ยนแปลงหรือคำสั่ง ajax บางคำสั่งเท่านั้น

ในกรณีนี้การปรับเปลี่ยนรูปแบบจะต้องทำในฟังก์ชั่นแบบฟอร์มหรือเบ็ดแก้ไขรูปแบบ ฟังก์ชันการสร้างแบบฟอร์มและการตรวจสอบความถูกต้องจะถูกเรียกใช้ทุกครั้งที่มีการเรียกกลับ ajax เพียงตรวจสอบ $ form_state บนแบบฟอร์มการสร้างหรือปรับเปลี่ยนฟังก์ชันและปรับค่าตามความเหมาะสม

ดูแก้ไขข้อผิดพลาด "ตรวจพบตัวเลือกที่ผิดกฎหมาย ... "


1
ถ้าฉันจำได้ดีฉันพยายามทำสิ่งนี้โดยไม่ประสบความสำเร็จในกรณีของฉันขอบคุณ
Codium

1
ฉันเกรงว่าสิ่งนี้จะไม่ได้ผลสำหรับฉันเช่นกัน
kevin.coyle

สิ่งนี้ไม่ทำให้แบบฟอร์มมีความปลอดภัยน้อยลงหรือไม่?
Binny

ใช่ความคิดเห็นก่อนหน้าทั้งหมดถูกต้อง อัปเดตคำตอบแล้ว
jaimealsilva

3

ฉันประสบปัญหานี้หลายครั้งใน Drupal 6 การเปลี่ยนค่าของรายการที่เลือกผ่าน Ajax

นี่คือสิ่งที่คุณสามารถทำได้คือ

  1. หากเป็นไปได้พยายามแทรกค่าที่เป็นไปได้ทั้งหมดในใน Field API คุณต้องแก้ไขฟิลด์นั้นและเมื่อคุณเปลี่ยนค่าคุณจะต้องตรวจสอบให้แน่ใจว่าเฉพาะค่าที่แสดงรายการอยู่ในรายการ
  2. วิธีแก้ปัญหาที่ฉันนำมาใช้คือคุณสามารถเปลี่ยนประเภทฟิลด์จากรายการเลือกเป็นฟิลด์ข้อความจากฟิลด์ API และขอให้ Drupal บันทึกค่าตามที่เป็นอยู่ ตอนนี้บนรันไทม์ของฟอร์มคุณจะต้องเปลี่ยนแบบฟอร์มเปลี่ยนชนิดเพื่อเลือกรายการและตัวเลือกแบบพุชที่คุณต้องการ ในขณะที่ส่งเช่นกันคุณจะต้องกำหนดค่าที่ถูกต้องที่จำเป็นโดยฟิลด์ที่จะถูกบันทึกไว้ในฐานข้อมูลตามที่เป็นอยู่ ตรวจสอบให้แน่ใจว่ามีการเรียกใช้ตัวจัดการการส่งของคุณก่อนตัวจัดการการส่งแบบฟอร์มเริ่มต้นเพื่อที่คุณจะได้ใช้array_merge

หากวิธีแก้ปัญหาแรกเหมาะกับคุณคุณจะประหยัดเวลาได้มากในการเขียนโค้ดและทดสอบสิ่งต่างๆ แต่ถ้ารายการในรายการแบบหล่นลงเป็นแบบไดนามิกและคุณไม่สามารถควบคุมมันได้คุณอาจต้องใช้วิธีที่สอง

ทำโพสต์ถ้าคุณประสบปัญหาใด ๆ ฉันได้ทำงานค่อนข้างมากกับปัญหานี้สำหรับโครงการของฉันและฉันทำรูปแบบ ~ 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 :)


ข้อความแสดงข้อผิดพลาดหายไป แต่องค์ประกอบที่เลือกยังคงมีคลาสข้อผิดพลาดวิธีการลบหรือป้องกันได้อย่างไร
Tejas Vaidya

นี่คือ Drupal เทียบเท่ากับการวางเทปบนไฟเตือนบนแผงหน้าปัดรถยนต์ของคุณ
Frank Robert Anderson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.