Skip to content

Conversation

@ramebd
Copy link

@ramebd ramebd commented Oct 11, 2012

SelectMenu is not triggering the "onchange" event for the underlying select. This seems to be because the "change" event is not explicitly being called. Adding the line above into the "select" event seems to work. This is probably not the appropriate place to put this (perhaps it should go in jquery.ui.menu.js somewhere?), but it demonstrates the problem & at least a workaround.

Reference information from the answer on StackExchange here: http://stackoverflow.com/questions/5317146/html-javascript-jquery-document-onchange-for-hidden-element-not-working/5317385#5317385

SelectMenu is not triggering the "onchange" event for the underlying select. This seems to be because the "change" event is not explicitly being called. Adding the line above into the "select" event seems to work. This is probably not the appropriate place to put this (perhaps it should go in jquery.ui.menu.js somewhere?), but it demonstrates the problem & at least a workaround. Reference information from the answer on StackExchange here: http://stackoverflow.com/questions/5317146/html-javascript-jquery-document-onchange-for-hidden-element-not-working/5317385#5317385
@scottgonzalez
Copy link
Member

Why is it important to bind to the original element's change event instead of the plugin's change event?

@ramebd
Copy link
Author

ramebd commented Oct 11, 2012

It seems that the intention of the _trigger call is to process the "change" event, but that is only triggering the "change" event for the plugin object itself, NOT the underlying select that the "selectmenu" object is proxying for.

@scottgonzalez
Copy link
Member

That's how all of jQuery UI works. We never proxy events back to the original element. We only deal with new custom events. Again, why is it important to bind to the original event instead of the plugin's event?

@ramebd
Copy link
Author

ramebd commented Oct 11, 2012

Perhaps an example would make it clearer :)

I have the following code in my original select:

<select onchange='userid_changed(this);' class='selectmenu' id='userid'> option, option, option, etc </select>

Selectmenu object is created with:

$('select.selectmenu').selectmenu();

The original select is hidden and replaced with the new 'selectmenu' object and all works as expected.

But, the problem comes when I actually choose an item from within the selectmenu. Because the selectmenu plugin is not calling the 'change' event of the underlying select, my "userid_changed" function is not being called.

I referenced the StackExchange comment because it seemed to both explain & address the problem I was having.

It seems that simply changing the "selectedIndex" of the underlying select (as the plugin is doing) is not sufficient to actually trigger the 'onchange' event in the browser. I don't know if this is true across the board, and perhaps its actually a browser problem, but I tried IE9 and Firefox15 and both exhibited the same behaviour.

Specifically calling the jQuery "change" event on the select triggers the 'onchange' and my function is run.

I wont be shocked if this is the wrong way to fix the problem, I'm just trying to point out the issue and help progress to a fix.

@scottgonzalez
Copy link
Member

I fully understand what is happening, and it behaves the same in all browsers. My question is why can't you just use the plugin's events instead? We cannot guarantee that native events work as expected in all of our plugins.

@ramebd
Copy link
Author

ramebd commented Oct 11, 2012

Well, I guess my expectation was that the plugin would inherit & replicate the underlying object, proxying back any events that weren't handled internally. That and the selectmenu plugin used to work without having to generate a custom 'change' event for each selectmenu :)

It does make sense from a plugin perspective (I see where you're coming from there now) to provide a (plugin) controlled method of replicating functionality that cannot be guaranteed to behave as per native. However, that's why I thought to call the jQuery.change() event on the select. It seemed the most sensible (jQuery related) way of replicating the underlying functionality.

I simply assumed that the failure to do this may have simply been a regression due to the (significant) amount of changes made to the plugin since the last version I was upgrading from.

The down side of not applying this type of fix is that a .selectmenu() call will be required for each select on the page that has a custom "onchange" function. In my case, this becomes four separate .selectmenu({ change: function() {} }); in my header <script />.

@scottgonzalez
Copy link
Member

Or you can generalize it in your own code and just proxy the event once for any element that it occurs on.

$( document ).on( "selectmenuchange", function( event ) { $( event.target ).change(); });
@ramebd
Copy link
Author

ramebd commented Oct 12, 2012

As a followup, @scottgonzalez 's comment made me think about this in a different way. The workaround for the issue of selectmenu not triggering the underlying select "onchange" event is simply to init selectmenu like this:

$('select.selectmenu').selectmenu({ change: function () { $(this).change(); } });

It uses the same solution that I proposed, but does not need to modify the jquery.ui.selectmenu.js code. Which clearly makes more sense, since the capability to do what I need is already there, it just needed a bit more thinking about how achieve it.

@ramebd
Copy link
Author

ramebd commented Oct 12, 2012

I came to the same conclusion, thanks Scott :)

@ramebd ramebd closed this Oct 12, 2012
@scottgonzalez
Copy link
Member

No problem. I wanted to talk through the issue because sometimes there are cases that must be solved inside the plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants