intrepidus
intrepidus

Reputation: 974

Selected value on a cloned item not working as expected

Fiddle is here, containing this code: http://jsfiddle.net/enp2T/6/

<select id="aList">
    <option value="0">0</option>
    <option value="100">100</option>
    <option value="200">200</option>
    <option value="300">300</option>
</select>

<div id="newListContainer"></div>

$(function() {
    var value = 300;
    var clonedList = $('#aList').clone();    

    var listHtml = clonedList
        .removeAttr('id')
        .val(value)
        .wrap('<div/>')
        .parent()
        .html();

    $('#newListContainer').html(listHtml);       

    //$('#newListContainer>select').val(value);
});

I thought that my selected value of 300 would be maintained, but listHtml just contains a clone of the original list. I'm in a situation where it would be painful to try to re-find the object and set its value after it gets drawn (passing it to another external libraries function defers rendering till later, no complete callback unless I modify that library directly which I'm trying to avoid).

So am I doing something horribly wrong? Missing a quirk?

Clarification: I need to pass the HTML as a string, as the library that is using it is expecting a string.

Upvotes: 0

Views: 665

Answers (3)

ostapische
ostapische

Reputation: 1592

See this link. You can't set value to the select, you must set selected attribute to item with value=300.

$(function() {
    var value = 300;
    var clonedList = $('#aList').clone();    
    clonedList.find('option[value="' + value + '"]').attr("selected", true);
    var listHtml = clonedList
        .removeAttr('id')
        //.val(value)
        .wrap('<div/>')
        .parent()
        .html();
    $('#newListContainer').html(listHtml);       

    //$('#newListContainer>select').val(value);
});  

I have a mistake. @T.J. Crowder is right. jQuery can set value of select by .val(value) function. link

$(function() {
    var value = 300;
    var clonedList = $('#aList').clone();
    var holderCloned = clonedList.removeAttr('id').val(value).wrap('<div/>').parent();
    $('#newListContainer').empty().append(holderCloned);
});

Upvotes: 0

Zathrus Writer
Zathrus Writer

Reputation: 4331

jQuery clones the list with whatever you have selected - the problem here is that you don't have anything selected, so you're cloning a dropdown without a selected value (see here).

For an updated version of that script, check this updated jsFiddle.

Code:

$(function() {
    var value = 300;
    var clonedList = $('#aList').clone();
    clonedList.find('option[value="' + value + '"]').attr('selected', 'selected');

    var listHtml = clonedList
        .removeAttr('id')
        .val(value)
        .wrap('<div/>')
        .parent()
        .html();

    $('#newListContainer').html(listHtml);       

    //$('#newListContainer>select').val(value);
});

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074138

There's no reason to make a round-trip to markup for this, and I suspect that's the problem, as jQuery's val sets the selectedIndex of the select element, which doesn't get serialized.

Just use the cloned element:

var wrappedList = clonedList
    .removeAttr('id')
    .val(value)
    .wrap('<div/>')
    .parent();
// Note: Not doing `.html()` at the end

// html(...) would empty the container and then add the HTML, so
// we empty the container and then append the wrapped, cloned list
$('#newListContainer').empty().append(wrappedList);

Updated working fiddle

Upvotes: 3

Related Questions