Search code examples
jqueryattributeshtml-selectselected

Removing "selected" atttribute from cloned select options not working in IE


I have written a plugin that converts a <select multiple> into multiple, mutually exclusive, single <select>s.

The initial HTML rendered has multiple <option selected> which were set server-side:

<select id="template" style="display: none;" multiple="">
    <option value="1">One</option>
    <option value="2" selected="">Two</option>
    <option value="3">Three</option>
    <option value="4" selected="">Four</option>
    <option value="5">Five</option>
    <option value="6" selected="">Six</option>
    <option value="7">Seven</option>
</select>

When I clone the <option>s to a series of new lists (one per selected option), I noticed that removeAttr("selected") was not removing the selected attribute in IE only:

e.g. this code:

$('#template').children().clone().removeAttr('selected').appendTo($select);

results in this in the DOM on IE:

<li class="listClass">
    <select class="selectClass">
        <option value="1">One</option>
        <option value="2" selected="">Two</option>
        <option value="3">Three</option>
        <option value="4" selected="">Four</option>
        <option value="5">Five</option>
        <option value="6" selected="">Six</option>
        <option value="7">Seven</option>
    </select>
</li>

but shows it correctly in Chrome:

<li class="listClass">
    <select class="selectClass">
        <option value="1">One</option>
        <option value="2">Two</option>
        <option value="3">Three</option>
        <option value="4">Four</option>
        <option value="5">Five</option>
        <option value="6">Six</option>
        <option value="7">Seven</option>
    </select>
</li>

Here is a mockup: http://jsfiddle.net/TrueBlueAussie/t9p2bgt0/1/ Try it with Chrome and IE to see the difference in their respective DOM inspectors.

I realise this will not affect the operation of the new lists, but I would prefer to cleanup the <option>s html when they are cloned, so need to know if there is a workaround.

Notes:

  • Using prop('selected', false) instead, only changes the internal state and the attributes are left there (in IE and in Chrome).
  • Using removeProp('selected') has no effect on the DOM.

Solution

  • Use defaultSelected instead of selected, and use prop to set it to null instead of using removeAttr.

    Example 1:

    This attempts to clear selected, and the alert still shows the selected options:

    $('#template').children().prop('selected', null);
    alert($('#template').html());
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <select id="template" style="display: none;" multiple="">
        <option value="1">One</option>
        <option value="2" selected="">Two</option>
        <option value="3">Three</option>
        <option value="4" selected="">Four</option>
        <option value="5">Five</option>
        <option value="6" selected="">Six</option>
        <option value="7">Seven</option>
    </select>

    Example 2:

    This clears defaultSelected, which successfully clears the selected options:

    $('#template').children().prop('defaultSelected', null);
    alert($('#template').html());
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <select id="template" style="display: none;" multiple="">
        <option value="1">One</option>
        <option value="2" selected="">Two</option>
        <option value="3">Three</option>
        <option value="4" selected="">Four</option>
        <option value="5">Five</option>
        <option value="6" selected="">Six</option>
        <option value="7">Seven</option>
    </select>