Maffster
Maffster

Reputation: 25

Javascript For Loop keeps doubling up my divs

I have written a script that creates a number of fields based on a number the user inputs (k).

I originally wrote a script that would create the correct number of fields. However I wanted to arrange them like vectors on the screen, so I adapted my script.

I wanted the following script to create the correct number of fields and place them in DIVS, so I could lay them out as I wish on the page.

Since doing this, the script now produces duplicate DIVS as iff it runs through the loop twice, but I can't for life of me work out why...

function createFields(k)
{
k=k+1

for (var n=1; n<k; n++) {

    var makeBox=document.createElement("div");
    makeBox.id = "box" + n;
    document.getElementById("top").appendChild(makeBox);
    document.getElementById("box" + n).setAttribute('class',"box");

    var addOpen=document.createElement("div");
    addOpen.id = "open"+n;
    document.getElementById("box" + n ).appendChild(addOpen);
    document.getElementById("open" + n).setAttribute('class',"open");

    var vectorBox=document.createElement("div");
    vectorBox.id = "vector" + n;
    document.getElementById("box" + n).appendChild(vectorBox);
    document.getElementById("vector" + n).setAttribute('class',"vect");

    var xVector=document.createElement("div");
    xVector.id = "top" + n;
    document.getElementById("vector" + n).appendChild(xVector);
    document.getElementById("top" + n).setAttribute('class',"xVect");

    var newx=document.createElement("input");
    newx.id = "x" + n;
    document.getElementById("top" + n).appendChild(newx);
    document.getElementById("x" + n).setAttribute('name',"x" + n);
    document.getElementById("x" + n).setAttribute('type',"text");
    document.getElementById("x" + n).setAttribute('size',"4");
    document.getElementById("x" + n).setAttribute('maxlength',"4");

    var yVector=document.createElement("div");
    yVector.id = "bottom" + n;
    yVector.class = "yVect";
    document.getElementById("vector" + n).appendChild(yVector);
    document.getElementById("bottom" + n).setAttribute('class',"yVect");

    var newy=document.createElement("input");
    newy.id = "y" + n;
    document.getElementById("bottom" + n).appendChild(newy);
    document.getElementById("y" + n).setAttribute('name',"y" + n);
    document.getElementById("y" + n).setAttribute('type',"text");
    document.getElementById("y" + n).setAttribute('size',"4");
    document.getElementById("y" + n).setAttribute('maxlength',"4");

    var addClose=document.createElement("div");
    addClose.id = "close"+n;
    document.getElementById("box" + n ).appendChild(addClose);
    document.getElementById("close" + n).setAttribute('class',"close");

    }
}

Any clues?

UPDATED:

The Code is called via another function:

function getVectors()
{
v = document.getElementById("vectorN").value;
v=parseInt(v); //turn the text into an integer
document.getElementById("q1").innerHTML="Enter your Vectors below!";
createFields(v);
document.getElementById("enter").innerHTML="<input type=\"button\" id=\"button\" value=\"Submit Numbers\" onclick=\"canvas()\"/>";

}

Which is called by onchange in the html:

<p id="q1">How many Vectors will you need?
        <input id="vectorN" name="vectorN" type="text" onChange="getVectors()" size="4" maxlength="4">
      </p>

Further UPDATE

After checking the console.log, the only place that calls createFields() is the getVectors() function. It does appear to be calling createFields twice (despite only doing so once in the script). The ONLY place that calls getVectors() is the onChange event in the input field. Is it possible that when I change the innerHTML and remove the input field that this is being registered as an onChange event and calling the function again?

Upvotes: 2

Views: 257

Answers (3)

Jon P
Jon P

Reputation: 19772

This SO Question sheds some light on the problem. I'd been tabbing out of the text box, which only triggers the onChange event once. Pressing enter fires it twice, which is the problem you were getting.

There are a couple of ways to get around this. I've chosen to keep track of the number of fields entered. If this changes, generate the fields. If not do nothing.

var fields = 0;

function createFields(k) {
    if (k != fields) {
        fields = k;
        console.log("Fields: " + k);

        //Rest of the code the same;
    }
}

Demo: http://jsfiddle.net/Ej8Ly/5/

You could also do something similar in the getVectors() function instead.

Upvotes: 0

KnightHawk0811
KnightHawk0811

Reputation: 931

Rather than "creating" all the elements with the DOM why not build a "string" and then set a container objects .innerHTML = the_string value? This way it won't matter if the function gets called twice because it will simply overwrite itself the second time and produce the same output.

Upvotes: 0

Christiaan Westerbeek
Christiaan Westerbeek

Reputation: 11137

Your function looks fine. aren't you just calling the function twice? Do a console.log right after function createFields(k) { to check if that's the case. Maybe 2 event listeners on the field where the user inputs k (onkeyup, change)?

If you're not sure where you call createFields from. Do a find in all files and look for createFields. Add a console.log('Calling createFields from here'); just before you call createFields.

Upvotes: 1

Related Questions