fabianlindfors / multi.js

A user-friendly replacement for select boxes with the multiple attribute enabled
https://fabianlindfors.se/multijs
MIT License
953 stars 76 forks source link

Triggering events #8

Closed LukeMcLachlan closed 4 years ago

LukeMcLachlan commented 7 years ago

loads a long list (> 2000 items) very fast, way faster than multi-select script. However how do you trigger events on select or deselect? Or can you select an item by clicking a link? Such functionality would be extremely useful.

fabianlindfors commented 7 years ago

Hi! There are currently no built in events or functions for item selection but multi.js is closely bound to the original select element. When selecting an element the hidden select element is updated so you could bind events to it instead.

The same applies to selecting elements programmatically. multi.js follows the state of the select element. Simply change it's selection and trigger the change event on the element to make multi.js update itself.

Hope I could help!

konkitsu commented 7 years ago

That doesn't actually work. I just looked at the DOM in the Demo link and it's actually not updating the original select element at all. Which is why my bound events don't work.

image

fabianlindfors commented 7 years ago

I don't believe the Javascript changes will show up in the inspector but the underlying DOM data should be updating correctly.

Here I tried making the hidden select element visible and it updates with multi.js and the other way around.

skarmavbild 2017-03-16 kl 20 10 46

I also tried hooking into the select element's events and it seems to be working correctly for me. Which event are you listening for?

skarmavbild 2017-03-16 kl 20 13 51
konkitsu commented 7 years ago

That's interesting. It won't trigger properly.

I'm specifically listening only for the change event on the selector. I'm also using it on multiple selects. So it's more like:

var selects = $('select.multipleSelect');
selects.forEach(function(select) {
  multi(select);
  select.addEventListener('change', selectionChanged);
};

In any case, a lot of the items you likely want can be seen in the chosen library. https://harvesthq.github.io/chosen/

When I look at theirs and use their library, the events trigger properly and do change the DOM to include the selected attribute in the <option>.

fabianlindfors commented 7 years ago

Going to have to check out how chosen does it. Updating the DOM would be nice for debugging purposes!

Are you certain that your code works? The $('select.multipleSelect'); bit should be returning a jQuery collection which can't be iterated over with a standard ES5 forEach. Also if you're iterating over a jQuery collection then the individual elements would be jQuery objects which don't have the addEventListener function. Instead you would probably use the jQuery on function.

With jQuery the code could be written like this:

var $selects = $('select.multipleSelect');
$selects.multi();
$selects.on('change', function() { /* Event handler */ });