locked
select tag is not working inside the template

    Question

  • <div id="Template" data-win-control="WinJS.Binding.Template" style="display: none">
                    <div >
                        <div>Users</div>
                        <select id="selectID">
                            <option>Show All</option>
                            <option>User1</option>
                            <option>User2</option>
                            <option>User3</option>
                            <option>User4</option>
                        </select>
                    </div>
                </div>
    
    --------------------------------------------------
    
     document.getElementById("selectID").addEventListener("change", changeUser, false);

    I have a group collection. in the group header I have applied a template where there is a select control. on change I want the changeUser function need to be invoked. but the function ins not getting invoked.

    Chetan



    Thursday, July 19, 2012 3:49 AM

Answers

  • Things seem to be getting very confusing.  Let's restart.  I modified a Grid based template to show this.  Specifically the groupedItems page

    If you want to add an onChange handler you can do it as follows:

    1.  Define your onChange event handler in your JS file:

      function onSelectChange(event) {
            // do change stuff in here, the event will give you the control that the change is occuring for as well
            var str = "changed!";
        }

    2.  and Expose your onChange event handler through WinJS.Namespace.define:

        function onSelectChange(event) {
            // do change stuff in here, the event will give you the control that the change is occuring for as well
            var str = "changed!";
        }
        WinJS.Namespace.define("groupedItemsPage", { onSelectChange: onSelectChange }
    );
    })();

    3.  Wire your onChange event handler in your template:

     <!-- These templates are used to display each item in the ListView declared below. -->
        <div class="headerTemplate" data-win-control="WinJS.Binding.Template">
            <p class="group-title win-type-x-large" data-win-bind="textContent: title; groupKey: key" 
                onclick="WinJS.Navigation.navigate('/pages/groupDetail/groupDetail.html', { groupKey: event.srcElement.groupKey })" role="link"></p>
            <select onchange="groupedItemsPage.onSelectChange(event)">
                            <option>Show All</option>
                            <option>User1</option>
                            <option>User2</option>
                            <option>User3</option>
                            <option>User4</option>
                        </select>
        </div>
    -Jeff

    Jeff Sanders (MSFT)

    Tuesday, July 31, 2012 2:13 PM
    Moderator
  • the issue resolved when I copied the function outside the function block present inside the .js file and made that function as global.

    Chetan

    Friday, August 03, 2012 2:26 PM

