locked
Dom manipulation problem

    Question

  •   One of my function creates some divS and buttons inside them. Then I want to gather those buttons when the app starts. My code is as follows but I cannot get references of those buttons in JavaScript, although I can see them on HTML page. What am I missing?

    part of code in a navigation template project that creates buttons:

    for (var i = 0; i < counter; i++) {
                                    str = dataArray[i].timerName;
                                    str1 = str.slice(1, str.length - 1);
                                    console.log(str1);
                                    message += str1 + "\n";
                                    var newDiv = document.createElement("div");
                                    var newBt = document.createElement("button");
                                    newBt.id = str1 + "Bt";
                                    var btValue = document.createTextNode(str1);
                                    newBt.appendChild(btValue);
                                    newDiv.appendChild(newBt);
                                    listDiv.appendChild(newDiv);
                                }

    In another function I want to get references of those buttons:

    var buttons = document.querySelector("#timerList");
                console.log("tier: " + buttons.id);
                var allButtons = buttons.querySelectorAll("div");
                var bFound = (allButtons == null) ? "No matches found" : allButtons.length;
                console.log(bFound);
                for (var i = 0; i < bFound; i++) {
                    console.log(allButtons[i].id);
                    allButtons[i].addEventListener("click", function () { console.log(allButtons[i].value); }, false);
                }

    Friday, April 19, 2013 8:10 PM

Answers

  • I've created a blank app to test this. my default html looks like this:

    <body>
        <div id="timerList"></div>
    
    </body>

    my default.js like this (I had to assume some values for dataArray, counter and message ...)

    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.
                }
    
                var dataArray = [{ timerName: "1abc2" }, { timerName: "2def3" }, { timerName: "3ghi4" }];
                var counter = dataArray.length;
                var listDiv = document.getElementById("timerList");
                var message = "";
                for (var i = 0; i < counter; i++) {
                    var str = dataArray[i].timerName;
                    var str1 = str.slice(1, str.length - 1);
                    console.log(str1);
                    message += str1 + "\n";
                    var newDiv = document.createElement("div");
                    var newBt = document.createElement("button");
                    newBt.id = str1 + "Bt";
                    var btValue = document.createTextNode(str1);
                    newBt.appendChild(btValue);
                    newDiv.appendChild(newBt);
                    listDiv.appendChild(newDiv);
                }
    
                var buttons = document.querySelector("#timerList");
                console.log("tier: " + buttons.id);
                var allButtons = buttons.querySelectorAll("button");
                var bFound = (allButtons == null) ? "No matches found" : allButtons.length;
                console.log(bFound);
                for (var i = 0; i < bFound; i++) {
                    console.log(allButtons[i].id);
                    allButtons[i].addEventListener("click", function (evt) {console.log(evt.target.textContent);}, false);
                }
    
                args.setPromise(WinJS.UI.processAll());
            }

    This code works for me.

    Friday, April 19, 2013 10:10 PM

All replies

  • You are creating markup like this at runtime:

    <div id="timerList">
      <div>
         <button id="someTextBt">someText</button>
      </div>
      <div>
         <button id="someOtherTextBt">someOtherText</button>
      </div>
    </div>

    Your first selector

    document.querySelector("#timerList");


    selects the outer div.

    The second selector 

     var allButtons = buttons.querySelectorAll("div");

    selects the div's that surround the buttons, not the buttons themself. In order to get the buttons, you have to change it to:

     var allButtons = buttons.querySelectorAll("button");

    This gives you an array of buttons. The next issue is that you're accessing your counter loop (i) in your event handler:

     allButtons[i].addEventListener("click", function () { console.log(allButtons[i].value); }, false);

    This doesn't work because at the time when your event handler (console.log(allButtons[i].value);) get's called i has a value of bFound. In order to get the element that caused the click, you have to write something like this:

    allButtons[i].addEventListener("click", function (evt) {console.log(evt.target.textContent);}, false);

    In addition, I changed your .value to .textContent because that's how you get the text of a button.

    Hope that helps!

    Friday, April 19, 2013 9:11 PM
  • I have changed my code as your suggestions. But still I don't get reference to buttons inside that div.

    var allButtons = buttons.querySelectorAll("buttons");
                
                console.log(allButtons);                               // gives 0. Though there are two buttons inside that main timer div.
    Friday, April 19, 2013 9:57 PM
  • please remove the "s" in buttons:

    var allButtons = buttons.querySelectorAll("buttons");

    it should be 

    var allButtons = buttons.querySelectorAll("button");

    Friday, April 19, 2013 10:00 PM
  •   Yes, ofcourse, that was a typo error. But still the problem is same.
    Friday, April 19, 2013 10:07 PM
  • I've created a blank app to test this. my default html looks like this:

    <body>
        <div id="timerList"></div>
    
    </body>

    my default.js like this (I had to assume some values for dataArray, counter and message ...)

    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.
                }
    
                var dataArray = [{ timerName: "1abc2" }, { timerName: "2def3" }, { timerName: "3ghi4" }];
                var counter = dataArray.length;
                var listDiv = document.getElementById("timerList");
                var message = "";
                for (var i = 0; i < counter; i++) {
                    var str = dataArray[i].timerName;
                    var str1 = str.slice(1, str.length - 1);
                    console.log(str1);
                    message += str1 + "\n";
                    var newDiv = document.createElement("div");
                    var newBt = document.createElement("button");
                    newBt.id = str1 + "Bt";
                    var btValue = document.createTextNode(str1);
                    newBt.appendChild(btValue);
                    newDiv.appendChild(newBt);
                    listDiv.appendChild(newDiv);
                }
    
                var buttons = document.querySelector("#timerList");
                console.log("tier: " + buttons.id);
                var allButtons = buttons.querySelectorAll("button");
                var bFound = (allButtons == null) ? "No matches found" : allButtons.length;
                console.log(bFound);
                for (var i = 0; i < bFound; i++) {
                    console.log(allButtons[i].id);
                    allButtons[i].addEventListener("click", function (evt) {console.log(evt.target.textContent);}, false);
                }
    
                args.setPromise(WinJS.UI.processAll());
            }

    This code works for me.

    Friday, April 19, 2013 10:10 PM
  •   I'm fetching dataArray from a file read function. Inside that I've created those divs and buttons. May be it's something to look for. Thanks a lot for help though.


    • Edited by SonalMac Friday, April 19, 2013 10:34 PM
    Friday, April 19, 2013 10:33 PM