Home > Net >  Trigger change event on individual option selected in `select` with `multiple` attribute
Trigger change event on individual option selected in `select` with `multiple` attribute

Time:03-04

Given a standard select as per below, is is possible by jQuery (or otherwise) to trigger a change event on individual options - As multiple may be selected, I don't want to trigger on the select but on the option?

<select multiple="">
  <option>Test 2</option>
  <option>Testing 3</option>
</select>

Something like:

$(`option`).trigger(`change`);

CodePudding user response:

One way is to keep a reference of the last state of the multi-select, then compare to find the most recently clicked option.

let sels = [];
$(`select`).on(`change`, function() {
  $(this).val().forEach(v => {
    if (sels.indexOf(v) === -1) {
      console.log(`The option most recently selected is ${v}`);
    }
  })
  sels = $(this).val();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple="">
  <option value='2'>Test 2</option>
  <option value='3'>Testing 3</option>
</select>

CodePudding user response:

There is no change on an option. If you want it to act like a user is selecting option by option in the select, you would need to select the option and trigger the change event on the select.

const mySelect = document.querySelector("#mySelect");
mySelect.addEventListener("change", function () {
  const selected = Array.from(mySelect.querySelectorAll("option:checked")).map(x => x.value);
  console.log(selected);
});


function triggerEvent(elem, event){
  const evt = document.createEvent("HTMLEvents");
  evt.initEvent(event, true, true );
  elem.dispatchEvent(evt);
}

const values = ['1','2','4'];
values.forEach(val => {
  const opt = mySelect.querySelector(`[value="${val}"]`);
  if (opt) {
    opt.selected = true;
    triggerEvent(mySelect, 'change');
  }
});


/*
const values = ['1','2','4'];
const options = mySelect.querySelectorAll("option");
options.forEach(opt => {
  const initial = opt.selected;
  opt.selected = values.includes(opt.value);
  if (opt.selected !== initial) {
    triggerEvent(mySelect, 'change');
  }
});
*/
<select id="mySelect" multiple>
  <option value="1">one</option>
  <option value="2">two</option>
  <option value="3">three</option>
  <option value="4">four</option>
</select>

The real solution is why is your page not set up to handle default values? Seems like you should just be able to call a method with the values and be done. Seems odd to rely on events.

  • Related