it-swarm.asia

حل الخطأ "تم الكشف عن اختيار غير قانوني ..."

لقد كتبت رمزًا مثل أدناه وكل شيء يعمل بشكل جيد ، ولكن أثناء إرسال النموذج ، أحصل على الخطأ أدناه. أحاول تصفية القائمة المنسدلة الثانية بناءً على التحديد المنسدل الأول.

وقد تم الكشف عن اختيار غير مسموح به. يرجى الاتصال بمدير الموقع.

كيف أتغلب على هذا الخطأ؟

function dynamic_location_dropdown_form_alter(&$form, $form_state, $form_id) {
  if($form_id == 'product_node_form') {

  $location_options = array();

  if(isset($form['field_destination']['und']['#default_value'][0])) {
    $destination = $form['field_destination']['und']['#default_value'][0];
  }
  else {
    $destination = 0;
  }

  $location_options = dynamic_location_dropdown_locations($destination);

  $form['field_destination']['und']['#ajax'] = array(
    'event' => 'change',
    'wrapper' => 'squadron-wrapper',
    'callback' => 'dynamic_location_dropdown_ajax_callback',
    'method' => 'replace',
  );
  $form['field_product_location']['#validated'] = true;
  $form['field_product_location']['und']['#prefix'] = '<div id="squadron-wrapper">';
  $form['field_product_location']['und']['#suffix'] = '</div>';
  $form['field_product_location']['und']['#options'] = $location_options;
  }
}

function dynamic_location_dropdown_ajax_callback($form, $form_state) {
  $country_id = $form['field_destination']['und']['#value'];
  $form['field_product_location']['#validated'] = true;
  $form['field_product_location']['und']['#options'] =  dynamic_location_dropdown_locations($country_id);

  return $form['field_product_location'];
}

function dynamic_location_dropdown_locations($destination_id) {
  $nodes = array();
  $nodes[''] = '- None -';
  if($destination_id != '') {
    $select = db_query("
      SELECT node.title AS node_title, node.nid AS nid, node.created AS node_created
      FROM {node} node
      LEFT JOIN {field_data_field_location_country} field_data_field_location_country 
      ON node.nid = field_data_field_location_country.entity_id 
      AND (field_data_field_location_country.entity_type = 'node' 
      AND field_data_field_location_country.deleted = '0')
      WHERE (( (node.status = '1') 
      AND (node.type IN  ('location')) 
      AND (field_data_field_location_country.field_location_country_nid = $destination_id)))
      ORDER BY node_title ASC
    ");
    $nodes[''] = '- None -';
    foreach ($select as $node) {
      $nodes[$node->nid] = $node->node_title;
    }
  }

  return $nodes;
}
7
Hacker

المشكلة على الأرجح بسبب متطلبات FAPI AJAX الذي تم توثيقه في نماذج AJAX في Drupal 7 ، على الرغم من أنه يمكن غاب بسهولة.

يجب إجراء التغييرات على النموذج فقط في وظيفة أداة إنشاء النماذج (ajax_example_autocheckboxes () في المثال هنا) ، وإلا سيفشل التحقق من الصحة. يجب ألا تغير وظيفة رد الاتصال النموذج أو أي حالة أخرى.

حقيقة أنك تقوم بتعيين عنصر النموذج [#options] في AJAX يمثل بالتأكيد مشكلة. يجب أن يرد AJAX رد الصفيف أو HTML المراد طباعته فقط ، وليس تغيير النموذج. يجب أن يحتوي فقط على العبارة return.

يجب إجراء التغييرات على النموذج الخاص بك في form_alter. أيضًا ، يجب عليك استخدام مصفوفة form_state للتحقق مما إذا تم اختيار قيمة لأول قائمة منسدلة. سيتم تحديث هذا خلال طلب AJAX طلب.

أوصي بإلقاء نظرة على الوحدة الأمثلة ، بالإضافة إلى هذه الصفحات لمزيد من المعلومات حول AJAX في FAPI. يمكن أن يكون الأمر صعبًا بالتأكيد.

8
goron

يمكن استخدام الطريقة أدناه لإهمال الأخطاء فقط للحقول التي تمت إضافة القيمة إليها من خلال ajax
وفقًا للرمز الموضح أدناه ، يمكنك إدخال عنصر الحقل الذي يعطي خطأ بحيث تتغير القيمة في القائمة المنسدلة الثانية بسبب التغيير في القائمة المنسدلة الأولى بسبب استخدام ajax لن يظهر خطأ.

/**
 * Custom Form Validation.
 * Removes all form validation errors caused by a 'foo][bar' form element.
 */
function my_module_form_validate($form, &$form_state) {
  $errors = form_get_errors();
  if ($errors) {
    // Clear errors.
    form_clear_error();
    // Clear error messages.
    $error_messages = drupal_get_messages('error');
    // Initialize an array where removed error messages are stored.
    $removed_messages = array();


// Remove all errors originated by the 'foo][bar' element.
    foreach ($errors as $name => $error_message) {
      if ($name == 'foo][bar') {
        $removed_messages[] = $error_message;
        unset($errors[$name]);
      }
    }


// Reinstate remaining errors.
    foreach ($errors as $name => $error) {
      form_set_error($name, $error);
      // form_set_error() calls drupal_set_message(), so we have to filter out
      // these from the error messages as well.
      $removed_messages[] = $error;
    }


// Reinstate remaining error messages (which, at this point, are messages that
    // were originated outside of the validation process).
    foreach (array_diff($error_messages['error'], $removed_messages) as $message) {
      drupal_set_message($message, 'error');      
    }
  }
}
2
harshal

يبدو أن هذا خطأ أساسي https://www.drupal.org/node/153774 والحلول المذكورة هنا تسبب بالفعل المزيد من المشاكل.

عند استخدام #ajax لعنصر تحديد ، سيتم إنشاء "خطأ اختيار غير قانوني" في حالة تحديد أكثر من خيار. لكن لماذا؟ بعد قليل من الاستقصاء اتضح أنه عند تمكين #ajax يتسبب عنصر التحديد في إرسال قيم مثل المصفوفة (200،250) بدلاً من المصفوفة (200 => 200، 250 => 250) لذا يتسبب في مشكلة مع رمز التحقق من الخيارات داخل دالة _form_validate ولم يعد بإمكانها التحقق من الخيارات المحددة مقابل الخيارات المتاحة ، إليك الرمز: يحدث هذا فقط عند تحديد أكثر من خيار واحد واستخدام #ajax. الإصلاح هو تصحيح القيمة المقدمة قبل التحقق من الصحة

لقد قمت بكتابة وحدة نمطية لحل هذا الخطأ تلقائيًا ، وقد لا تعمل في جميع الحالات ولكن هذا حل واضح يمكنك استخدامه كنقطة بداية.

https://www.drupal.org/sandbox/sinasalek/2312751

1
Sina Salek