Reputation: 81
Hi I have this javascript that adds a textbox when the user clicks a button. The textbox is then added to the DOM webpage.
However It now does not seem to stop and gets caught it a infinite loop.
The loop uses
GetElementsbyTagName
and how many there are for the limit but it was working fine earlier on .
//add rows function
window.onload=function()
{
s=5; //for staff
n=20; //for events
//sets at default incase no js rows created
var staffbox = document.getElementById('staffcounter');
staffbox.value = s;
var eventsbox = document.getElementById('eventscounter');
eventsbox.value = n;
inp=document.getElementsByTagName('input');
for(c=0;c<inp.length;c++) // <---- I think this bit is causing the crash!
{
if(inp[c].name=='addstaff')
{
inp[c].onclick=function()
{
var sel = document.createElement('select');
sel.name = 'staff' + s;
option1 = document.createElement('option');
option1.name = 'Please select';
option1.value = '';
option1.innerHTML = option1.value;
option2 = document.createElement('option');
option2.name = 'Nurse';
option2.value = 'Nurse';
option2.innerHTML = option2.value;
sel.appendChild(option1);
sel.appendChild(option2);
document.getElementById('staffarea').appendChild(sel);
x=document.createElement('input');
x.setAttribute('rows',1);
x.setAttribute('cols',20);
x.name='staffquantity'+s;
document.getElementById('staffarea').appendChild(x)
document.getElementById ('staffarea').innerHTML += '<br>';
// This bit updates a counter that will be $_POST
var staffbox = document.getElementById('staffcounter');
staffbox.value = s;
s++;
}
}
else if(inp[c].name=='addevent')
{
timemaker(); // calls another function which creates a specific text box
x=document.createElement('input');
x.setAttribute('rows',1);
x.setAttribute('cols',20);
x.name='event'+n;
document.getElementById('eventarea').appendChild(x);
x=document.createElement('input');
x.setAttribute('rows',1);
x.setAttribute('cols',20);
x.name='supplies'+n;
document.getElementById('eventarea').appendChild(x);
x=document.createElement('input');
x.setAttribute('rows',1);
x.setAttribute('cols',20);
x.name='manufacturer'+n;
document.getElementById('eventarea').appendChild(x);
x=document.createElement('input');
x.setAttribute('rows',1);
x.setAttribute('cols',20);
x.name='quantity'+n;
document.getElementById('eventarea').appendChild(x);
var sel = document.createElement('select');
sel.name = 'success' + n;
y = document.createElement('option');
y.name = 'Yes';
y.value = 'Yes';
y.innerHTML = y.value;
x = document.createElement('option');
x.name = 'No';
x.value = 'No';
x.innerHTML = x.value;
sel.appendChild(y);
sel.appendChild(x);
document.getElementById('eventarea').appendChild(sel);
x=document.createElement('input');
x.setAttribute('rows',1);
x.setAttribute('cols',20);
x.name='comment'+n;
document.getElementById('eventarea').appendChild(x);
document.getElementById ('eventarea').innerHTML += '<br>';
// This bit updates a counter that will be $_POST
var eventsbox = document.getElementById('eventscounter');
eventsbox.value = n;
n++;
}
}
return;
}
Thanks
Upvotes: 3
Views: 1202
Reputation: 35701
HTMLCollection's are live query's.
Meaning:
NodeList and NamedNodeMap objects in the DOM are live; that is, changes to the underlying document structure are reflected in all relevant NodeList and NamedNodeMap objects. For example, if a DOM user gets a NodeList object containing the children of an Element, then subsequently adds more children to that element (or removes children, or modifies them), those changes are automatically reflected in the NodeList, without further action on the user’s part. Likewise, changes to a Node in the tree are reflected in all references to that Node in NodeList and NamedNodeMap objects.
This is why you get a infinite loop.
inp=document.getElementsByTagName('input');
In the loop i see that new <input>
's are created.
x=document.createElement('input');
So the solution should be either to change to inp=document.querySelectorAll("input")
Or to have a static variable of the length
like so:
var = inp=document.getElementsByTagName('input'),
inputsLength = inp.length;
for(c=0;c<inputsLength;c++){
... loop ....
}
Upvotes: 4
Reputation: 23142
If you only need to do something with <input name="addEvent" />
and <input name="addStaff" />
, then you could simplify your script a little by giving those elements a unique id
attribute and retrieving them thusly:
var addEventInp = document.getElementById("addEventID");
var addStaffInp = document.getElementById("addStaffID");
Then, you could do whatever you need to do with just those two elements. I'll bet that this approach will get rid of your infinite loop problem as well.
Upvotes: 0
Reputation: 5986
When you add an input element to your document count of inp changes.
inp=document.getElementsByTagName('input');
So it's an infinite loop when you depend on inp's count and add an input every iteration.
Assing length to a variable and use it for the loop.
inpCount = document.getElementsByTagName('input').length;
Upvotes: 2