locked
How do I populate a drop down list from code?

    Question

  • I have a <select> item in my html which is used as a settings flyout and I am trying to populate in code...

    Html looks like this:

    <select class="taskDetailProjects">
    </select>

    The code to populate it looks like this:

    data.projects.forEach(function (item) {
          $(".taskDetailProjects").append('<option value="' + item.rowid + '">' + item.name + '</option>');
    });

    This code simply crashes the application.  No errors or anything.  It just crashes...

    Why is this not working?  What is the best way to do this?  Can I simply bind the <select> element to a function?

    Thanks.


    www.emadibrahim.com

    Sunday, May 13, 2012 10:18 PM

Answers

  • This technique seems to work better.  Give it a try:

            var selector = document.querySelector(".taskDetailProjects");
            selector.innerHTML = ""; //Clear selector
            projects.forEach(function (item) {
                var option = document.createElement('option');
                option.innerText = item.name;
                option.setAttribute("value", item.rowid);
                selector.appendChild(option);
            });

    Monday, May 14, 2012 3:18 PM

All replies

  • I got something sort of working but it is behaving weird...

        var options = document.querySelector(".taskDetailProjects").options;
        data.projects.forEach(function (item) {
            if (item.rowid == data.selectedTask.projectId) {
                options.add(new Option(item.name, item.rowid, false, false));
            } else {
                options.add(new Option(item.name, item.rowid, false, false));
            }
        });

    The above code will popuplate the drop down but for some reason adds 2 copies of the first item, so I end up with:

    option 1

    option 1

    option 2

    option 3

    Any idea what is going on?


    www.emadibrahim.com

    Sunday, May 13, 2012 11:00 PM
  • For starters, it looks like you are adding the same thing to the selector options list no mater what the outcome of the if statement.
    Monday, May 14, 2012 1:28 AM
  • That was a typo and beside the point, the same issue exists even if I do that:

       var options = document.querySelector(".taskDetailProjects").options;
        data.projects.forEach(function (item) {
                options.add(new Option(item.name, item.rowid, false, false));
        });

    Questions:

    - Why is it adding one extra element?  I used DOM explorer and found that the html is valid and only has 3 elements but the dropdown in the UI has 4 elements - is this a bug in the rendering engine?

    - Is there a "right" or "better" way to bind a drop down to an array of objects?


    www.emadibrahim.com

    Monday, May 14, 2012 1:03 PM
  • You must have another typo somewhere.  Your example works correctly for me (with some simplification):

    <body>
        <p>Content goes here</p>
        <select id="mySelector" class="taskDetailProjects"></select>
    </body>


    (function () {
        "use strict";
    
        var projects = [{ rowid: 1, name: "First" }, { rowid: 2, name: "Second" }, { rowid: 1, name: "Third" }];
    
        WinJS.Utilities.ready(function () {
            var options = document.querySelector(".taskDetailProjects").options;
            projects.forEach(function (item) {
                options.add(new Option(item.name, item.rowid, false, false));
            });
        });
    })();


    The output in the Dom Explorer is:

    <body>...</body>
    <p>Content goes here</p>
    </p>
    <select class="taskDetailProjects" id="mySelector">...</select>
    <option value="1">First</option>
    </option>
    <option value="2">Second</option>
    </option>
    <option value="1">Third</option>
    </option>
    </select>
    </body>


    ---and the rendered page has only 3 elements in the selector.

    By the way, if you are going to repopulate the list, you should clear it before adding new items:

    var options = document.querySelector(".taskDetailProjects").options;
            options.length = 0;  //Clear list
            projects.forEach(function (item) {
                options.add(new Option(item.name, item.rowid, false, false));
            });

    ***Update, something is goofy with the rendering of the selector.  When I add another item (on a button click event handler), the item is duplicated--but not in the DOM explorer!





    • Edited by jrboddie Monday, May 14, 2012 2:20 PM
    Monday, May 14, 2012 1:40 PM
  • Just saw your update and it looks like you are having the same problem...  It sounds like a BUG...  anyone from Microsoft here to confirm that this is a bug?

    Or can you point me to where is the best place to report it?


    www.emadibrahim.com

    Monday, May 14, 2012 2:24 PM
  • This technique seems to work better.  Give it a try:

            var selector = document.querySelector(".taskDetailProjects");
            selector.innerHTML = ""; //Clear selector
            projects.forEach(function (item) {
                var option = document.createElement('option');
                option.innerText = item.name;
                option.setAttribute("value", item.rowid);
                selector.appendChild(option);
            });

    Monday, May 14, 2012 3:18 PM
  • I will give it a try but interestingly enough I restarted my computer and tried it again and the same exact code worked fine...  Code rendered = View rendered..  Weird!!!  

    www.emadibrahim.com

    Monday, May 14, 2012 3:21 PM
  • I've encountered the same bug. I've tried lots of different ways of adding the option to the select, and I get the behaviour described, but only intermittently. Well actually I get...

    add option 1, select shows 1, 1

    add option 2 select shows 1, 2, 2

    so the last option added is there twice.

    Unfortunately, when the bug triggers, clearing the options crashes the app.


    Update: tried jrboddie's answer and so far so good.
    • Edited by lazcool Wednesday, October 24, 2012 10:03 AM
    Wednesday, October 24, 2012 9:45 AM