Mathieu Turcotte
Mathieu Turcotte

Reputation: 354

jQuery .clone() of a <select>: change the selected option

When loading a list of records from my database to display them in a html grid, I need to put a few <select> in a couple columns.

In my javascript, I do an ajax call to receive my data in json format and push my results in an array. In my display function, I then loop on the array and construct my table's multiple <tr> to a string and then push that html string in the <tbody> of my table:

if (buildingList) {

    buildingList.forEach(function(element) {
        buildingListHTML += "<tr>";
            buildingListHTML += "<td>" + element.nID + "</td>";
            buildingListHTML += "<td>" + element.cTaskNumber + "</td>";
            buildingListHTML += "<td>" + element.nProductTypeID + "</td>";
            buildingListHTML += "<td>" + element.nQty + "</td>";
            buildingListHTML += "<td>" + element.dRequired + "</td>";
            buildingListHTML += "<td><input type='checkbox'" + ((element.bCompleted == 0) ? "" : "checked") + " disabled></td>";
        buildingListHTML += "</tr>";
    });
}
$("#workOrderBuildingListBody").html(buildingListHTML);

That part works well. But now, for my column nProductTypeID, I want to display a <select> with my list of product types, and automatically select the right one from the list, according to the ID I have.

Basically, what I've done so far is create a <select> in a hidden <div> in my php file:

<div id="WOSkuSelectTemplate" style="display: none;">
    <select class="WOSkuSelect">
        <?php Common::generateProdTypesOptions($db); ?>
    </select>
</div>

Then, instead of just doing "<td>" + element.nProductTypeID + "</td>", I'm trying to do something like this:

if(actionsList) { //if there are actions entries
    actionsList.forEach(function(element) {
        var WOSkuSelectTemplate = $("#WOSkuSelectTemplate").clone().html();
        $(WOSkuSelectTemplate).val(element.nProductTypeID);
        alert(WOSkuSelectTemplate);

        actionsListHTML += "<tr>";
            actionsListHTML += "<td>" + element.nID + "</td>";
            actionsListHTML += "<td>" + element.cTaskNumber + "</td>";
            actionsListHTML += "<td>" + WOSkuSelectTemplate + "</td>";
            actionsListHTML += "<td>" + element.nQty + "</td>";
            actionsListHTML += "<td>" + element.nActionTypeID + "</td>";
            actionsListHTML += "<td>" + element.cFrom + "</td>";
            actionsListHTML += "<td>" + element.cTo + "</td>";
            actionsListHTML += "<td>" + element.dRequired + "</td>";
            actionsListHTML += "<td><input type='checkbox'" + ((element.bCompleted == 0) ? "" : "checked") + " disabled></td>";
        actionsListHTML += "</tr>";

    });
}
$("#workOrderActionsListBody").html(actionsListHTML);

I've tried multiple ways of doing it it, but nothing works. If I clone the <select> itself, when I try to concatenate my strings, when I do "<td>" + WOSkuSelectTemplate + "<td>", it just displays something like [object: object]. if I do + WOSkuSelectTemplate.html() +, I get only the options without the select, which is why I am instead cloning a <div>and get the .html(), which gives me the <select> itself with the options.

But whatever I try, I cannot seem to make the $(WOSkuSelectTemplate).val(element.nProductTypeID); part to work... All my <select>are there with the options in them, but they don't select the proper row. The comboboxes themselves have the right values, I can even set them from the console. but I can't get my javascript to do it for me.

The only option I see if to get the string like I do, and do a replace of 'selected=""' for 'selected="' + element.nProductTypeID + '"' but I really don't find that clean...

Is there any other way to achieve this?

English is not my primary language, sorry if anything is unclear.

Thank you.

Upvotes: 0

Views: 1914

Answers (2)

nonzaprej
nonzaprej

Reputation: 1600

It's "dirty" but you can do this:

// [test code]
var actionsList = [{
    nProductTypeID: 2, 
    nID: 1, 
    cTaskNumber: 3, 
    nQty: 10,
    nActionTypeID: 75,
    cFrom: "John", 
    cTo: "Doe", 
    dRequired: "true", 
    bCompleted: 0
}];

// [/test code]

$(document).ready(function() {

// other code...
    var actionsListHTML = "";

    if(actionsList) { //if there are actions entries
        actionsList.forEach(function(element) {
            var clonedDivWithSelect = $("#WOSkuSelectTemplate").clone();
            clonedDivWithSelect.find("option[value=\"" + element.nProductTypeID + "\"]").attr("selected", "selected");
            
            actionsListHTML += "<tr>";
                actionsListHTML += "<td>" + element.nID + "</td>";
                actionsListHTML += "<td>" + element.cTaskNumber + "</td>";
                actionsListHTML += "<td>" + clonedDivWithSelect.html() + "</td>";
                actionsListHTML += "<td>" + element.nQty + "</td>";
                actionsListHTML += "<td>" + element.nActionTypeID + "</td>";
                actionsListHTML += "<td>" + element.cFrom + "</td>";
                actionsListHTML += "<td>" + element.cTo + "</td>";
                actionsListHTML += "<td>" + element.dRequired + "</td>";
                actionsListHTML += "<td><input type='checkbox'" + ((element.bCompleted == 0) ? "" : "checked") + " disabled></td>";
            actionsListHTML += "</tr>";
            
        });
    }
    $("#workOrderActionsListBody").html(actionsListHTML);
    
    // other code...
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="WOSkuSelectTemplate" style="display: none;">
    <select class="WOSkuSelect">
        <option value="0">Test option 0</option>
        <option value="1">Test option 1</option>
        <option value="2">Test option 2</option>
        <option value="3">Test option 3</option>
    </select>
</div>

<table style="width: 100%;">
  <tbody id="workOrderActionsListBody">
    
  </tbody>
</table>

P.S. Yeah Agam Banga beat me on time about the selection part.

Upvotes: 0

Agam Banga
Agam Banga

Reputation: 2693

You can use this

WOSkuSelectTemplate.find('select').find("option[value = '" + element.nProductTypeID + "']").attr("selected", "selected");

Upvotes: 1

Related Questions