mikemaccana
mikemaccana

Reputation: 123268

How can I add a 'change' event listener for a styled select?

Obviously, if I have a 'select' element, I can add an event listener for changes using some basic JS:

document.querySelector('select').addEventListener('change', function(ev){
  console.log('Changed', ev.target.value)
})

Click the 'select' element, modify the value, the log fires. Simple stuff.

However I'm working on a library for styled select boxes - like chosen or select2 without the jQuery dependency.

In my library, clicking the styled select box changes the .value of the real select box:

query('select').value = newValue;

I can see this is working if I make the real select box visible.

However, changing the value of the select box through JS doesn't trigger the select boxes 'change' event.

Is there a way I can change the select boxes value though JS and still have change events attached to the select box fire?

Upvotes: 2

Views: 8147

Answers (3)

mikemaccana
mikemaccana

Reputation: 123268

Based on @Hamix's excellent answer, and some advice from MDN about createEvent() being out of date, I eventually went with:

var changeEvent = new Event('change');
realSelect.dispatchEvent(changeEvent);

Here's a demo - again based on @Hamix's jsfiddle so go give him an upvote.

Upvotes: 0

Hamix
Hamix

Reputation: 1335

Javascript

function fireEvent(element, event) {
    if (document.createEventObject) {
        // dispatch for IE
        var evt = document.createEventObject();
        return element.fireEvent('on' + event, evt)
    } else {
        // dispatch for firefox + others
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent(event, true, true); // event type,bubbling,cancelable
        return !element.dispatchEvent(evt);
    }
}

document.querySelector('select').addEventListener('change', function (ev) {
    console.log('Changed', ev.target.value)
});

btn.onclick = function () {
    select.selectedIndex = 2;
    var obj = document.querySelector('select');
    fireEvent(obj, 'change');
}

User call

var yourPlugin=new CustomSelect(options);
yourPlugin.value("3");

Plugin function

function value(val) {
    if (!val) return select.value;
    select.value = val;
    fireEvent(select, 'change');
}

DEMO

Upvotes: 1

Martin Ernst
Martin Ernst

Reputation: 3279

Just an idea: Trigger the event by yourself after changing the value:

var el = query('select');
el.value = newValue;
el.dispatchEvent(new Event('change'));

Upvotes: 0

Related Questions