locked
Binding a List to a select element RRS feed

  • Question

  • Is there an easy way to bind the items in a WinJS.Binding.List to the options in a select element?  I have been searching but have not found any good solution.  For now, I am manually adding / removing the options to the select element, but I like to see a better approach.
    Wednesday, June 6, 2012 5:49 PM

Answers

  • You can wire up to the change events on the list:

    function loaded() {
        var select = document.getElementById("mySelect");
    
        var data = [
            { name: "first", value: 1 },
            { name: "second", value: 2 },
            { name: "third", value: 3 },
            { name: "forth", value: 4 },
            { name: "fifth", value: 5 }
        ];
    
        var list = new WinJS.Binding.List(data);
    
        var handler = function _handler(eventInfo) {
            bindSelect(select, list, 3);
        };
    
        list.onitemchanged =
            list.oniteminserted =
            list.onitemmoved =
            list.onitemmutated =
            list.onitemremoved =
            list.onreload = handler;
    
        // First time bind.
        bindSelect(select, list, 3);
    
        setTimeout(function () {
            list.push({ name: "sixth", value: 6 });
        }, 3000);
    
        setTimeout(function () {
            list.splice(1, 1);
        }, 6000);
    }
    
    function bindSelect(selectElement, list, selectedValue) {
        selectElement.innerHTML = window.toStaticHTML("");
        list.forEach(function _each(item) {
            var option = document.createElement("option");
            option.textContent = item.name;
            option.value.textContent = item.value;
            option.selected = item.value === selectedValue;
            selectElement.appendChild(option);
        });
    }
    Note: if you use that list for any other data binding you'll need to make sure you call "addEventListener" instead of setting the onchange properties. 

    Wednesday, June 6, 2012 8:40 PM

All replies

  • No that I know of, probably because it's pretty darn easy to do. For example:

    function loaded() {
        var select = document.getElementById("mySelect");
    
        var data = [
            { name: "first", value: 1 },
            { name: "second", value: 2 },
            { name: "third", value: 3 },
            { name: "forth", value: 4 },
            { name: "fifth", value: 5 }
        ];
    
        var list = new WinJS.Binding.List(data);
    
        bindSelect(select, list, 3);
    }
    
    function bindSelect(selectElement, list, selectedValue) {
        list.forEach(function _each(item) {
            var option = document.createElement("option");
            option.textContent = item.name;
            option.value.textContent = item.value;
            option.selected = item.value === selectedValue;
            selectElement.appendChild(option);
        });
    }

    • Proposed as answer by Bryan Thomas Wednesday, June 6, 2012 7:52 PM
    Wednesday, June 6, 2012 7:52 PM
  • Yes, this is essentially what I ended up doing.  However, this implementation is a one-way binding.  I was looking for a more dynamic binding where I can add to the list from somewhere else in the code and have the items in the select automatically updated.
    Wednesday, June 6, 2012 8:18 PM
  • You can wire up to the change events on the list:

    function loaded() {
        var select = document.getElementById("mySelect");
    
        var data = [
            { name: "first", value: 1 },
            { name: "second", value: 2 },
            { name: "third", value: 3 },
            { name: "forth", value: 4 },
            { name: "fifth", value: 5 }
        ];
    
        var list = new WinJS.Binding.List(data);
    
        var handler = function _handler(eventInfo) {
            bindSelect(select, list, 3);
        };
    
        list.onitemchanged =
            list.oniteminserted =
            list.onitemmoved =
            list.onitemmutated =
            list.onitemremoved =
            list.onreload = handler;
    
        // First time bind.
        bindSelect(select, list, 3);
    
        setTimeout(function () {
            list.push({ name: "sixth", value: 6 });
        }, 3000);
    
        setTimeout(function () {
            list.splice(1, 1);
        }, 6000);
    }
    
    function bindSelect(selectElement, list, selectedValue) {
        selectElement.innerHTML = window.toStaticHTML("");
        list.forEach(function _each(item) {
            var option = document.createElement("option");
            option.textContent = item.name;
            option.value.textContent = item.value;
            option.selected = item.value === selectedValue;
            selectElement.appendChild(option);
        });
    }
    Note: if you use that list for any other data binding you'll need to make sure you call "addEventListener" instead of setting the onchange properties. 

    Wednesday, June 6, 2012 8:40 PM
  • Thanks Bryan.  I may do a blog post on this topic to try to help spread the word on how to do implement this.  I think it's something that is missing from the framework, especially considering how easy it is to bind a ListView.  I would expect a dropdown to be at least as simple.

    I guess another option would be to use a framework like knockoutjs.

    Wednesday, June 6, 2012 10:41 PM