Monday, April 25, 2011

Best way to create a dynamic Select (Dropdown) list?

I'm using jQuery and jqGrid.

I'm trying to populate a select list dynamically, one for each row and I need to add a click event to it. When the select list is being populated I grab the index of the item I want selected, and then after all items are add I'm trying to set the selected item.

I've tried

$("#taskList")[0].selectedIndex = taskIndex;
$("#taskList").selectOptions(taskIndex, true);
$("#taskList").val(1); //Tried to see if I could select any index and no luck.
$("#taskList option[value=" + taskIndex + "]").attr("selected", true);

So this means I'm probably populating the list incorrectly...

var taskList = document.createElement("select");
var taskIndex = 0;
for (var i = 0; i < result.TaskTypes.length; i++) {
   $(taskList).addOption(result.TaskTypes[i].TaskId, result.TaskTypes[i].TaskName);
   if (result.TaskTypes[i].TaskName == rowData.TaskType)
    taskIndex = i;
}

Is there a better way?

I tried this but I couldn't add the click event to it. The proper item was selected though.

var taskList = "<select name='taskList' Enabled='true'>";
for (var i = 0; i < result.TaskTypes.length; i++) {
    if (result.TaskTypes[i].TaskName == rowData.TaskType)
        taskList += "<option selected> " + result.TaskTypes[i].TaskName + "</option>";
    else
    taskList += "<option>" + result.TaskTypes[i].TaskName + "</option>";
}
taskList += "</select>";
From stackoverflow
  • Falling under the "better way" category, JQuery lets you use an each loop instead of creating the for loops manually.

    jQuery.each(result.TaskTypes, function(i, val) {
          $("#" + i).append(document.createTextNode(" - " + val));
        });
    
    Brad8118 : Tried this too. No luck. Quick question about the "$("#" + i)." How does it know what element to append to. I would need to do something like this.. $("#taskList " + i) ??? thanks
  • The way I would have done it, is in your first example - instead of using the jQuery API for addOption, use the DOM API, like this:

    var option = document.createElement("option");
    option.innerHTML = result.TaskTypes[i].TaskName;
    option.value = result.TaskTypes[i].TaskId;
    option.onclick = myClickHandler;
    taskList.add(option, null);
    

    Then after the loop you can just use:

    taskList.selectedIndex = taskIndex;
    

    to have the select list positioned to your required default selection.

    I haven't used jQuery extensively, but I think its a good idea not to neglect the DOM API - its often not as convenient as the shortcuts that jQuery and other libraries offer, but these extend DOM capabilities and should not come instead of the DOM.

    Brad8118 : Not working... taskList.add(option); threw an exception. "htmlfile: Invalid argument." Changed to $(taskList).add(option); Its not adding items to taskList after I changed it. Checked and innerHTML and Value are being set. Ideas??
    Guss : I get a failure with add() as well, not sure why - its a documented API. Anyway, the DOM method appendChild() works great for me.
    Guss : eh. You probably want to use taskList.add(option,null) to add an option to the bottom of the list. Calling it with a single parameter doesn't work indeed (I was under the assumption that the last parameter is optional and defaults to null).
    Brad8118 : Good news bad news.... Good- appendChild() works. Bad - Still can't set what item I want selected. --> awesome :(
    Guss : I've just edited my answer, and I think you'll find all the details you need in there :-)
    Brad8118 : Tired taskList.add(option, null); and I still get the "htmlfile: Type mismatch." error I tried $(taskList).add(option, null); and its not populating taskList. Am I having an issue with var taskList = document.createElement("select");
    Guss : Are you using IE? what error do you get with the createElement() call ?
    Brad8118 : IE6. I get the error thrown in Studio. (sorry its not thrown in IE) I might need to add $(taskList).attr({id:"taskList"}); ?? I gotta restart my machine, be back in a few.
    Brad8118 : didn't work adding $(taskList).attr({id:"taskList"});
    Guss : Hmm.. sorry, can't help you there: IE6 is not my turf. I'm not trying to be an elitist or something, but I'm haven't supported it for a long time now. For example, my company does web widgets for tier 1 web sites, and we only support IE7 (and 8 when it will come out).
    Brad8118 : Its cool. thanks for your help.
    Brad8118 : Got it thanks again.
    Guss : You welcome :-) good luck!
  • You can set the selected index like this:

    $("#taskList").selectedIndex = taskIndex;
    
    Brad8118 : Tried this and it didn't work.
    Greg : Ah, you don't have id="taskList" on your select - that's why it's not working
    thenduks : Indeed, this should probably solve the issue if you just add `id="taskList"` to the select element.
    Brad8118 : Tried var taskList = document.createElement("select"); $(taskList).attr({ id: "taskList" }); no luck
    thenduks : Put the id in your markup. If you must do it via JavaScript then you're looking for one of: $('