62

I have the following markup:

<select onchange="jsFunction()">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
</select>

When a user pulls down the combobox and selects the same option that was previously selected (or doesn't change the selection at all), JavaScript doesn't regard it as an onchange event. So, the jsFunction() is not called. But I want the jsFunction() called even in this case. How can I achieve this?

Dilip Raj Baral
  • 3,060
  • 6
  • 34
  • 62
  • 3
    Normally when I want this behaviour I add an extra entry with no value which is the default... and in the event handler check if it was selected, and if so, do nothing. – Geoffrey Aug 09 '12 at 06:01
  • @Geoffrey I did think that too. That again brings up another problem. How do I dynamically (using JavaScript) select the desired option (entry with no value in this case)? – Dilip Raj Baral Aug 09 '12 at 06:05

8 Answers8

78

I'd do it like this:

<select onchange="jsFunction()">
  <option value="" disabled selected style="display:none;">Label</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
</select>

If you want you could have the same label as the first option, which in this case is 1. Even better: put a label in there for the choices in the box.

NickSuperb
  • 1,174
  • 1
  • 8
  • 28
simme
  • 1,514
  • 12
  • 23
24

You have to add empty option to solve it,

I also can give you one more solution but its up to you that is fine for you or not Because User select default option after selecting other options than jsFunction will be called twice.

<select onChange="jsFunction()" id="selectOpt">
    <option value="1" onclick="jsFunction()">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
</select>

function jsFunction(){
  var myselect = document.getElementById("selectOpt");
  alert(myselect.options[myselect.selectedIndex].value);
}
gaurang171
  • 9,032
  • 4
  • 28
  • 30
5

Just set the selectIndex of the associated <select> tag to -1 as the last step of your processing event.

mySelect = document.getElementById("idlist");
mySelect.selectedIndex = -1; 

It works every time, removing the highlight and allowing you to select the same (or different) element again .

Pooya
  • 6,083
  • 3
  • 23
  • 43
user6132740
  • 51
  • 1
  • 1
2

Try this. Just add an empty option. This will solve your problem.

<select onchange="jsFunction()">
    <option></option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
</select>​
Nathan Arthur
  • 8,287
  • 7
  • 55
  • 80
Praveen Singh
  • 534
  • 2
  • 8
  • 23
2

For this problem, I have finally put a new <i> tag to refresh the select instead. Don't try to trigger an event if the selected option is the same that the one already selected.

enter image description here

If user click on the "refresh" button, I trigger the onchange event of my select with :

const refreshEquipeEl = document.getElementById("refreshEquipe1");

function onClickRefreshEquipe(event){
    let event2 = new Event('change');
    equipesSelectEl.dispatchEvent(event2);
}
refreshEquipeEl.onclick = onClickRefreshEquipe;

This way, I don't need to try select the same option in my select.

La Page PT
  • 571
  • 1
  • 6
  • 20
1

use the "onmouseup" property with each option element. it's verbose, but should work. also, depending on what your function is actually doing, you could arrange things a little differently, assuming the number is important in the handler:

<select>
<option onmouseup="handler()" value="1">1</option>  //get selected element in handler
<option onmouseup="handler(2)" value="2">2</option>  //explicitly send the value as argument
<option onmouseup="handler(this.value)" value="3">3</option> //same as above, but using the element's value property and allowing for dynamic option value. you could also send "this.innerHTML" or "this.textContent" to the handler, making option value unnecessary
</select>
eamyx
  • 19
  • 1
  • I find this solution undesirable because it adds a lot of bloat to the page. For example, on a page where there are 50 rows of a table, and each one has a dropdown control in it and there are 10 options in the select, for your generalized solution with 31 characters this involves inserting 15500 characters. This is already getting into the zone of adding a substantial amount of bulk to a page. – cazort Apr 02 '19 at 19:02
  • 1
    I also tested this and this solution completely fails to work in the case of using the keyboard to navigate or select the element. Nothing is fired at all, as would be expected. – cazort Apr 02 '19 at 19:26
1

JavaScript code:

  • on mousedown event: set selectedIndex property value to -1
  • on change event: handle event

The only drawback is that when the user clicks on the dropdown list, the currently selected item does not appear selected

figolu
  • 1,388
  • 13
  • 6
0

It's not firing because the value hasn't "changed". It's the same value. Unfortunately, you can't achieve the desired behaviour using the change event.

You can handle the blur event and do whatever processing you need when the user leaves the select box. That way you can run the code you need even if the user selects the same value.

Strelok
  • 50,229
  • 9
  • 102
  • 115
  • Actually the situation is like this. I have a combox box. When any option is selected, I hide the combox and show the value of the combobox as a LABEL with the CHANGE option. When CHANGE is clicked, again I show that combobox. – Dilip Raj Baral Aug 09 '12 at 06:13
  • @RajBD, yeah you won't be able to do that without handling `blur` and making them leave the select to update. It's a minor usability issue though. I think it would be better if you give them an explicit option to "cancel", by placing a "Cancel" link next to the select box when you're showing it. – Strelok Aug 09 '12 at 06:27
  • 1
    This does not work. The blur event does not fire until the event loses focus. If you just click on the already selected option, it does not fire. – cazort Apr 02 '19 at 19:12