All replies

  • please help in resolving the issue. Its urgent.

    Chetan

    Thursday, July 19, 2012 3:21 PM
  • You can bring up the DOM explorer while running your application and verify the ID of the element you are concerned of.  Then you can debug and see if document.getElementById("selectID") succeeds or not.

    Jeff Sanders (MSFT)

    Thursday, July 19, 2012 8:27 PM
    Moderator
  • if I take out the select control from the template then the change event is triggered but it is not the case when it is present inside.

    var d = document.getElementById("selectID").selectedIndex;

    the above statements returns 0.

    but when I try to set the selectedIndex explicitly then its not working.


    Chetan

    Friday, July 20, 2012 4:22 AM
  • Hi Chetan,

    You missed the first step (or you just forgot to answer). ...bring up the DOM explorer while running your application and verify the ID of the element you are concerned of


    Jeff Sanders (MSFT)

    Friday, July 20, 2012 11:44 AM
    Moderator
  • Hi

    You need to catch the change event.

    function changeUser(evt) {
            var selected = evt.target.selectedIndex;
    
        }

    MSDN provide a example:

    please refer to :

    How to use templates to bind data (Metro style apps using JavaScript and HTML)

    Friday, July 20, 2012 1:48 PM
  • Thanks Dino.. i had already referred to the above shared article. but it did not help. even i provide evt as an argument inside the function definition.

    my function definition goes like this

    function changeUSer()

    {

    lines of codes

    }

    this function is invoked when i keep the select tag outside the template. but function is not triggered when it is part of the template. i hope i m clear with the issue.


    Chetan

    Saturday, July 21, 2012 6:53 PM
  • i did not understand. which first step ur talking about. i just shared the required code.


    Chetan

    Saturday, July 21, 2012 6:55 PM
  • HI

    WinJS.Binding.Template is a winControl.

    This winControl is created by the WinJS.UI.processAll method, and
    it returns the Metro-specific properties created for different types of user interface controls.

    That's why you can't use getElementById.(Because there will be many same select control with same ID in each table row)

    You can use WinJS.Utilities.children to get each row and listen to the change event. I add your Code to the shared article codes, hope you can understand.

    Default.HTML
    <body>
        <p> The selectIndex ID:</p>
        <span id="selectIndex"></span>
        <div id="templateControlRenderTarget"></div>
       
        <div id="templateDiv" data-win-control="WinJS.Binding.Template">
        <div class="templateItem" data-win-bind="style.background: color">
            <ol>
                <li><span>Name :</span><span data-win-bind="textContent: name"></span></li>
                <li><span>Birthday:</span><span data-win-bind="textContent: birthday"></span></li>
                <li><span>Pet's name: </span><span data-win-bind="textContent: petname"></span></li>
                <li><span>Dessert: </span><span data-win-bind="textContent: dessert"></span></li>
            </ol>
        </div>
            <select id="selectID" class="selector">
                            <option>Show All</option>
                            <option>User1</option>
                            <option>User2</option>
                            <option>User3</option>
                            <option>User4</option>
                        </select>
    </div>
     
            <fieldset id="templateControlObject">
        <legend>Pick a name:</legend>
        <select id="templateControlObjectSelector">
            <option value="0">Show one</option>
            <option value="1">Show two</option>
            <option value="2">Show three</option>
        </select>
    </fieldset>
    </body>

    Default.js
    function handleChange(evt) {
        var templateElement = document.getElementById("templateDiv");
        var renderHere = document.getElementById("templateControlRenderTarget");
        renderHere.innerHTML = "";
        var selected = evt.target.selectedIndex;
        WinJS.UI.process(templateElement).then(function (templateControl) {
            while (selected >= 0) {
                templateControl.render(people[selected--], renderHere);
            }
        });
        WinJS.Utilities.children(renderHere).listen("change", function (evt) {
            if (evt.currentTarget.className== "seletor") {
                var selected = evt.target.selectedIndex;
                selectIndex.innerText = selected;
            }
           
        });
    }


    Monday, July 23, 2012 7:07 AM
  • Hi

    Have You read the code I provided?

    I think it's make the question clear enough.

    Thursday, July 26, 2012 8:24 AM
  • Thanks for the soln. but I m finding the solution pretty complex. so difficult to understand.

    what is this fieldset tag doing?

    I have a listview where I show 4 items. I have 2 templates. one template has only text and other template has a text and dropdown(select tag).

    To first 3 items I apply first type of template and on just 1 item I apply the second kind of template.


    Chetan

    Thursday, July 26, 2012 12:43 PM
  • handleChange event is binded to which control ?

    Chetan

    Thursday, July 26, 2012 12:57 PM
  • Hi

    HandleChange event is binded to templete row.

    Each row has  many controls, that's why I use if statement.

     if (evt.currentTarget.className== "seletor") {// you can write your own filter here.

    In your project, tyr to use

    WinJS.Utilities.children(renderTemplateDIV).listen("change", function (evt) {

    after your renderd the template field.

    If you still confuse, you can paste your simple repro codes here.


    For fieldset :http://msdn.microsoft.com/en-us/library/ie/ms535247(v=vs.85).aspx
    • Edited by Dino He Friday, July 27, 2012 3:31 AM
    Friday, July 27, 2012 3:28 AM
  • ok.. again I will try to reframe my problem..

    I am using a listview to show four groups of data. i.e A, B, C and D.

    A, B, C and D are group headers and each has few items to show.

    I am showing A, B and D as plain text. but I am showing C with a down arrow key on click of it I need to show flyout which has options to filter the data in group C.

    2 Group Header template are used for same. once with plain text and another one with text and down arrow key.

    I am adding the code snippet below

    var ListView = document.getElementById("ListView").winControl;
    
                ui.setOptions(ListView , {
                    itemDataSource: GroupedList.dataSource,
                    groupDataSource: GroupedList.groups.dataSource,
                    itemTemplate: itemTemplateFunction,
                    groupHeaderTemplate: groupTemplatefunction
                });

    the above code is used to dynamically bind different template to groupheader and items based on certain conditions.

    <div id="grpTemplate1" data-win-control="WinJS.Binding.Template" style="display: none">
                    <div class="Header" data-win-bind="innerText: groupName"></div>
                </div>
    
    -------------------------------
    
                <div id="grpTemplate2" data-win-control="WinJS.Binding.Template" style="display: none">
                        <button class="titlecontainer">
                            <span class="Header">C</span>
                            <span class="chevron win-type-x-large">&#xe099</span>
                        </button>
                      
                </div>

    there is a button inside the groupHeader for a category. when i click on it, i do not get the control for the same. please help.

    thanks for all the support till now.


    Chetan

    Tuesday, July 31, 2012 6:43 AM
  • Things seem to be getting very confusing.  Let's restart.  I modified a Grid based template to show this.  Specifically the groupedItems page

    If you want to add an onChange handler you can do it as follows:

    1.  Define your onChange event handler in your JS file:

      function onSelectChange(event) {
            // do change stuff in here, the event will give you the control that the change is occuring for as well
            var str = "changed!";
        }

    2.  and Expose your onChange event handler through WinJS.Namespace.define:

        function onSelectChange(event) {
            // do change stuff in here, the event will give you the control that the change is occuring for as well
            var str = "changed!";
        }
        WinJS.Namespace.define("groupedItemsPage", { onSelectChange: onSelectChange }
    );
    })();

    3.  Wire your onChange event handler in your template:

     <!-- These templates are used to display each item in the ListView declared below. -->
        <div class="headerTemplate" data-win-control="WinJS.Binding.Template">
            <p class="group-title win-type-x-large" data-win-bind="textContent: title; groupKey: key" 
                onclick="WinJS.Navigation.navigate('/pages/groupDetail/groupDetail.html', { groupKey: event.srcElement.groupKey })" role="link"></p>
            <select onchange="groupedItemsPage.onSelectChange(event)">
                            <option>Show All</option>
                            <option>User1</option>
                            <option>User2</option>
                            <option>User3</option>
                            <option>User4</option>
                        </select>
        </div>
    -Jeff

    Jeff Sanders (MSFT)

    Tuesday, July 31, 2012 2:13 PM
    Moderator
  • Hi

    Sounds like your real question is

    How to handle sub control event in Listview

    Please check my post here:

    http://social.msdn.microsoft.com/Forums/en-US/winappswithhtml5/thread/0771142e-bf14-4b21-ba55-bf262b24ddf2/

    Friday, August 03, 2012 7:19 AM
  • the issue resolved when I copied the function outside the function block present inside the .js file and made that function as global.

    Chetan

    Friday, August 03, 2012 2:26 PM
  • Thanks Dino and Jspanders for the all the support

    Chetan

    Friday, August 03, 2012 2:28 PM
  • Great.  FYI step 2 of my instructions also makes the function global but with a Namespace scoping.

    Jeff Sanders (MSFT)

    Friday, August 03, 2012 2:28 PM
    Moderator
  • yes I am aware of it..

    Chetan

    Monday, August 06, 2012 5:34 AM