0

I have some custom select-behaviour in my project, which adds some general functionality to select-boxes. I have implemented that they can be marked as optional, which allows the user to select the default value, which is empty.

Nowhere in the custom javascript code it ever manipulates the select's "value" property directly - it just manipulates the options, adding or removing the selected attribute/property. This works fine for all real options that have actual values - they get submitted with the value of their value-attribute.

However, when I select the default-option, which's value is empty (value=""), then the browser always sends the value of the 1st option upon form submit. I don't understand why. I can even confirm this with JavaScript.

<select id="stockWay" data-select-name="selectBox" data-optional="" name="stockWay" data-placeholder=“please choose ..." class="hide">
        <option value=“FOO”>FOO</option>
        <option value=“BAR”>BAR</option>
        <option value="" selected="selected">please choose ...</option
</select>

This is the HTML of my select how it's on the site, that's copy pasted. When I call this JavaScript:

document.getElementById("stockWay").value

it returns "FOO". That doesn't make any sense to me, the empty-value option is clearly selected. And even if the empty value counts as "missing", it should use it's text-content according to the docs. I really don't get what is going on here. I thought the value-property on the select-element is a reflection of what option-children has the selected-attribute?? Clearly there is more going on, but I don't know what or where and how.

Does anyone have any hints where else I could be looking in order to find out how this happens? Any pointers would be greatly appreciated.

Edit: I have just further debugged this in chrome and I could see the following behaviour: The code calls

selectedOption.setAttribute("selected", "selected");

whenever an option gets selected. For all options with real values, this causes the property "selected" to become true. Only for the empty-value option, this does for some reason not make it become true. It simply remains false. It's literally one line of code. In both cases I can see that selectedOption is the expected element in the page. I don't get it.

Mercious
  • 378
  • 3
  • 25
  • Instead of using `setAttribute()`, write `selectedOption.selected = true;` (or `false`). The property on the DOM element node is boolean, not a string; the string convention is for HTML code, but the HTML has already been parsed. – Pointy Jul 15 '19 at 14:24
  • Okay, I will try to refactor every place that sets the selected option to instead manipulate the property instead of the attribute. I guess that means I will have to adjust the query-statement too, using the ":checked" selector, as updating the property does not seem to add the attribute in the html code. But I am still baffled how setting the attribute seems to work for one option but not the other. It makes no sense. – Mercious Jul 15 '19 at 14:30
  • https://jsfiddle.net/gdt0ejvb/ - I'm not sure why you need to select `:checked` but as you can see everything here works as expected. You'll have to share some more code with us (other than `.setAttribute("selected", "selected")` which is wrong as described by @Pointy – Sergiu Paraschiv Jul 15 '19 at 14:33
  • You don't need the attribute to be reflected in the HTML. – Pointy Jul 15 '19 at 14:33
  • The way the "selected" attribute works is that if it's pressent on the element *at all* with any string value, the state of the `.selected` property is considered `true`. Thus you can use `.removeAttribute()` to get rid of "selected" entirely, or more simply just directly manipulate the property on the node, since that's what really matters anyway when the `
    ` is submitted.
    – Pointy Jul 15 '19 at 14:36
  • For what it's worth, when I test `.setAttribute("selected", "selected")` on an ` – Pointy Jul 15 '19 at 14:44
  • @SergiuParaschiv :checked because the existing code works under the premise that a selected option has the "selected" attribute. I need to adjust that and since much of the existing logic used querySelectorAll() to get all selected-options, the appropriate replacement would be to use the ("option:checked") selector, right? Just so I can get some closure on this: Setting the selected option of a select-element with java-script by setting the attribute "selected" is just plain wrong and whether or not it works is undefined behaviour? – Mercious Jul 15 '19 at 15:06
  • https://stackoverflow.com/questions/10911526/how-do-i-change-an-html-selected-option-using-javascript/10911660 – Sergiu Paraschiv Jul 15 '19 at 16:16
  • @SergiuParaschiv That mentions yet another method of achieving the setting of an options "selected" property. By setting the value of the owning select. I really don't want to be annoying, but I just want to understand whether or not setting the select option by settings its "selected" attribute to any value can be considered wrong. I can't find any committed answer to this anywhere. All over stackoverflow there are threads and answers that set it by attribute, by property, by selectedIndex of the select, by value of the select, ... . That's very confusing – Mercious Jul 15 '19 at 16:25
  • Sorry for not explaining myself. The idea of that link was to point something else: there is no "universal" way. There are at least three different ones, each with it's own browser compatibility "table" and history. A simple answer to your question would be: it is not wrong, it's _different_ and needs to be understood _in context_. The context here being: the `selected="selected"` way is old, probably has a convoluted history and does not work "as expected" these days. Also read this https://stackoverflow.com/questions/1033944/what-values-can-appear-in-the-selected-attribute-of-the-option-tag – Sergiu Paraschiv Jul 15 '19 at 17:06
  • @SergiuParaschiv All good, no worries. Your last comment gives me closure, that's exactly what I wanted to know about this topic. If you or Pointy committed an answer that explains what you last explained I would gladly accept it. Thanks! – Mercious Jul 15 '19 at 17:26

0 Answers0