Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations sizbut on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

DOM adding input-fields mozilla bug? 3

Status
Not open for further replies.

Rekcor

Programmer
Feb 15, 2005
48
NL
I don't now where to put this question, because its a combination of Javavscript/HTML/PHP.

Anyway, I wanted to make a flexible form, which allows the user to enter multiple events for an online agenda.
The user can enter data in several input fields. These input fields are in a table:

Code:
<form action="/Management/calendar.php" method="post">
<table width="100%" class="sortable" id="inputList">
<tr id="inputRow">
<td><input style="width: 80px" name="date[]" type="text"></td>
<td><input style="width: 80px" name="time[]" type="text"></td>
<td><input style="width: 150px" name="name[]" type="text"></td>
<td><input style="width: 270px" name="description[]" type="text">
</td>
</tr>
</table>
<input style="float:right;" width="30px;" type="button" name="addRow" value="New row" onclick="duplicateCleanRowInTable('inputRow')"><p>
<input type="submit" name="addEvents" value="Ok"></p></fieldset>
</form>

Because I wanted to give the user the possible to enter n entries, I added the 'New Row' button. This button calls a function, which copies the entire row. The input fields are made empty:

Code:
<script>
function duplicateCleanRowInTable(rowId)
{
	/*
	 make copy of row
	*/ 
	newRow=document.getElementById(rowId).cloneNode(true);
	
	/*
	 clean up row
	*/
	newRow.id=''; 
	
	//walk through all cells and clear contents in form elements
	for (i=0; i<newRow.childNodes.length; i++)
	{
		newRow.childNodes[i].childNodes[0].value='';
	}
	
	/*
	 add new row to table
	*/
	document.getElementById('inputList').tBodies[0].appendChild(newRow);
}

This works fine in IE, but when multiple events (no matter how many) are posted in Mozilla, only the first comes through. In other words:

Code:
<?php
 print_r($_POST);
?>

always returns:

Array
(
[calendarList] => Kalender 1
[date] => Array
(
[0] => Test
)

[time] => Array
(
[0] => Test
)

[name] => Array
(
[0] => Test
)

[description] => Array
(
[0] => Test
)

[addEvents] => Ok
)

in Mozilla, whereas in IE it returns arrays with multiple entries.

Is this a bug in Mozilla or in my code?
 
Is this a bug in Mozilla or in my code?
I don't know. One thing to try would be to hand-code a version that starts with two rows of <input>s, instead of using scripting to generate the second row, and see if it works. If it does, you'll know that the problem lies in your script; if it doesn't, you'll know it's something else. Also, try changing the form to [tt]method="get"[/tt] so you can see what values it is sending back. If it's the script that's at fault, you could find the DOM Inspector (in the Tools menu) useful in determining what it actually generates when you add a new row.

I'd also try removing the [] from your <input> names.

-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
Thanx!

When I manually add a second row, everything works fine. When I add the row using the JS function, the row is added to the table, but the form elements inside the cells are for some reason not posted in Mozilla.
 
Are you changing the names of the form elements you are creating with JS? If not, they will just overwrite the ones from the last "line" of the table.

Cheers,
Jeff

[tt]Jeff's Page [/tt][tt]@[/tt][tt] Code Couch
[/tt]
 
Are you changing the names of the form elements you are creating with JS? If not, they will just overwrite the ones from the last "line" of the table

Im not changing them. Because there is an '[]' behind the name, PHP recognizes the posted values to be in an array. This works fine in Mozilla when I add another row manually.
 
Might I suggest you name them differently. That's why they are not being sent through in the form. Make the name property of all your input elements contain unique names... and stick with just alpha characters (as a general rule - without getting into specifics).

That'll fix it for you [smile]

Cheers,
Jeff

[tt]Jeff's Page [/tt][tt]@[/tt][tt] Code Couch
[/tt]
 
Hi Jeff,

Thanks for your tip, but

Code:
<tr>
<td><input style="width: 80px" name="date[]" type="text"></td>
<td><input style="width: 80px" name="time[]" type="text"></td>
<td><input style="width: 150px" name="name[]" type="text"></td>
<td><input style="width: 270px" name="description[]" type="text">
</td>
</tr>
<tr>
<td><input style="width: 80px" name="date[]" type="text"></td>
<td><input style="width: 80px" name="time[]" type="text"></td>
<td><input style="width: 150px" name="name[]" type="text"></td>
<td><input style="width: 270px" name="description[]" type="text">
</td>
</tr>

works fine in Moz, regardless of the same names. The problem arises (only in Moz, not in IE) when I add the second row using de HTML DOM method cloneNode.

I also used the Moz Dom inspector and everything looks fine: after pressing the 'New Row'-button, the TBODY element has another childNode, which is an exact copy of the original row (all properties are the same).

This forces me to conclude its a bug in Mozilla: the new row is inserted in the table, but somehow not in the form...
 
Rather than throw my suggestion of using unique names out the window... why not give it a go?! Get rid of the [] in your element names (as Chris suggests) and put some unique names together (make them the same as your IDs if you already set an ID on every element). It should take you no time and the worse that can happen is that you prove me wrong. The best that can happen is that it solves the problem!

I'm suggesting you try 2 things:
- remove [] from the name property on each input element
- give each name property a unique value

The fact it doesn't work as you expect in Moz (but does in IE) is not a guarantee that there is a bug at all. IE is infamous for not breaking on code that is badly formed.

