By joshi.rohit100 on
I have a custom form which contains two multiselect lists. One list is populated by #ajax on another.
Ajax is working fine for multiple selections. Now I added a file upload field on the form. Again Ajax working fine when I select only one value from the select list.
But When I select multiple values on select list, it throws "Illegal choice error".
This error occurs only when there is file upload field on the form.
Here is the sample code :-
function multiselect_form_test_form($form, &$form_state) {
$form['select_1'] = array(
'#type' => 'select',
'#options' => array(1 => 'One', 2 => 'Two'),
'#title' => 'Select 1',
'#ajax' => array(
'callback' => 'ajax_callback_test',
'wrapper' => 'ajax-wrapper-test',
),
'#multiple' => TRUE,
);
$option_2 = array();
if (isset($form_state['values'])) {
if (isset($form_state['values']['select_1'][1])) {
$option_2[3] = 'Three';
}
if (isset($form_state['values']['select_1'][2])) {
$option_2[4] = 'four';
}
}
else {
$option_2 = array(3 => 'Three', 4 => 'four');
}
$form['select_2'] = array(
'#type' => 'select',
'#options' => $option_2,
'#title' => 'Select 2',
'#prefix' => "<div id='ajax-wrapper-test'>",
'#suffix' => "</div>",
'#multiple' => TRUE,
);
$form['image_1'] = array(
'#type' => 'managed_file',
'#title' => 'Upload File',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
function ajax_callback_test($form, &$form_state) {
return $form['select_2'];
}
Comments
solution for multiselect ajax
Hi,
The problem that you specified is due to the fact that when more than one options(both one and two in your example) have been selected
from first dropdwon and there is a file upload field, the $_POST['select_1'] does not contain values in the correct format. The correct
format is
but it contains
which actually causes the error.
If you go include 'callback' in your #ajax then the ajax_form_callback() (default page callback for system/ajax) in includes/ajax.inc is called.
If you print $_POST at the beginning of this function ajax_form_callback(), you will find the above discrepancy. So there might be some problem in the
process which encrypts and sends data to the page callback ( i.e ajax_form_callback()) . I still do not find out where the $_POST data got tampered but
devise an alternative solution for the above problem. The solution is instead of using 'callback' in your #ajax use 'path' in your #ajax, create
a menu link for the 'path' and implement the page callback in the following way.
Create a menu link in your hook_menu
replace
'callback' => 'ajax_callback_test',with
'path' => 'custom_ajax_callback',in
Add the following page callback for 'custom_ajax_callback'
With Regards
Debarya Das
Thanks
Thanks Debarya for your time. It is working but throwing warning
"Warning: Invalid argument supplied for foreach() in menu_unserialize() (line 400 of C:\wamp\www\d7\includes\menu.inc)."
Removal of the warning message
Hi,
Change
'access arguments' => TRUE,in
with
'access arguments' => array('Administer content'),or define a new permission string.
With Regards
Debarya Das
Thanks Again
Thanks again for help.
A quick note, $_POST values
A quick note, $_POST values should never be accessed in Drupal forms, as the values are unsanitized. The values in $form_state['values'] should be used.
Contact me to contract me for D7 -> D10/11 migrations.
$_POST used only to prevent options tampering
Hi Jaypan,
It's true that $_POST should not be used in Drupal form because the values are unsanitized. In the above example, I have used $_POST only to re-structure the $_POST in correct format. After that I used standard Drupal way to deal with form. So it will not create a problem. When you are using the 'callback' mechanism in #ajax, the system/ajax is called via POST mechanism(In misc/ajax.js). So Drupal also uses $_POST, but it then sanitize the input using it's security function. $_POST does not proved to be harmful until you involve the values from $_POST directly into the SQL query or store them into database or perform some other coding task. So in this case it will not be applicable.
With Regards
Debarya Das
How do I impelent this on a standard node edit form?
I have the same issue on a standard node edit form which has a multiselect entity reference field supplied by a view and a several file upload fields, any of which trigger the "illegal choice" error. How would I implement this fix? Where do the code patches go? A roadmap would be useful.
Do we have patch for this issue.
Thanks joshi.rohit100 for reporting this issue. I was also facing same issue and failed to find why multiselect was not working on node alter form. This issue is core issue and should be reported. It is an unrealistic behaviour. This issue needs to fix in proper way.
Ok i reached here https://www.drupal.org/node/1045208
This issue was old one.