locked
Change div content via oniteminvoked event RRS feed

  • Question

  • Hello,

    I need to change the content of a div when the user clicks on a ListView item, so using the oniteminvoked event.

    The problem is, i set up the eventlistener like this:

    lstHosts = document.getElementById("HostsListView"); lstHosts.addEventListener("iteminvoked", function (e) { e.detail.itemPromise.then(function (invokedItem) { Options.innerHTML = document.getElementById(invokeditem.data.title).innerHTML; }); }, false);

    Obviously the item's title in the ListView and the div id are the same.

    But it works only the first time, the second i get "Unable to get property 'innerHTML' of undefined or null reference".

    Then i tried using the eventlistener to store the title, i created a function which does the same thing as above, and added the oniteminvoked: handler thing to the ListView's data-win-options. It does still work but only for the first time, then i get the same error as before.

    Is there any method to accomplish what i need?

    Thanks in advance.

    Monday, October 29, 2012 10:03 AM

Answers


  • Hi moneri_,

    In your code, you use databinding to assign the "id" attribute of the certain content element in each itemTemplate. Actually, you can simply use the querySelector method to locate the certain child elements within the certain ListView item container. Here is a simple example I've used for test which works correctly for multiple times (in a Navigation App project).

    #html of the Listview and item template:

    <div id="lvBlogFeedItemTemplate" data-win-control="WinJS.Binding.Template">
                <div  class="row" >
                    <div>
    
                        <a data-win-bind="href:uri;innerText:title" ></a> 
                        <input type="hidden" data-win-bind="value:summary" />
                    </div>
                </div>
            </div>
    
     <div id="lvBlogFeeds" 
                 
                                 data-win-control="WinJS.UI.ListView"
                                 data-win-options="{itemTemplate: select('#lvBlogFeedItemTemplate') ,layout:{type:WinJS.UI.ListLayout}}"
                >
    
            </div>
    # JS code for wrapping the event handler of ListView "iteminvoked" event. The handler locate an input hidden element within the selected item and use its value to populate another html <div> element.
     // Wrap event handlers for Listview
                var lvHost = document.getElementById('lvBlogFeeds');
                lvHost.addEventListener("iteminvoked", function (evt) {
    
        
                    evt.detail.itemPromise.then(function (invokedItem) {
                        console.log("itemInvoked: " + invokedItem.data.title);
    
                        var input = evt.srcElement.querySelector("input[type=hidden]");
    
                        MSApp.execUnsafeLocalFunction(function () {
                            document.getElementById('divMessage').innerHTML = input.value;
                        });
                    });
              
                });


    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Putting communities in your palms. Launch the browser on your phone now, type aka.ms/msforums and get connected!

    • Marked as answer by Song Tian Monday, November 5, 2012 9:46 AM
    Tuesday, October 30, 2012 2:48 AM
    Moderator
  • Hi,

    Please add the iteminvoked event as follow:

    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
        WinJS.strictProcessing();
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll().then(function completed() {                
                    // addEventListener
                    var listView = document.getElementById("basicListView");
                    listView.addEventListener("iteminvoked", handler);
    
                }));
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
    
        function handler(eventInfo) {
            var dlg = new Windows.UI.Popups.MessageDialog("Ta-da!", "Ta-da!");
            dlg.showAsync();
    
        }
    
        app.start();
    })();


    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com
    Microsoft One Code Framework

    • Marked as answer by Song Tian Monday, November 5, 2012 9:46 AM
    Tuesday, October 30, 2012 2:45 AM

