I've created custom ajax powered select box. When there is an Image widget in this form, selecting multiple values, causes Illegal choice error. What is wrong?
/**
* Implement hook_form_alter().
*/
function mymodule_form_alter(&$form, &$form_state, $form_id) {
if (isset($form['#entity_type']) && isset($form['#bundle'])) { // entity form
$form['items'] = array(
'#type' => 'select',
'#options' => array(
t('Item 1'), t('Item 2')
),
'#multiple' => TRUE,
'#ajax' => array(
'callback' => 'mymodule_update_subitems',
'wrapper' => 'mymodule-subitems-field-wrapper',
'effect' => 'fade',
'speed' => 'fast',
),
);
$form['subitems'] = array(
'#type' => 'item',
'#markup' => 'Just for dev',
'#prefix' => '<div id="mymodule-subitems-field-wrapper">',
'#suffix' => '</div>',
);
}
}
function mymodule_update_subitems($form, $form_state) {
return $form['subitems'];
}
| Comment | File | Size | Author |
|---|---|---|---|
| #40 | drupal-1045208-40.patch | 864 bytes | imyaro |
| #36 | drupal-1045208-31-36-interdiff.txt | 1.01 KB | rosk0 |
| #36 | drupal-1045208-36.patch | 845 bytes | rosk0 |
| #31 | drupal-multiselect_select_form_ajax-1045208-31.patch | 833 bytes | mkolar |
| #1 | Capture.PNG | 14.01 KB | elaman |
Comments
Comment #1
elamanError message screenshot.
Comment #2
rfayMy bet is that with multiple values selected, the ID is no longer unique. It also may be that you're affecting more form items than you expect.
Comment #3
elamanAs i wrote before, if there is no Image widget in altered form, there is no error. How it can be?
Comment #4
rfay@Peritus, I'm interested in the problem. If you'll package it up as a module and attach it to the issue I'll take a shot at debugging it. Please also provide the content type that gives you trouble (as a feature or export) and step-by-step instructions on how to recreate the problem.
Comment #5
elamanThanks for response. Here is the steps to recreate problem:
Comment #6
rfayI'll take a look. Probably this weekend.
Thanks,
-Randy
Comment #7
rfayI am perfectly able to add multiple images (which is what I thought you were saying).
When I select any of the items in the select box I get
Edit: I am completely able to select multiple items in the select added by this module, and submit the results, without a validation error.
Comment #8
rfayThere is a problem in core here, but your problem still exists when it's fixed. I opened #1049462: Usage of deprecated $form_state['clicked_button'] causes bugs during AJAX submissions by non-buttons for that problem.
$clicked_button = end($form_state['triggering_element']['#parents']);
Comment #9
rfayI agree with you that this a bug.
Here's what happens:
Fields other than filefields don't seem to have this problem, as far as I can tell.
This is not fundamentally a problem with multiselect and ajax. I tried adding #multiple => TRUE to the "Generate Checkboxes" example in the AJAX Example, of course it means that the resultant value becomes an array, messing up the logic, but it works with a little alteration.
This is pretty much an edge case, but it is probably a sign of something wrong in FAPI.
Comment #10
rfayI asked effulgentsia to take a look at this as well.
Comment #11
rfayUpdate: git bisect says that the validation fail part of this was introduced in #995854: #ajax doesn't work at all if a file element (or enctype => "multipart/form-data") is included in the form on December 23. However, I don't think it actually worked before; the form-alter didn't seem to happen; but the validation failure didn't occur.
Comment #12
elamanI've no error after applied #6 patch from #990260: create a new book from non-book content type gives "Passed variable is not an array..." error. issue.
But still remains Illegal choice error on multiple option select. If i select only one option, there is no error and everything work as it should. So where exactly bug is? File module?
Comment #13
rfayYes, you've discovered a completely different problem, which is why this bug remains open and we'll pursue #1049462: Usage of deprecated $form_state['clicked_button'] causes bugs during AJAX submissions by non-buttons over there. (BTW, that solves the same issue as #990260: create a new book from non-book content type gives "Passed variable is not an array..." error., so I marked it as a dup)
Comment #14
elamanOk. Thanks :)
Comment #15
effulgentsia commentedsubscribing to look at later
Comment #16
fp commentedRan into this issue too. Subscribing.
Comment #17
dscutaru commentedRan into this issue too,
It seems this happens only when form contains multiple select element and file/image element(s)
If I replace the select with checkboxes it works fine - we can call this as a workaround
After some digging I found the problem being in the misc/ajax.js in the Drupal.ajax.prototype.beforeSend, aprox line 351
there is a comment and the trouble code
in the case of multiple select v is an Array, this array later in misc/jquery.form.js is used to create a hidden form element and at this point it is forced into a string, so for example [1,2,3] became "1, 2, 3"
In the end you end up with one string value in the $form_state['values'], instead of an array, for Ex:
$form_state['values']['field_cat']['und'][0][tid] = '2,4,7';
instead of
$form_state['values']['field_cat']['und'][0][tid] = '2';
$form_state['values']['field_cat']['und'][1][tid] = '4';
$form_state['values']['field_cat']['und'][2][tid] = '7';
If somehow in 2015 someone will also run into this issue and will need a solution here is mine:
replace
with
Comment #18
bneel commented#17 works but break views (7.x-3.7).
You need to replace
with
thanks @dscutaru
The diff between your suggestion is :
if (v !== null && typeof v == "object")instead ofif (typeof v == "object")Comment #19
brendanrjohn commenteddid anyone else test this? I tried #18, but it seems to stop all ajax on the site. And reversing didn't fix.
Comment #20
brendanrjohn commentedok fixed my own probs by using a backup of the ajax.js file.
Comment #21
koppie commentedNeither #17 nor #18 worked for me. Ajax still worked, but I still got the "illegal choice" error.
Comment #22
moonray commentedMy use case is an entity reference multi-select field and any additional multi-value field. First add a value to the entity reference field. You then click on the 'add another item' on that additional field twice; the second time gives the illegal choice error.
#18 fixed the issue for me. No more illegal choice errors.
Comment #23
moonray commentedSetting back to 'needs work' since we don't have an actual patch file that can be tested.
Comment #24
moonray commentedAnd an actual patch based on #18.
Comment #26
moonray commentedDid some additional testing, and it looks like the problem persists. In my case, it's an issue with entityreference module, though.
Comment #27
vistree commentedHi, I also have this problem with entityreference. Nothing described on this page helped. Any progress?
Comment #28
debaryadas commentedHi,
A same issue has been discussed at https://drupal.org/node/2229055 and a solution has been provided. Anyone interested can check it.
Comment #29
drupup commentedSame issue.
Setup:
Standard node add/edit form
Entity reference fields, multiselect, selection filtered by view, checkbox
File upload fields
I've been checking the logs, and it appears that as soon as a file is uploaded it breaks the view used to generate the items for the entity reference field:
Notice: Trying to get property of non-object in eval() (line 2 of .../sites/all/modules/views/plugins/views_plugin_argument_default_php.inc(53) : eval()'d code).
The "Illegal choice" notice happens because the entity reference field is now, technically speaking, "empty" despite the fact that it has multiple items selected.
If I switch the entity reference field so it is not filtered by view the problem goes away.
It doesn't matter whether there are zero, one, or multiple items selected...the view throws out the notice every time the upload field is used. So the issue is clearly with the view that filters the field.
Switching between widgets (select list, autocomplete, checkbox), as has been suggested elsewhere, has no effect. I've tried to implement #17/#18, but neither had any effect.
I'd be willing to try to implement the workaround suggested in #28, but will need better instructions about how and where to implement the code. My situation involves a standard node edit screen, not a custom form.
This is a fairly common use case. This issue queue is going to grow until this is resolved.
Comment #30
bartram commentedYou can create an empty beforeSend AJAX method that won't disable the triggering element to avoid this issue:
Comment #31
mkolar commentedI have same problem with taxonomy term ref (multiselect options).. And code from #24 helped. Here is the patch for actual 7.x branch.
Comment #32
cilefen commentedComment #33
sassafrass commentedMy scenario: I have created a custom entity. In the corresponding custom form I implemented a select_or_other element where '#multiple' => TRUE. Upon selection, ajax is used to populate a second select element.
Works as expected under the following conditions:
- Works if I don't have a file field associated with the entity/form.
- Works if I do have a file field associated with the entity/form, but I only select a single value
Doesn't work as expected when:
- I add a file field and I attempt to select more than one value
I tried the patch in #31, but it did not work for this scenario.
My scenario and results are similar to the issue discussed here: https://drupal.org/node/2229055
I implemented a similar solution in that I check the values submitted. If it has been converted to a string, I explode the string into an array and use that instead.
Comment #34
skaduPatch in #31 works for me. I am using an entityreference multi select field. Without the patch, if I have more than one option selected in that list and I trigger ajax (from another field) I would get the Illegal Choice messages. However, with this patch, I am able to work within the form as expected.
Comment #35
happysnowmantech commentedPatch in #31 worked for me when I encountered this problem with an taxonomy term entityreference multi select field with reference_option_limit module enabled.
Comment #36
rosk0Used this patch heavily in one of my projects, works well.
Attaching same patch with small code style fixes.
Comment #37
vladan.me commentedAs mentioned in #33, it does not work for case when there's a file field and multiple select. As a matter of fact, changed piece of code doesn't even trigger in that particular case. Not quite sure how to proceed from here, any ideas?
EDIT:
Actually, it didn't trigger because other module/theme override it. In my particular case, bootstrap theme has its own ajax.js file. This patch is good to go.
Comment #38
vladan.me commentedComment #39
David_Rothstein commentedIs it really correct that the first one doesn't need to be run through Drupal.checkPlain() like the second one? If it doesn't, why not?
Also, this issue doesn't mention Drupal 8 anywhere - does the problem exist in Drupal 8 too? If so, we need to get it fixed there first.
Finally, this issue could probably use a new title and an issue summary update... it is a little unclear exactly what this issue is about, but I don't think it has anything specific to do with form altering the node form (even though that is in the current issue title).
Comment #40
imyaro commentedPatch works for me.
Many thanks, I spend too much time with this problem
Yes, I agree with David_Rothstein
It should be passed throught the checkPlain too.
Added it in the new patch.
Comment #42
trentl commentedI tried both patches from #36 and #40 to no avail.
Here is my situation: 2 drop-down select boxes in a custom content type each referencing other entities via an Entity View. Entity view is restricted by a group id field passed via the URL (view argument).
Initially, upon opening the node/add// url, both fields are properly populated with selections. Fill out form and select items from each drop-down select and attempt to save.
Form is rejected with "Illegal Choice" error. dblog provides this -> "Illegal choice (node id) in (field name) element."
Working with the same logic I have other content types that reference another Entity without issue. However, they only reference a single Entity, not multiple (as in the case of this particular content type).
Not sure if this helps, but thought I'd provide the feedback to the community.
Comment #43
Yorgg commentedI can confirm that none of the patches work with the current version of Drupal 7.