views:

584

answers:

3
$('<option selected="selected">something</option>')
.removeAttr('selected')
.wrap('<p></p>').parent().html();

results in

<option>something</option>

which is expected. But if I put back the 'selected' attribute after removing it (or to an <option> tag without 'selected' attribute), I get the same output.

$('<option selected="selected">something</option>')
.removeAttr('selected')
.attr('selected', 'selected')
.wrap('<p></p>').parent().html();

Why is this happening?

+1  A: 

First, an <option> shouldn't be wrapped in a paragraph - this could account for some weird behavior you're seeing. Also, the "selected" attribute might not be expressed in the HTML markup but it is being set where it counts - i.e. the DOM "selected" property.

var option = $('<option selected="selected">something</option>');
option.removeAttr('selected').attr('selected', 'selected');

option[0].selected === true;
J-P
May I ask why an <option> shouldn't be wrapped in a paragraph?
Wadih M.
I wrapped the `<option>` tag in `<p>` just to test serialization behavior.
Imran
+1  A: 

There are two selecteds, the selected attribute and the selected property.

The HTML selected="selected" attribute sets the initial state of the JavaScript selected boolean property, but after that, like all form field state, they are independent.

If you select the option by clicking on it in the select box, it doesn't add an HTML selected="selected" attribute to the HTMLOptionElement DOM node, so you won't see that reflected in the innerHTML/html() of the element. Instead it just sets the underlying form contents as reflected by the option.selected property.

IE before version 8 doesn't even allow you to set the HTML selected attribute, because setAttribute is broken there. If you try, it'll actually set the selected boolean property.

attr() in jQuery is a kind of hybrid of attribute and property access which tries to sweep these problems under the rug. But the upshot is calling attr('selected') is effectively the same as using the boolean selected property.

bobince
A: 

seeing this analysis, which can be seen in the DOM is that it is selected the item, but the text of HTML can not be seen.

<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>
andres descalzo