Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Using the new D7 AJAX form API stuff I'm trying to rebuild the multiselect options on the fly with AJAX.
I can see that $options is indeed being changed so I know that Drupal FAPI is doing what it needs to update $form_state. However, the form options actually don't change. I am not familiar enough with multiselect to understand if it is processing $form_state or doing anything funky with the $options.
Any ideas to point me in the right direction? Hopefully it's not a bug and it's possible to do with multiselect...
This is a crude example:
function my_form($form, &$form_state) {
$form['blah'] = array(
'#type' => 'select',
'#title' => t('Blah'),
'#options' => array(1 => '1', 2 => '2'),
'#ajax' => array(
'callback' => 'my_callback',
'wrapper' => 'multiselect',
),
);
$options = (isset($form_state['values']['blah']) && $form_state['values']['blah'] == 2) ? array('one' => 'One', 'two' => 'Two') : array('yes' => 'Yes', 'no' => 'No');
$form['other'] = array(
'#type' => 'multiselect',
'#title' => t('Other'),
'#prefix' => '<div id="multiselect">',
'#suffix' => '</div>',
'#options' => $options,
);
$form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
return $form;
}
function my_callback($form, &$form_state) {
return $form['other'];
}
function my_form_submit($form, &$form_state) {
}
Comments
Comment #1
mradcliffeI'm going to close this for now as I just tried with a normal select list, and I had the same issue.
I'm sorry for the spam.
Comment #2
mradcliffeI confirmed it working with a very simple form. Sorry for the spam again.
Comment #3
adf1969 CreditAttribution: adf1969 commented@mradcliffe:
You are not nuts or wrong.
I just tried it with standard "select" and it works fine.
If I change the widget to a multiselect it doesn't work (version: dev-2011-03-07)
The problem is that when the callback is processed (from a button-click or any other AJAX request) it doesn't send back the values in the 2 multiselect select boxes.
If I can find the time, I'll dive into the multiselect code and see if I can figure out why it isn't sending the values back with the POST.
Andrew.
Comment #4
BenVercammen CreditAttribution: BenVercammen commentedI'm currently facing the same issue, I don't get the values that are selected in the multiselect field when performing an AJAX callback triggered by another field.
As I was digging into the code, I figured out that only the "selected" items in the multiselect box are submitted. I also discovered that when submitting the form, the field will automatically select all options in the "_sel" box via
$('select.multiselect_sel').selectAll()
.So the only missing link here is that before relying on the selected data in your AJAX callback, you'll need to trigger the selectAll() code so all values are being put in your $_POST data. Otherwise they'll never end up in your $form_state['values'].
I'm still stuck on this last part, as I'm not sure which place is the best to trigger the selectAll function...
Comment #5
BenVercammen CreditAttribution: BenVercammen commentedOkay, I've found a rather nice and clean way to solve the issue... I've added the following lines to the multiselect.js script:
I'm not sure whether this can override or be overridden by other modules implementing this function. To make sure we don't override, we could put the callback in a variable and call it in our new function, which could look something like this:
One final obstacle (which is more just a matter of aesthetics) is to "deselect" all items when loading the page again, but I've already spent enough time on this for now...
Comment #6
jbeuckm CreditAttribution: jbeuckm commentedI see why this should work, but I added the beforeSubmit code above to my module and $form_state['values']['multiselect_element'] is still NULL.
This is my module's behavior code that submits the form when add/remove buttons are pressed:
Here is the element that makes the AJAX call:
I even modified the AJAX behavior code so that I could verify that the multiselect_sel elements had their options selected:
The alert reports null when an item is added and reports the option value when one is removed (ironically close to the opposite of what I want). I have tried moving my module's weight ahead and behind the multiselect module with the same results. How can I get my current values on AJAX?
Comment #7
kitt2012 CreditAttribution: kitt2012 commentedGentlemen,
How's it going? Thought I'd pop a post on here to see if anybody looking into this back in May found a solution. I've used the multiselect widgit in config forms, but have run into a problem using my current ajax form.
Looking through here it seems it was a current issue last year.
I will be having a stumble through the multiselect code today.
Thank you for any input.
xK
Comment #8
kitt2012 CreditAttribution: kitt2012 commentedSeems to me that the results will be saved through to a $_POST value if all the options are selected.
multielect.js attempts to do this on line 15. However as the button clicked is registered as an ajax button, this does not fire.
On further testing, if all the options are physically selected from the selected options side, and then an ajax button is clicked - all options are saved to $_POST.
Linking multiselect.js line 15 -19 to ajax clicked triggers in the FAPI, seems to me to be the key.
xK
Comment #9
Jarada CreditAttribution: Jarada commentedIn case anyone comes across this anew and wishes to get this sorted, the key to this fix is to do this selection before the form is serialized, not after. So instead of using beforeSend, which comes after, we use beforeSerialize.
In order to not override another module's functionality, I used this code (was working on preview, but you can adjust to work on other submits)...