Search code examples
javascripthtmlselectedindex

Javascript's "selectedIndex" appears to work, but actually doesn't give the same behavior as a real click


I have an HTML form with a Javascript custom dropdown function taken from W3Schools. It replaces the ugly default dropdown with a really neat one, and works in most cases. However, I ran into a problem.

The custom dropdown code uses the function "selectedIndex" in order to define which label should be selected when the user clicks. It seems to work, but I am also using the Sisyphus "save form data" plugin, and when I refresh the page, the user changes are lost.

I know it is not a problem with Sisyphus or my implementation, because if I unhide the default original dropdown, I click on it, and upon refresh the options are saved just fine.

This inquiry shows that the "selectedIndex" function doesn't give exactly the same result as if the user had physically clicked on the label. It appears to change the value but somehow doesn't really register it, spooky....

After reading similar issues on stackoverflow, I added the two following lines under the "selectIndex" function: trying to programmatically set it's "selected" state to "true", and also to trigger a click:

s.selectedIndex = i;
s.options[i].selected = true;
s.options[i].click();

Still no luck. Here is a wider view of the code:

// When an item is clicked, update the original select box, and the selected item
for (i = 0; i < sl; i++) {
    if (s.options[i].innerHTML == this.innerHTML) {
        
        //update the original select box
        s.selectedIndex = i;
        s.options[i].selected = true;
        s.options[i].click();
        
        //update the new select box
        h.innerHTML = this.innerHTML;
    }
}

Here is the HTML:

<div class="dropdown has-label">
<label for="jours_entiers_de_travail">Number of days</label>
<div class="select-wrapper">
  <select name="jours_entiers_de_travail" id="jours_entiers_de_travail">
  <option value="1">1 day</option>
  <option value="2">2 days</option>
  <option value="3">3 days</option>
  </select>
</div>
</div>

And a full version of the dropdown can be seen on this Codepen:

https://codepen.io/benviatte/pen/OJNYwRy

This codepen appears to work, but again, the issue comes when I try to use the value assigned by selectedIndex, for example with Sisyphus. The value doesn't seem to have been properly assigned.

Thank you dearly for your help


Solution

  • Sisyphus documentation hints that it uses change events to monitor updates of form elements. Source code appears to confirm this in JSDoc markup for the bindSaveDataOnChange function.

    Hence try triggering a change event on the select box instead of clicking the option element programmatically. Untested but possibly like

        //update the original select box
        s.selectedIndex = i;
        s.options[i].selected = true;
        // s.options[i].click();    // replace with:
        $(s).trigger("change");     // trigger change event on select box
    

    Also see Trigger change event <select> using jquery for a variety of ways of triggering change events in both jQuery and plain JavaScript, and trigger() | jQuery API Documentation.