All replies

  • Hi,

    Please add the iteminvoked event as follow:

    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
        WinJS.strictProcessing();
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll().then(function completed() {                
                    // addEventListener
                    var listView = document.getElementById("basicListView");
                    listView.addEventListener("iteminvoked", handler);
    
                }));
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
    
        function handler(eventInfo) {
            var dlg = new Windows.UI.Popups.MessageDialog("Ta-da!", "Ta-da!");
            dlg.showAsync();
    
        }
    
        app.start();
    })();


    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com
    Microsoft One Code Framework

    • Marked as answer by Song Tian Monday, November 5, 2012 9:46 AM
    Tuesday, October 30, 2012 2:45 AM

  • Hi moneri_,

    In your code, you use databinding to assign the "id" attribute of the certain content element in each itemTemplate. Actually, you can simply use the querySelector method to locate the certain child elements within the certain ListView item container. Here is a simple example I've used for test which works correctly for multiple times (in a Navigation App project).

    #html of the Listview and item template:

    <div id="lvBlogFeedItemTemplate" data-win-control="WinJS.Binding.Template">
                <div  class="row" >
                    <div>
    
                        <a data-win-bind="href:uri;innerText:title" ></a> 
                        <input type="hidden" data-win-bind="value:summary" />
                    </div>
                </div>
            </div>
    
     <div id="lvBlogFeeds" 
                 
                                 data-win-control="WinJS.UI.ListView"
                                 data-win-options="{itemTemplate: select('#lvBlogFeedItemTemplate') ,layout:{type:WinJS.UI.ListLayout}}"
                >
    
            </div>
    # JS code for wrapping the event handler of ListView "iteminvoked" event. The handler locate an input hidden element within the selected item and use its value to populate another html <div> element.
     // Wrap event handlers for Listview
                var lvHost = document.getElementById('lvBlogFeeds');
                lvHost.addEventListener("iteminvoked", function (evt) {
    
        
                    evt.detail.itemPromise.then(function (invokedItem) {
                        console.log("itemInvoked: " + invokedItem.data.title);
    
                        var input = evt.srcElement.querySelector("input[type=hidden]");
    
                        MSApp.execUnsafeLocalFunction(function () {
                            document.getElementById('divMessage').innerHTML = input.value;
                        });
                    });
              
                });


    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Putting communities in your palms. Launch the browser on your phone now, type aka.ms/msforums and get connected!

    • Marked as answer by Song Tian Monday, November 5, 2012 9:46 AM
    Tuesday, October 30, 2012 2:48 AM
    Moderator
  • I was so stupid that i didn't realize that the divs i wanted to replace the Options div with were inside the Options div itself, so calling Options.innerHTML the first time replaced everything, and that's why the second time getElementById returned null.

    Once i moved them outside, it worked everytime i clicked.

    Hope i explained myself well.

    Thanks again

    moneri_


    • Edited by moneri_ Tuesday, October 30, 2012 4:05 PM
    Tuesday, October 30, 2012 4:05 PM
  • In the below code, handler is not working its showing an error

    (function () {
        "use strict";
    
        WinJS.UI.Pages.define("/pages/home/home.html", {
            // This function is called whenever a user navigates to this page. It
            // populates the page elements with the app's data.
            ready: function (element, options) {
                // TODO: Initialize the page here.
                var listView = document.getElementById("basicListView");
                listView.addEventListener("iteminvoked", handler);
    
            },
            function handler(eventInfo) {
            var dlg = new Windows.UI.Popups.MessageDialog("Ta-da!", "Ta-da!");
        dlg.showAsync();
    
    }
    
    });
    })();

    so i changed the above to

    (function () {
        "use strict";
    
        WinJS.UI.Pages.define("/pages/home/home.html", {
            // This function is called whenever a user navigates to this page. It
            // populates the page elements with the app's data.
            ready: function (element, options) {
                // TODO: Initialize the page here.
                var listView = document.getElementById("basicListView");
                listView.addEventListener("iteminvoked", handler);
    
            },
            handler : function (eventInfo) {
            var dlg = new Windows.UI.Popups.MessageDialog("Ta-da!", "Ta-da!");
        dlg.showAsync();
    
    }
    
    });
    })();

    but then its saying that handler is not defined? I'm not able to understand the problem


    Saturday, December 21, 2013 5:33 PM