JQuery attribute handling inconsistency
$('<option selected="selected">something</option>')
.removeAttr('selected')
.wrap('<p></p>').parent().html();
leads to
<option>something</option>
which is expected. But if I return the "selected" attribute after removing it (or a tag <option>
without the "selected" attribute), I get the same result.
$('<option selected="selected">something</option>')
.removeAttr('selected')
.attr('selected', 'selected')
.wrap('<p></p>').parent().html();
Why is this happening?
source to share
There are two selected
s attributes , selected
and a property selected
.
The HTML attribute selected="selected"
sets the initial state of the JavaScript selected
boolean property , but after that, like the entire form field, they are independent.
If you select an option by clicking it in the select box, it won't add an HTML attribute selected="selected"
to the HTMLOptionElement DOM node, so you won't see what is reflected in the innerHTML
/ html()
element. Instead, it just sets the content of the base form as shown in the property option.selected
.
IE before version 8 doesn't even let you set the HTML attribute selected
because it's broken there setAttribute
. If you try it will actually set the selected
boolean property .
attr()
in jQuery is sort of a hybrid of attribute and property access that tries to cover these issues under the rug. But the result of the call is attr('selected')
actually the same as using the boolean property selected
.
source to share
First, it shouldn't be wrapped in a paragraph - that might explain some strange behavior you're seeing. Also, the "selected" attribute may not appear in the HTML markup, but it is set where it is counted, ie. DOM property "selected". <option>
var option = $('<option selected="selected">something</option>');
option.removeAttr('selected').attr('selected', 'selected');
option[0].selected === true;
source to share
seeing this parsing that can be seen in the DOM is that it is selected by the element, but no HTML text is displayed.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
<script language="JavaScript">
$(function(){
var opc0 = document.createElement("option");
var theText = document.createTextNode("something 0");
opc0.appendChild(theText)
opc0.setAttribute("selected", "selected");
opc0.removeAttribute("selected");
opc0.setAttribute("selected", "selected");
var opc1 = $("<option value=\"test\" label=\"tlabel\" selected=\"selected\">something 1</option>");
opc1.removeAttr("label");
opc1.removeAttr("selected");
opc1.attr("selected", "selected");
opc1.attr("label", "tlabel2");
var opc2 = $("<option label=\"tlabel\" selected=\"selected\">something 2</option>");
opc2.removeAttr("selected")
var opc3 = $("<select id=\"selectTest\"></select>");
var opc3a = $("<option value=\"a\" selected=\"selected\">something 3 a</option>");
var opc3b = $("<option value=\"b\">something 3 b</option>");
var opc3c = $("<option value=\"c\">something 3 c</option>");
var opc3d = $("<option value=\"d\">something 3 d</option>");
var opc3e = $("<option value=\"e\">something 3 e</option>");
var opc3f = $("<option value=\"f\">something 3 f</option>");
opc3.append(opc3a);
opc3.append(opc3b);
opc3.append(opc3c);
opc3.append(opc3d);
opc3.append(opc3e);
opc3.append(opc3f);
opc3a.removeAttr("selected");
opc3.val("a");
var html0 = opc0.outerHTML;
var html1 = opc1.parent().html();
var html2 = opc2.parent().html();
var html3 = opc3.parent().html();
$("#preTest0").text(html0); //ok
$("#preTest1").text(html1); //err
$("#preTest2").text(html2); //ok
$("#preTest3").text(html3); //err
$(document.body)
.append(opc1)
.append(opc3);
$("#selectTest option:eq(4)").attr("selected","selected");
$("#selectTest option:selected").each(function () { $("#preTest5").text( $("#preTest5").text() + $(this).text() + " is selected "); });
var html4 = opc3.html();
$("#preTest4").text(html4); //ok accion, err html view
});
</script>
</head>
<body>
<pre id="preTest0"></pre><br />
<pre id="preTest1"></pre><br />
<pre id="preTest2"></pre><br />
<pre id="preTest3"></pre><br />
<pre id="preTest4"></pre><br />
<pre id="preTest5"></pre><br />
</body>
</html>
source to share