9

I am trying to change selectedindex of a select tag. But onchange event is not triggered while changing the index via jquery.

I am creating option for the select tag dynamically. I won't be knowing the values of option tag.

Is there any other method to achieve it? Here is my code snippet. Feel free to give inputs.

function callFunc(obj) {
  console.log(obj.value);
}

setTimeout(() => {
  $("#select1")[0].selectedIndex = 2;
}, 2000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select1" onchange="callFunc(this);">
  <option value='0'>select ....</option>
  <option value='1'>1</option>
  <option value='2'>2</option>
  <option value='3'>3</option>
</select>

1
  • how do you create your select dinamically? Commented Dec 27, 2017 at 7:17

3 Answers 3

11

trigger change (and beforechange) when selectedIndex is modified

..a simple VanillaJS function:

    // equivalent to jquery: $(el).val(index).trigger('change');
    function setSelectedIndex(el, index){
       el.selectedIndex = index;
       el.dispatchEvent(new Event('change', { bubbles: true }));
    }

    // sample call - setSelectedIndex(select1, 2)
    setTimeout(setSelectedIndex, 2000, select1, 2);
    

... or if you want to make this a general feature for all select elements (present and future):

// put this somewhere central
(function selectedIndexWithEvents(proto, selectedIndex) {
  const original = Object.getOwnPropertyDescriptor(proto, selectedIndex);
  if (!original || !original.set) return;
  Object.defineProperty(proto, selectedIndex, {
    get() { return original.get.call(this); },
    set(value) {
      if (this[selectedIndex] === value) return; // unchanged
      if (this.dispatchEvent(Object.assign(new Event('beforechange', { bubbles: true, cancelable: true }), { newValue: value })).defaultPrevented) return; // preventDefault(true)
      original.set.call(this, value);
      this.dispatchEvent(new Event('change', { bubbles: true }));
    }
  });
})(HTMLSelectElement.prototype, "selectedIndex");


// your sample call now will trigger beforechange and change
function callFunc(el){ console.log('changez', el); }
setTimeout(() => { $("#select1")[0].selectedIndex = 2; }, 2000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select1" onchange="callFunc(this);">
  <option value='0'>select ....</option>
  <option value='1'>1</option>
  <option value='2'>2</option>
  <option value='3'>3</option>
</select>

Sign up to request clarification or add additional context in comments.

1 Comment

If others are as confused as I was by { bubbles: true }, it is documented there, and controls whether the event is propagated through the parents: The bubbles read-only property of the Event interface indicates whether the event bubbles up through the DOM tree or not.
4

You need to trigger the change yourself calling change() on the element. I have replaces the selectedIndex with val function's call. Also attach event handler using javascript, not via markup.

const select = $("#select1");

select.on('change', function() {
  console.log(this.value);
});

setTimeout(() => {
  select.val(2).change();
}, 2000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select1">
  <option value='0'>select ....</option>
  <option value='1'>1</option>
  <option value='2'>2</option>
  <option value='3'>3</option>
</select>

8 Comments

If the values is dynamic, how will I select it then ?
Didn't understand you. Can you clarify a bit?
If I am creating options dynamically. How will I get the value to change the index. I saw select.val(2).change(); is using value of option tag.
If you are creating your options dynamically and want to bind to some option by default, you need to know to which you want to bind. If you want to get the current value of the selected one, you can use this.value or $(this).val() to get the appropriate one.
You can still use your approach with selectedIndex, only after it you need to call change() on the select. select[0].selectedIndex = 2; select.change();
|
2

You can use trigger function of jQuery.

function callFunc(obj) {
  console.log(obj.value);
}


setTimeout(function(e){ $("#select1").val(2).trigger('change'); }, 2000)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select1" onchange="callFunc(this);">
  <option value='0'>select ....</option>
  <option value='1'>1</option>
  <option value='2'>2</option>
  <option value='3'>3</option>
</select>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.