8
<select>
    <option>1</option>
    <option>2</option>
    <option class="test">3</option>
</select>

$('.test').attr('selected', 'selected');​

The select box above would choose the third option as default without any issues. However, if you check the elements with Firebug there isn't any selected="selected" attribute present within the chosen <option>.

I know this isn't a big issue as it still works but I need selected="selected" there so my other scripts could catch it and perform further processing. Are there any workarounds out there?

Thanks.

user435216
  • 305
  • 2
  • 5
  • 16

3 Answers3

23

The selected attribute does not correspond to the current selectedness state of the option. The selected attribute corresponds to the default selectedness, which will be restored if .reset() is called (or a type="reset" button is clicked) on the form. The current selectedness state can be accessed using the DOM property selected, whereas the default-selectedness, as reflected by the attribute, is accessed under the DOM property defaultSelected.

The same goes for value vs defaultValue on <input type="text">/<textarea>, and checked/defaultChecked on type="checkbox"/"radio".

jQuery's attr() is misleadingly named, and its attempts to pretend attributes and properties are the same thing is flawed. When you use attr(), you are usually accessing the property, not the attribute. Consequently, $(el).attr('selected', 'selected') is actually doing el.selected= 'selected'. This works because 'selected', as with any non-empty string, is ‘truthy’: it gets converted to el.selected= true. But this does not at any point touch the selected="selected" attribute.

IE further complicates this already confusing situation by (a) getting getAttribute/setAttribute wrong so it accesses the properties instead of the attributes (which is why you should never use these methods in an HTML document), and (b) incorrectly mapping the current form state to the HTML attributes, so the attributes do actually appear in that browser.

but I need selected="selected" there

Why? Are you serialising the form to innerHTML? This won't include form field values (again, except in IE due to the bug), so is not a usable way to store field values.

bobince
  • 528,062
  • 107
  • 651
  • 834
  • Thanks. The other script _uses_ the current selected option(from DOM), or the default option if nothing has been selected yet for further processing. After reading your response, In order to let that script choose currently selected option, I guess the correct method would be setting the DOM property `selected` instead of using `selected="selected"`? – user435216 Sep 16 '10 at 19:29
  • Yes. Though there are also limited conditions where some browsers will *also* set the current value when you set the default value. aaaargh! – bobince Sep 16 '10 at 19:44
  • Alright, actually I haven't messed with DOM properties before. For the sample above, I should use `$('.test').val(true);` to set the third option's `selected` DOM property to true? Is that correct? Thanks. – user435216 Sep 16 '10 at 21:00
  • No, `val` accesses the value of the option, not its selectedness. In this specifc case, the `value=` attribute and the `value` DOM property *are* the same! (aargh!) You'd set the selectedness with the DOM property `selected`, so `$('.test').attr('selected', true)` (contrary to the name this is not setting an attribute!) or `$('.test')[0].selected= true`. Or, what's often more practical than futzing with ` – bobince Sep 16 '10 at 22:58
3

This works as expected, Check it out : http://jsfiddle.net/MZYN7/1/

letronje
  • 9,002
  • 9
  • 45
  • 53
1

It should be $('.test').attr('selected', true);​

also

<option selected>value</option>

It will not show up as selected="selected"

Jakub
  • 20,418
  • 8
  • 65
  • 92
  • I don't think the value of 'selected' attribute matters(It need not be true, it could be any value). Just the fact that it is present is enough to select it. – letronje Sep 16 '10 at 18:52
  • @letronje: true, however I just followed the standard jQuery format `.attr( attributeName, value )` – Jakub Sep 16 '10 at 18:55
  • My point is that $('.test').attr('selected', 'selected'); also works ~> http://jsfiddle.net/MZYN7/1/ – letronje Sep 16 '10 at 18:56
  • `$('.test').attr('selected', 'selected')` only works because when you assign a non-empty string like `'selected'` to a boolean property, it behaves like `true`. – bobince Sep 16 '10 at 19:03
  • @bobince thnx, didn't know that. – letronje Sep 16 '10 at 19:24