edoras
edoras

Reputation: 159

JavaScript closure, just not getting it

I'm trying to add inputs iteratively, and be able to run a calculation independently on each, but can not seem to apply the closure principles. The calculation function is only working on the last item added. I've tried using a for loop within as well as around the main function (addIt()) but it only seems to make things worse... Here's the basic html:

<button class="btn btn-default btn-block" onClick="addIt('Item'+count)">Add One</button>

<form>
     <div id="itemForm"></div> 
<form>

And here is my overly complex and inelegant js (by the way, I'm open to better ways of doing this, so please don't hesitate to jump all over this):

count = 0;
        addIt = function(p) {
                count++;
                var itFrm = document.getElementById("itemForm");
                var itDiv = document.createElement("div");
                var children = itFrm.children.length + 1
                itDiv.setAttribute("id", "itemDiv")
                itDiv.appendChild(document.createTextNode(p));
                itFrm.appendChild(itDiv);

                var remove = document.createElement("a");
                var linkText = document.createTextNode("Remove It");
                remove.setAttribute("href", "#");   
                remove.setAttribute("onClick", "removeIt()");
                remove.appendChild(linkText);

                var brk = document.createElement("br");

                var num = document.createElement("input");
                num.setAttribute("id", "numInput"+count);
                num.setAttribute("type", "number");
                num.oninput = function () {
                                var numInput = document.getElementById('numInput'+count).value ;    
                                var divisor = 10;
                                var result = document.getElementById('result'+count);   
                                var myResult = (Number(numInput) / Number(divisor));
                                result.value = myResult;
                                };
                num.setAttribute("placeholder", "Set number...");

                var clc = document.createElement("input");
                clc.setAttribute("id", "result"+count);
                clc.setAttribute("readonly", "readonly");
                clc.setAttribute("placeholder", "After Calculation...");

                var hr = document.createElement("hr");

                itDiv.appendChild(remove);
                itDiv.appendChild(num);
                itDiv.insertBefore(brk, num);
                itDiv.appendChild(clc);
                itDiv.appendChild(hr);
            };

            function removeIt(elem) {
                var elem = document.getElementById('itemDiv');
                elem.parentNode.removeChild(elem);
                return false;
            };

I tried to setup a jsfiddle here but for some reason the removeIt function doesn't work there, although it's working locally for me, but only removes the oldest iteration. Any thoughts on how I've botched that are welcomed and appreciated as well.

Upvotes: 1

Views: 45

Answers (1)

codemonkeyliketab
codemonkeyliketab

Reputation: 320

    var countString = count.toString();   
    num.oninput = function() {
    var numInput = document.getElementById('numInput' + countString).value;
    var divisor = 10;
    var result = document.getElementById('result' + countString);
    var myResult = (Number(numInput) / Number(divisor));
    result.value = myResult;   };

It was a scoping issue with count. Its basically a global variable so the closure will look for it. Use a local variable that gets re declared on each button press to fix it.

Upvotes: 1

Related Questions