Giải quyết lỗi Một sự lựa chọn bất hợp pháp đã được phát hiện


7

Tôi đã viết mã như dưới đây và tất cả đều hoạt động tốt, nhưng trong khi gửi biểu mẫu tôi nhận được lỗi bên dưới. Tôi đang cố gắng lọc thả xuống thứ hai dựa trên lựa chọn thả xuống đầu tiên.

Một sự lựa chọn bất hợp pháp đã bị phát hiện. Vui lòng liên hệ với quản lý.

Làm thế nào để tôi khắc phục lỗi đó?

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

tốt, bạn đã sử dụng '#validated' => TRUEnên quan tâm đến điều đó. Vì vậy, dự đoán của tôi là trong một số thuộc tính, bạn có khóa 'und' chứ không phải trong mảng biểu mẫu nơi bạn sử dụng khóa '#validated' ...?
30

Câu trả lời:


8

Vấn đề rất có thể là do yêu cầu về FAPI AJAX được ghi lại trong AJAX Forms trong Drupal 7 , mặc dù có thể dễ dàng bỏ qua.

Thay đổi về biểu mẫu chỉ phải được thực hiện trong chức năng xây dựng biểu mẫu (ajax_example_autocheckboxes () trong ví dụ ở đây), nếu không xác thực sẽ thất bại. Hàm gọi lại không được thay đổi biểu mẫu hoặc bất kỳ trạng thái nào khác.

Thực tế là bạn đang thiết lập phần tử biểu mẫu [#options]trong cuộc gọi lại AJAX chắc chắn là một vấn đề. Gọi lại AJAX chỉ nên trả về mảng hoặc HTML sẽ được in, không thay đổi biểu mẫu. Cuộc gọi lại đó chỉ nên chứa returncâu lệnh.

Các thay đổi đối với biểu mẫu của bạn nên được thực hiện trong form_alter. Ngoài ra, bạn nên sử dụng mảng form_state để kiểm tra xem giá trị đã được chọn cho lần thả xuống đầu tiên của bạn chưa. Điều này sẽ được cập nhật trong một yêu cầu AJAX.

Tôi khuyên bạn nên xem mô-đun ví dụ , cũng như các trang này để biết thêm thông tin về AJAX trong FAPI. Nó chắc chắn có thể là khó khăn.


Ngoài ra, đối với ví dụ mẫu, hãy xem danh sách Chọn động trong biểu mẫu (thả xuống phụ thuộc) (nhưng xem xét sử dụng " return $form['squadron_wrapper']" để làm cho phản hồi AJAX nhỏ hơn).
Top-Master

2

Phương pháp bên dưới chỉ có thể được sử dụng để bỏ qua lỗi cho các trường có giá trị được thêm vào thông qua ajax
Theo mã được đưa ra dưới đây, bạn có thể nhập phần tử trường gây ra lỗi để giá trị thay đổi trong danh sách thả xuống thứ hai do thay đổi trong thả xuống đầu tiên do sử dụng ajax sẽ không hiển thị lỗi.

/**
 * 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');      
    }
  }
}

1

Đây dường như là một lỗi cốt lõi https://www.drupal.org/node/153774 và các giải pháp được đề cập ở đây thực sự gây ra nhiều vấn đề hơn.

Khi #ajax được sử dụng cho một yếu tố được chọn, nếu có nhiều tùy chọn được chọn, "lỗi lựa chọn bất hợp pháp" sẽ được tạo. Nhưng tại sao? Sau một chút điều tra, hóa ra khi #ajax được bật, nó khiến phần tử được chọn gửi các giá trị như mảng (200.250) thay vì mảng (200 => 200, 250 => 250) Vì vậy, nó gây ra sự cố với mã xác thực tùy chọn bên trong Hàm _form_validate và nó không còn có thể kiểm tra các tùy chọn đã chọn đối với các tùy chọn khả dụng, đây là mã: Điều này chỉ xảy ra khi có nhiều hơn một tùy chọn được chọn và #ajax được sử dụng. Cách khắc phục là sửa giá trị đã gửi trước khi xác thực

Tôi đã viết một mô-đun để tự động khắc phục lỗi này, nó có thể không hoạt động trong mọi trường hợp nhưng đó là một cách giải quyết rõ ràng mà bạn có thể sử dụng nó làm điểm bắt đầu.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.