Do you test in any other browsers? Try Opera. Try Netscape. If you have access to a MacOSX installation - try Safari and IE 5.2 to see what happens. I think I already know [smile]

Cheers,
Jeff

[tt]Jeff's Page [/tt][tt]@[/tt][tt] Code Couch
[/tt]
 
I'm suggesting you try 2 things:
- remove [] from the name property on each input element
- give each name property a unique value

Ok, I tried it. The []s are gone and the function duplicateCleanRowInTable adds 'NewRow' to the name property of the newly added input fields.

Code:
(...)
//walk through all cells and clear contents in form elements
	for (i=0; i<newRow.childNodes.length; i++)
	{		
		newRow.childNodes[i].childNodes[0].value='';
		newRow.childNodes[i].childNodes[0].name=newRow.childNodes[i].childNodes[0].name+'NewRow';
	}
(...)

Using the DOM inspector, I found out the following code is present after pressing the 'Add row' button once:

Code:
<tr>
<td><input style="width: 80px" name="date" type="text"></td>
<td><input style="width: 80px" name="time" type="text"></td>
<td><input style="width: 150px" name="name" type="text"></td>
<td><input style="width: 270px" name="description" type="text">
</td>
</tr>
<tr>
<td><input style="width: 80px" name="dateNewRow" type="text"></td>
<td><input style="width: 80px" name="timeNewRow" type="text"></td>
<td><input style="width: 150px" name="nameNewRow" type="text"></td>
<td><input style="width: 270px" name="descriptionNewRow" type="text">
</td>
</tr>

Unfortunately... it still doesn't work. You are right about one thing however: it doesn't work in Opera either ;-)

 
I'd still try changing from post to get (while debugging) to see what FF is sending back - maybe those input names are being malformed in some way. You might be able to fix it by explicitly resetting the names as you want them.

If all else fails and you do end up having to give each row unique names - date1, time1, name1, desc1; date2, time2, name2, desc2; etc. - add a hidden <input> that holds the number of the highest-numbered row (i.e. it'll be 1 on load, and your script will need to increment it with each new row). That way the script will know how many fields it has to look for.

-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
I wrote a function which walks the DOM tree of the form:

Code:
<script>
function showFormElements()
{
	for (i=0; i<document.getElementById('theForm').elements.length;i++)
	{
		alert(document.getElementById('theForm').elements[i]+'\n'+document.getElementById('theForm').elements[i].name);
	}
}
</script>

In IE, the new elements are childNodes of the form, in Mozilla and Opera, they arent. They are - in all browsers - (grand)childnodes of the TBODY node...
 
Chris,

I also tried the GET suggestion: the new elements do not appear in the URL

Regards,
Koos
 
Maybe I found a solution. I think its the cloneNode function which is causing me the trouble. If I add the new form elements manually (as is done in the code below), the new elements become childNodes of the form:

Code:
<html>
<head>
<title>Adding elements to a form</title>
<script language="javascript">
var items=1;
function AddItem() {
  div=document.getElementById("items");
  button=document.getElementById("add");
  items++;
  newitem="<b>Item " + items + ": </b>";
  newitem+="<input type=\"text\" name=\"item" + items;
  newitem+="\" size=\"45\"><br>";
  newnode=document.createElement("span");
  newnode.innerHTML=newitem;
  div.insertBefore(newnode,button);
}
</script>
</head>
<body>
<h1>Adding Form Elements</h1>
<p>The form below allows you to add elements dynamically.</p>
<hr>
<form name="form1" id="theForm">
<div ID="items">
<b>Item 1:</b>
<input type="text" name="item1" size="45">
<br>
<input type="button" value="Add an Item"
onClick="AddItem(); showFormElements()" ID="add">
</div>
</form>

<script>
function showFormElements()
{
	for (i=0; i<document.getElementById('theForm').elements.length;i++)
	{
		alert(document.getElementById('theForm').elements[i]+'\n'+document.getElementById('theForm').elements[i].name);
	}
}
</script>

</body>
</html>

I will try and implement this in my own code and tell you if it worked out...

Regards,
Koos
 
Code:
document.getElementById('inputList').tBodies[0].appendChild(newRow);
I wonder if it's the tBodies collection that it doesn't like? Perhaps because there's no explicit <tbody> in your markup? DOM scripting isn't really my strong suit, but how about this instead:
Code:
document.getElementById(rowId).parentNode.appendChild(newRow);

-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
Hi Guys,

I found the solution! However, it was not in the code I showed you. The problem was with the <form> and <fieldset> tags I used. I didn't show them because we are talking about a huge page here.

It was like this:

Code:
<fieldset id="1">
<form>
(...)
</fieldset>
<fieldset id="2">
(...)
</fieldset>
</form>

So the </fieldset> was before </form>. Now I've changed it into:

Code:
<form>

<fieldset id="1">
(...)
</fieldset>

<fieldset id="2">
(...)
</fieldset>

</form>

everything works fine.

What have we learned from this: ALWAYS close a tag inside another tag. Maybe its a good tip for you guys to ask the next dummy with questions like this first to put his/her page through the W3C validator, before thinking of further solutions.

If the HTML is not 100% ok, Javascript and DOM programming will behave strangely in strict browsers like Mozilla and Opera.

Thanx for you tips/time and eh...sorry about mistake I made. I'll gladly give you the stars you deserve.
 
I think you deserve a star for figuring out the problem!


Tracy Dryden

Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard. [dragon]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top