/    Sign up×
Community /Pin to ProfileBookmark

Bit confused with nodes

Hello!
I am trying to adapt a script that adds form inputs but I’m very green at JS yet and from previous experience (php and whatnot) I’ve found that after being on my own for a while and then asking for input usually some1 comes up with a tip that would save me hours so this time I figured I’d do it differently. Perhaps some of you may help me out while I google this nodes thing out and make some sense of it.

[URL=”http://files.getdropbox.com/u/1531805/1.html”]This[/URL] is the original script
[URL=”http://files.getdropbox.com/u/1531805/attempt.html”]This[/URL] is the one I’m trying to make

[CODE]<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Untitled Document</title>

<script type=”text/javascript”>

<!–

var counter = 0;

function init() {
document.getElementById(‘moreFields’).onclick = moreFields;
moreFields();
}

function moreFields() {
counter++;
var newFields = document.getElementById(‘readroot’).cloneNode(true);
newFields.id = ”;
newFields.style.display = ‘block’;
var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
var theName = newField[i].name
if (theName)
newField[i].name = theName + counter;
}
var insertHere = document.getElementById(‘writeroot’);
insertHere.parentNode.insertBefore(newFields,insertHere);
}

function lessFields() {
counter–;
}

window.onload = moreFields;

// –>

</script>

</head>
<body>

<form action=”form.php” method=”post” name=”data” id=”1″>
<table width=”200″ align=”center”>
<tr>
<th scope=”col”><img src=”https://files.getdropbox.com/u/1531805/upbanner.png” width=”830″ height=”130″ alt=”text” /></th>
</tr>
<tr>
<td>
<table width=”829″><tr>
<td width=”100″><label>Order Date:</label></td>
<td><input name=”Order date:” type=”text” class=”txtbox”/></td>
</tr>
<tr>
<td><label>Teacher name:</label></td>
<td><input name=”Tname” type=”text” class=”txtbox” /></td>
</tr>
<tr>
<td><label>Subject:</label></td>
<td><input name=”Subject” type=”text” class=”txtbox”/></td>
</tr>
</table></td></tr><br><br><br>
<tr>
<td>
<table width=”829″ border=”1″ cellspacing=”1″>
<tr>
<td align=”center”><label>Autorius</label></td>
<td align=”center” style=”width:400px”><label>Antraste</label></td>
<td align=”center” style=”width:70px”><label>Metai</label></td>
<td align=”center” style=”width:70px”><label>Egz skaicius</label></td>
</tr>

<div id=”readroot” style=”display: none”><br>

<input type=”button” value=”Remove field”
onclick=”this.parentNode.parentNode.removeChild(this.parentNode);return lessFields()” /><br /><br />

<div><tr>
<td><input name=”Autor” type=”text” class=”txtbox2″/></td>
<td><input name=”Title” type=”text” class=”txtbox3″/></td>
<td><input name=”Year” type=”text” class=”txtbox4″/></td>
<td><input name=”Amount” type=”text” class=”txtbox4″/></td>
</tr></div>
</table>

</div>

<span id=”writeroot”></span>

</table>
<table width=”829″ align=”center”><tr height=”20″><td align=”right”>
<br><input type=”button” onclick=”return moreFields()” value=”Give me more fields!” />
<input type=”submit” value=”Send form” /></td></tr></table>

</form>

</body>
</html>[/CODE]

My current problem is being able to clone the table code. I’ve wrapped it around in a <div> but apparently that still doesnt get recognized as node. I think it should thou because it worked on some of the Nodes examples I’ve been through.
If that gets solved I will try to either get one remove button eliminating the last cloned “readroot” or multiple buttons but sided (new <tr>) with the table rows. Both of them will imply some node backtracking code changes that I am not sure I am yet able to get there :s

ps: ignore the ugly looking table I get it fixed wih css

to post a comment
JavaScript

14 Comments(s)

Copy linkTweet thisAlerts:
@MalgrimJul 18.2009 — Sorry, but there's too much amiss to simply correct it. I'd suggest something like the following, maybe you can work based on that
[code=html]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
<!--
var counter = 0;

function moreFields() {
counter++;
var newFields = document.getElementById('prototype').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.getElementsByTagName('input');
for (var i=0; i<newField.length; i++) {
var theName = newField[i].name;
if (theName) newField[i].name = theName + counter;
}
document.getElementById('fieldSetList').appendChild(newFields);
}
// -->
</script>
<style type="text/css">
h1 {text-align:center;}
th {font-weight:normal;}

.c {text-align:center;}
.r {text-align:right;}
.txtbox {width:150px;}
.txtbox2 {width:150px;}
.txtbox3 {width:400px;}
.txtbox4 {width:110px;}

.fieldSet table {border:1px outset #666666; width:100%;}
.fieldSet td,th {border:1px inset #666666; text-align:center;}

#container {width:830px; margin:auto;}
#prototype {display:none;}
</style>
<!--[if lt IE 7]>
<style type="text/css">
body {text-align:center;}
#container {text-align:left;}
</style>
<![endif]-->
</head>
<body onload="moreFields();">
<form action="form.php" method="post" name="data" id="form1">
<div id="container">
<h1><img src="https://files.getdropbox.com/u/1531805/upbanner.png" width="830" height="130" alt="text" /></h1>
<table>
<tr>
<td><label>Order Date:</label></td>
<td class="in"><input name="orderDate" type="text" class="txtbox"/></td>
</tr>
<tr>
<td><label>Teacher name:</label></td>
<td class="in"><input name="TName" type="text" class="txtbox" /></td>
</tr>
<tr>
<td><label>Subject:</label></td>
<td class="in"><input name="subject" type="text" class="txtbox"/></td>
</tr>
</table>
<div id="fieldSetList">
<div id="prototype" class="fieldSet">
<table>
<thead>
<tr>
<th><label>Autorius</label></th>
<th class="c"><label>Antraste</label></th>
<th class="c"><label>Metai</label></th>
<th class="c"><label>Egz skaicius</label></th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="Autor" type="text" class="txtbox2"/></td>
<td><input name="Title" type="text" class="txtbox3"/></td>
<td><input name="Year" type="text" class="txtbox4"/></td>
<td><input name="Amount" type="text" class="txtbox4"/></td>
</tr>
</tbody>
</table>
<p class="l">
<input type="button" value="Remove field" onclick="this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);" />
</p>
</div>
</div>
<p class="r">
<input type="button" onclick="moreFields();" value="Give me more fields!" />
<input type="submit" value="Send form" />
</p>
</div>
</form>
</body>
</html>[/code]


PS: Not decrementing the counter is intentional, as deleting the 2nd of 3 elements would cause a 4th element created thereafter to be named ...3 again.
Copy linkTweet thisAlerts:
@ntk418Jul 19.2009 — Hello, I also have modified it a bit, to make an alternative method.

This method looks different than the template, but I am just assuming that is just what you were going with because of the example. It looks a bit different but uses the table HTML DOM object and it's functions. The link for more info about this (it's really pretty simple) is here.

[CODE]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">

var headerArray = new Array("Author", "Title", "Year", "Amount");

function moreFields() {
howMany = parseInt(document.getElementById('howMany').value);
for (var ii = 0; ii < howMany; ii++) {
dynamicParent = document.getElementById('dynamicParent');
index = dynamicParent.rows.length;
dynamicParent.insertRow(index);
dynamicParent.rows[index].id = 'dynamicParent' + index;
for (var i = 0; i < 5; i++) {
dynamicParent.rows[index].insertCell(i);
if (i < 4) {
textField = document.createElement('input');
textField.type = 'text';
textField.name = headerArray[i] + index;
dynamicParent.rows[index].cells[i].appendChild(textField);
} else {
dynamicParent.rows[index].cells[i].style.cursor = 'pointer';
dynamicParent.rows[index].cells[i].style.textAlign = 'center';
dynamicParent.rows[index].cells[i].style.width = '300px';
dynamicParent.rows[index].cells[i].innerHTML = 'Remove Field';
dynamicParent.rows[index].cells[i].onclick = function() {
if (this.parentNode.parentNode.rows.length > 2) {
this.parentNode.parentNode.removeChild(this.parentNode);
}
}
}
}
}
document.getElementById('howMany').value = '1';
}

</script>

</head>

<body onload="moreFields()">

<form action="test.html" method="post" name="data" id="1">
<table width="200" align="center">
<tr>
<th scope="col"><img src="https://files.getdropbox.com/u/1531805/upbanner.png" width="830" height="130" alt="text" /></th>
</tr>
<tr>
<td>
<table width="829">
<tr>
<td width="135" align='right'><label>Order Date : </label></td>
<td><input name="Order date:" type="text" class="txtbox"/></td>
</tr>
<tr>
<td align='right'><label>Teacher Name : </label></td>
<td><input name="Tname" type="text" class="txtbox" /></td>
</tr>
<tr>
<td align='right'><label>Subject : </label></td>
<td><input name="Subject" type="text" class="txtbox" /></td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table width="974" border="1" cellspacing="1" id="dynamicParent">

<tr>
<td align="center"><label>Author</label></td>
<td align="center"><label>Title</label></td>
<td align="center"><label>Year</label></td>
<td align="center" colspan="2"><label>Amount</label></td>
</tr>

</table>
<td/>
</tr>
<tr height="20">
<td align="right">
<input type='text' id='howMany' value='1' size='2' />
<input type="button" onclick="moreFields()" value="More Field(s)" />
<input type="submit" value="Send Form" />
</td>
</tr>
</table>
</form>

</body>
</html>
[/CODE]
Copy linkTweet thisAlerts:
@AuchiauthorJul 19.2009 — Oh wow, thx for both inputs!

ntk418 that is even better than what I was going for, I will just try to change where the remove button is, maybe remove the span and make it borderless then tweak it with css (havent read the code properly yet so this may not make any sense).

I've came across DOM but I sort of jumped it since I'm still tryin to get the basics of js but i'll definitely look into it now.

Malgrim you've managed to get it to work so Im sure I'll learn something from there, already read the code as I was intrigued but I have to be honest I havent fully understood yet. Some differences in html structure and css I'll eagerly look into as well again.

Thanks again
Copy linkTweet thisAlerts:
@ntk418Jul 19.2009 — Hello, you might have noticed already, but just in case I am going to throw this out there.

I had to remove the <span> element as the way I went about doing it was using the .inertRow() method. In order for this to function, I had to make the 'Remove Field' button a <td> in the added row. With a little bit of tweaking though it should be no problem to make it look however you want. If you need any more help with this let me know, I would be more than happy to give any advice I can.

**EDIT**

The example script I posted should have a problem with the bug mentioned above by Malgrim
Copy linkTweet thisAlerts:
@AuchiauthorJul 20.2009 — No I believe it does not, I have not been able to make it happen yet anyway.

Oh and I didnt meant <span> but <colspan> :S

As far as the html goes I understand it fine, it the index part in the javascript Im finding cool cause I can see it work everywhere except in my head xD

What exacly does this return?
[CODE]index = dynamicParent.rows.length;[/CODE]
This should return the number of rows in the dynamicParent right?

So [CODE]dynamicParent.insertRow(index);[/CODE] inserts a row after (index) and [CODE]dynamicParent.rows[index].id[/CODE] is the id of the row followed by [index]?

Its strange cause it makes sense to add a row after index so when u have insertrow(0) it adds at start but its awkward to call the index of the previous row of the row you actually wanna change id.


Anyway I love how the script is so simple and effective, almost seems easy. I will now try to make the last <td> look like a button, or at least differently. Never tried to change the looks of a single column

Added to that,since the html doesnt even have it (until its created ofc) I guess I'll need some sort of script to add a css rule into all last columns

edit: Ye thinking about it for a while is there any clever way to style that without breaking that loop into 5 if elses? :S
Copy linkTweet thisAlerts:
@ntk418Jul 20.2009 — Yes rows.length returns the current number of rows in the dynamicParent element as an array. But remember, arrays start at value of 0, so if rows.length is equal to 14, the last array element would be [13]. So by using the length as the index, it inserts it as the last element, because [14] did not yet exist, although the length was 14.

*EDIT* Sorry I am finding hard to keep my train of though.

By using .insertRow(index), it does not insert the row after that number, but to that index itself.

The part to change the end column you would just change it to the following (explained under the code):

function moreFields() {
howMany = parseInt(document.getElementById('howMany').value);
for (var ii = 0; ii &lt; howMany; ii++) {
dynamicParent = document.getElementById('dynamicParent');
index = dynamicParent.rows.length;
dynamicParent.insertRow(index);
dynamicParent.rows[index].id = 'dynamicParent' + index;
for (var i = 0; i &lt; 5; i++) {
dynamicParent.rows[index].insertCell(i);
if (i &lt; 4) {
textField = document.createElement('input');
textField.type = 'text';
textField.name = headerArray[i] + index;
dynamicParent.rows[index].cells[i].appendChild(textField);
} else {
dynamicParent.rows[index].cells[i].style.cursor = 'pointer';
dynamicParent.rows[index].cells[i].style.textAlign = 'center';
dynamicParent.rows[index].cells[i].style.width = '300px';
dynamicParent.rows[index].cells[i].innerHTML = 'Remove Field';
[COLOR="Blue"]dynamicParent.rows[index].cells[i].class = 'WHATEVER YOUR BUTTON CLASS IS NAMED';[/COLOR] <br/>
dynamicParent.rows[index].cells[i].onclick = function() {
if (this.parentNode.parentNode.rows.length &gt; 2) {
this.parentNode.parentNode.removeChild(this.parentNode);
}
}
}
}
}
document.getElementById('howMany').value = '1';
}


By adding the above line (the line in blue) to the moreFields() function, it assigns the TD a class when it is created. So you just need to change it the right name, and make sure the class is defined in the css. HTH

<i>
</i>dynamicParent.rows[index].id = 'dynamicParent' + index;


This just basically gives the row an id of 'dynamicParent14' for example. (I think is pointless now, but when I was mocking it up I was trying to use the row id as the identifier of the element to remove when the button is pressed). Now it just uses the .parentNode to remove the row, so assigning each row an id is most likely redundant.

I just read my post and it didn't make a lot of sense to even me :. I know what I'm try to say I just can't get the words out LOL. But if you still need help just let me know.
Copy linkTweet thisAlerts:
@ntk418Jul 20.2009 — Just noticed an error I made in the above post (and there is no edit button, is this because I have already made an edit?).

I said tableName.rows.length returns as an array.

What I mean was tableName.rows.length returns the current array length, and tableName.rows returns an array of each row element.

In regards to your edit about asking a way to style it without using 5 if/else. I'm assuming you mean because you want each <td> to have it's own style? If this is the case (and each td also has the same style as the corresponding one in the other rows) you could just make an array containing the names of each cells class. Then when it is in the for loop to write each <td>, you just do something like:

dynamicParent.rows[index].cells[i].class = classNamesArray[i];

This would give an end result similar to:

<i>
</i> var classNamesArray = new Array('authorClass', 'titleClass', 'yearClass', 'amountClass', 'buttonClass');

<i> </i> function moreFields() {
<i> </i> howMany = parseInt(document.getElementById('howMany').value);
<i> </i> dynamicParent = document.getElementById('dynamicParent');
<i> </i> for (var ii = 0; ii &lt; howMany; ii++) {
<i> </i> index = dynamicParent.rows.length;
<i> </i> dynamicParent.insertRow(index);
<i> </i> for (var i = 0; i &lt; 5; i++) {
<i> </i> dynamicParent.rows[index].insertCell(i);
<i> </i> [COLOR="Blue"]dynamicParent.rows[index].cells[i].class = classNamesArray[i];[/COLOR]
<i> </i> if (i &lt; 4) {
<i> </i> textField = document.createElement('input');
<i> </i> textField.type = 'text';
<i> </i> textField.name = headerArray[i] + index;
<i> </i> dynamicParent.rows[index].cells[i].appendChild(textField);
<i> </i> } else {
<i> </i> dynamicParent.rows[index].cells[i].innerHTML = 'Remove Field';
<i> </i> dynamicParent.rows[index].cells[i].onclick = function() {
<i> </i> if (this.parentNode.parentNode.rows.length &gt; 2) {
<i> </i> this.parentNode.parentNode.removeChild(this.parentNode);
<i> </i> }
<i> </i> }
<i> </i> }
<i> </i> }
<i> </i> }
<i> </i> document.getElementById('howMany').value = '1';
<i> </i> }
Copy linkTweet thisAlerts:
@AuchiauthorJul 21.2009 — Thats brilliant,thanks!

This is strange and funny and the same time, I just stumbled upon my own thread when goggling for the syntax of what I was hoping it would exist, a table.row.class.

I'll try to follow up with the array but it might be a lil bit trickier since I just want to edit 2 of those <td>, but from the top of my head I can at the very worst just have a decoy class to fill in the array in <td> I dont want changed.

And btw u made perfect sense to me,thx again. And assigning each row to it's id will hopefully not be redundant as I will try to catch those values in php and I'll need unique identifiers (well at least in my limited knowledge)
Copy linkTweet thisAlerts:
@AuchiauthorJul 21.2009 — Meh I'm messing up the code for some reason. Kinda disappointing now that I thought I was getting a clue how it worked.

I had to change the code you suggested a bit cause I realized I needed the input fields changed, not the <td> themselfs.

Heres what I have atm, CSS included
[CODE]<style type="text/css">
<!--
body,td,th {
font-family: Verdana, Geneva, sans-serif;
font-size: 12px;
color: #000;
}
.txtbox {
height: 20px;
width: 400px;
text-align: justify;
vertical-align: middle;
}
.txtbox2 {
height: 16px;
width: 400px;
text-align: justify;
vertical-align: middle;
}
.yearClass {
height: 16px;
width: 70px;
text-align: justify;
vertical-align: middle;
}
.authorClass {
height: 16px;
width: 242px;
vertical-align: middle;
}
.titleClass {
height: 16px;
width: 400px;
vertical-align: middle;
}
.amountClass {
height: 16px;
width: 70px;
text-align: center;
vertical-align: middle;
}
.buttonClass{
cursor: pointer;
width: 200px;
text-align: center;

}
.td { border:1px solid
}
-->
</style>
<script type="text/javascript">

var headerArray = new Array("Author", "Title", "Year", "Amount");
var classNamesArray = new Array(authorClass, titleClass, yearClass, amountClass, buttonClass);

function moreFields() {
howMany = parseInt(document.getElementById('howMany').value);
for (var ii = 0; ii < howMany; ii++) {
dynamicParent = document.getElementById('dynamicParent');
index = dynamicParent.rows.length;
dynamicParent.insertRow(index);
dynamicParent.rows[index].id = 'dynamicParent' + index;
for (var i = 0; i < 5; i++) {
dynamicParent.rows[index].insertCell(i);
<!--dynamicParent.rows[index].cells[i].className = classNamesArray[i];
if (i < 4) {
textField = document.createElement('input');
textField.type = 'text';
textField.name = headerArray[i] + index;
dynamicParent.rows[index].cells[i].appendChild(textField);
[COLOR="RoyalBlue"]textfield.className = classNamesArray[i];[/COLOR]
} else {
<!--dynamicParent.rows[index].cells[i].style.cursor = 'pointer' -->
<!--dynamicParent.rows[index].cells[i].style.textAlign = 'center'; -->
<!--dynamicParent.rows[index].cells[i].style.width = '200px'; -->
[COLOR="RoyalBlue"]dynamicParent.rows[index].cells[i].className = buttonClass;[/COLOR]
dynamicParent.rows[index].cells[i].innerHTML = 'Remove Field';
dynamicParent.rows[index].cells[i].onclick = function() {
if (this.parentNode.parentNode.rows.length > 2) {
this.parentNode.parentNode.removeChild(this.parentNode);
}
}
}
}
}
document.getElementById('howMany').value = '1';
}

</script>
</head>

<body onload="moreFields()">
<?php
include ('config.php');
if (!isset($_POST['submit'])) {
?>
<form action="form.php" method="post" name="data" id="1">
<table width="200" align="center">
<tr>
<th scope="col"><img src="https://files.getdropbox.com/u/1531805/upbanner.png" alt="text" /></th>
</tr>
<tr>
<td>
<table width="974">
<tr>
<td width="135" align='right'><label>Order Date : </label></td>
<td><input name="Order date:" type="text" class="txtbox"/></td>
</tr>
<tr>
<td align='right'><label>Teacher Name : </label></td>
<td><input name="Tname" type="text" class="txtbox" /></td>
</tr>
<tr>
<td align='right'><label>Subject : </label></td>
<td><input name="Subject" type="text" class="txtbox" /></td>
</tr>
</table>
<br>
</td>
</tr>
<tr>
<td>
<table width="974" border="0px" cellspacing="1" id="dynamicParent">

<tr>
<td align="center" class="td authorClass"><label>Author</label></td>
<td align="center" class="td titleClass" ><label>Title</label></td>
<td class="td amountClass" ><label>Year</label></td>
<td class="td amountClass" ><label>Amount</label></td>
<td></td>
</tr>

</table>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td style="width:800px" align="right"><input type='text' id='howMany' value='1' size='2' />
<input type="button" onclick="moreFields()" value="More Field(s)" />
<input type="submit" value="Send" /></td>
<td></td>
</tr>
</table>
</td>
</tr>
</table>
</form>


</body>
</html>[/CODE]


The result can be seen here

I kept some commented code, some stuff I tried before.

Its interesting how it fails the same way assigning a class to either a <td> or an input field, breaking the .insertcell() cycle for some reason :S

I've been going around this for a while and I cant seem to figure why
Copy linkTweet thisAlerts:
@ntk418Jul 21.2009 — <i>
</i>var classNamesArray = new Array(authorClass, titleClass, yearClass, amountClass, buttonClass);


The class names need to be strings, as they are now it is trying to add JS vars to an array (vars that have not been created, this should throw an error?)

Change the entries to strings by adding '' around them, should give the following:

<i>
</i>var classNamesArray = new Array('authorClass', 'titleClass', 'yearClass', 'amountClass', 'buttonClass');


[CODE]
function moreFields() {
howMany = parseInt(document.getElementById('howMany').value);
for (var ii = 0; ii < howMany; ii++) {
dynamicParent = document.getElementById('dynamicParent');
index = dynamicParent.rows.length [COLOR="Lime"]// Returns the current ammount of rows in the dynamicParent table[/COLOR];
dynamicParent.insertRow(index); [COLOR="Lime"]// This creates a row at the specified index (index) in the dynamicParent table, which is currently non-existant[/COLOR]
[COLOR="Red"]dynamicParent.rows[index].id = 'dynamicParent' + index;[/color] [COLOR="Lime"]// This line can be removed[/COLOR]
for (var i = 0; i < 5; i++) {
dynamicParent.rows[index].insertCell(i); [COLOR="Lime"]// This creates a new <td> at the specified index (i) of current row (index) of the dynamicParent table.[/COLOR]
[COLOR="Red"]<!--dynamicParent.rows[index].cells[i].className = classNamesArray[i];[/color] [COLOR="Lime"]// This can be removed[/COLOR]

if (i < 4) {[COLOR="Lime"] // If this <td> holds a <input type='text' />[/COLOR]
textField = document.createElement('input'); [COLOR="Lime"]// Creates the input for each <td>[/COLOR]
textField.type = 'text'; [COLOR="Lime"]// Sets the input as type='text', making similar to: <input type='text' /> to place inside each <td>[/COLOR]
textField.name = headerArray[i] + index;
[COLOR="Blue"]textField.className = classNamesArray[i];[/COLOR][COLOR="Lime"] // This gives the text field a class[/COLOR]
dynamicParent.rows[index].cells[i].appendChild(textField); [COLOR="Lime"]// Places the <input type='text' /> created above into the <td>[/COLOR]
} else { [COLOR="Lime"]// else it must be the 'Remove Field' <td>[/COLOR]
[COLOR="Red"]<!--dynamicParent.rows[index].cells[i].style.cursor = 'pointer' -->
<!--dynamicParent.rows[index].cells[i].style.textAlign = 'center'; -->
<!--dynamicParent.rows[index].cells[i].style.width = '200px'; -->[/color] [COLOR="Lime"]// These can be removed, you should take care of the styling of this <td> (the Remove Field) in the css declarations[/COLOR]
[COLOR="Red"]dynamicParent.rows[index].cells[i].className = buttonClass;[/color][COLOR="Lime"] // This line should be changed to the blue line below[/COLOR]
[COLOR="Blue"]dynamicParent.rows[index].cells[i].className = 'buttonClass';[/color][COLOR="Lime"] // Notice the '' around buttonClass which makes it a string[/COLOR]
dynamicParent.rows[index].cells[i].innerHTML = 'Remove Field'; [COLOR="Lime"] // Sets the innerHTML of the last <td> to say 'Remove Field' as to imitate a button [/COLOR]
dynamicParent.rows[index].cells[i].onclick = function() { [COLOR="Lime"]// This tells the browser what to do when the last <td> is clicked, also part of the button simulation[/COLOR]
if (this.parentNode.parentNode.rows.length > 2) { [COLOR="Lime"]// This just makes it so you cannot remove the last row[/COLOR]
this.parentNode.parentNode.removeChild(this.parentNode);
}
}
}
}
}
document.getElementById('howMany').value = '1';
}[/CODE]


Removing the red lines, and adding the blue lines above should take care of the problem.

If you do all of the above it should give this:
<i>
</i> function moreFields() {
howMany = parseInt(document.getElementById('howMany').value);
for (var ii = 0; ii &lt; howMany; ii++) {
dynamicParent = document.getElementById('dynamicParent');
index = dynamicParent.rows.length;
dynamicParent.insertRow(index);
for (var i = 0; i &lt; 5; i++) {
dynamicParent.rows[index].insertCell(i);
if (i &lt; 4) {
textField = document.createElement('input');
textField.type = 'text';
textField.name = headerArray[i] + index;
textField.className = classNamesArray[i];
dynamicParent.rows[index].cells[i].appendChild(textField);
} else {
dynamicParent.rows[index].cells[i].className = 'buttonClass';
dynamicParent.rows[index].cells[i].innerHTML = 'Remove Field'; <br/>
dynamicParent.rows[index].cells[i].onclick = function() {
if (this.parentNode.parentNode.rows.length &gt; 2) {
this.parentNode.parentNode.removeChild(this.parentNode);
}
}
}
}
}
document.getElementById('howMany').value = '1';
}
Copy linkTweet thisAlerts:
@ntk418Jul 21.2009 — I think I understand what you mean by trying to catch each row in php. However, you will be needing to catch the input fields, so the row having an id isn't going to help. Maybe ad a hidden input to the form that contains the number of rows and is updated everytime moreFields() is called, or the 'Remove Field' <td> is clicked, then catch that input in php so you know how many fields the user has added. For instance:

[code=php]
$numFields = $_POST['numFields'];
$author = new Array();
$title = new Array();
$year = new Array();
$amount = new Array();
for ($i = 1; $i <= $numFields; $i++) {
$author[$author.length] = $_POST['Author' . $i];
$title[$title.length] = $_POST['Title' . $i];
$year[$year.length] = $_POST['Year' . $i];
$amount[$amount.length] = $_POST['Amount' . $i];
}
[/code]


That is just a rough example, but it should get the idea across.

Of course this would cause a problem with naming, with the bug that Malgrim mentioned. Maybe there is a better way of iterating through the $_POST elements. Maybe something like:

I'm going to look into it some and post back about what I find, becuase now I'm wondering about that.
Copy linkTweet thisAlerts:
@AuchiauthorJul 21.2009 — Man you sure are being patient on me.

I had understood all the code but it sure is reassuring a double check,thanks for the work.

I have removed the strings because table.row.class was failing me so I checked at w3schools that DOM article you mentioned and that was how they had it.

I will change it asap.

About catching the inputs I jumped ahead of myself, I noticed each input had its name from the array+id and miss interpreted you :S

I had gone ahead with a script for cycling the rows while validating them but at the time I was using fixed number of rows. Keeping a counter on the number of rows by adding with moreField() and removing with function() sounds like the most obvious approach, I'll sleep over it.


Edit : Fully functional!

Added to the array not having "" around the css classes I had a typo on [CODE]textfield.className = classNamesArray[i];[/CODE] where the "f" of field should be "F". It was silly of me having a array right above this new one and not noticing the difference between ", ' and nothing at all :s

On to some client validation and a row counter
Copy linkTweet thisAlerts:
@ntk418Jul 21.2009 — Glad you got it working ?
Copy linkTweet thisAlerts:
@AuchiauthorJul 22.2009 — Glad you helped me o/
×

Success!

Help @Auchi spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 6.2,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @meenaratha,
tipped: article
amount: 1000 SATS,

tipper: @meenaratha,
tipped: article
amount: 1000 SATS,

tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,
)...