...

View Full Version : Processing dynamically added table rows



oyster_genetics
08-22-2007, 06:12 PM
I have a ColdFusion form that uses javascript to dynamically add rows to a table. This works great, but I can't figure out how to process the rows when the form is submitted. It seems that somehow, I need to grab the length of the table and pass it to the form (post_my_rows.cfm) that will handle the processing. If there is a better way to do this, I'd appreciate the direction. Here's the code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/JavaScript">
function addRow(r){
var root = r.parentNode;//the root
var allRows = root.getElementsByTagName('tr');//the rows' collection
var cRow = allRows[0].cloneNode(true)//the clone of the 1st row
var cInp = cRow.getElementsByTagName('input');//the inputs' collection of the 1st row
for(var i=0;i<cInp.length;i++){//changes the inputs' names (indexes the names)
cInp[i].setAttribute('name',cInp[0].getAttribute('name')+'_'+(allRows.length+1))
}
var cSel = cRow.getElementsByTagName('select')[0];
cSel.setAttribute('name',cSel.getAttribute('name')+'_'+(allRows.length+1));//change the selecet's name
root.appendChild(cRow);//appends the cloned row as a new row
}
function shownames(){
var allInp=document.getElementsByTagName('input');
for(var i=0;i<allInp.length;i++){
alert(allInp[i].name)
}
}
function delRow()
{
var tbl = document.getElementById('tblSample');
var lastRow = tbl.rows.length;
if (lastRow > 2) tbl.deleteRow(lastRow - 1);

}
</script>
</head>
<body>

<cfquery name="filter_copi" datasource="OSP">
SELECT principal_investigator.PI_lname+','+principal_investigator.PI_fname+','+ principal_investigator.PI_minitial+','+department.dept_name as thename,
department.dept_name as dept_name,
pi_dept.pi_id as pi_id,
pi_dept.dept_id as dept_id,
pi_dept.pi_and_dept as pi_dept
FROM department, principal_investigator, pi_dept
where principal_investigator.pi_id = pi_dept.pi_id
and department.dept_ID = PI_Dept.dept_ID
order by department.dept_name, principal_investigator.PI_lname+','+principal_investigator.PI_fname+','+ principal_investigator.PI_minitial;
</cfquery>

<form action="post_my_rows.cfm" method="get">
<cfoutput>
<!--- Gets the value of getnumba from above --->
</cfoutput>
<table id="tblsample" width="766" border="0" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>Co_pi</th>
<th>&nbsp;</th>
<th>Direct</th>
<th>year</th>
<th>&nbsp;</th>
</tr>
</thead>


<tr>


<td width="98"><select name="select">
<option value="item1" selected="selected">item1</option>
<cfoutput query="filter_copi">
<option value="#pi_dept#">#thename#</option>
</cfoutput>
</select></td>
<td width="286">&nbsp;</td>
<td width="286"><input type="text" name="textfield_a" /></td>
<td width="286"><input type="text" name="textfield_b" /></td>
<td width="286"><input name="button22" type="button" onClick="delRow()" value= "Remove" />
<input name="button2" type="button" value="+" onClick="addRow(this.parentNode.parentNode)"></td>
</tr>
</table>
<br />
<input name="Input" type="submit" value="Submit" />
<input name="button" type="button" onclick="shownames()" value="Show names">
<input name="button3" type="button"
onClick="alert(document.getElementById('tblsample').rows.length);" value="Count Table Rows">
</form>
</body>
</html>

nikkiH
08-22-2007, 06:57 PM
You could just loop through the Request.Form collection on the server side.
Here is an example of such a loop.
http://www.bennadel.com/blog/377-Posting-Form-Values-With-The-ColdFusion-CFHttp-And-CFHttpParam-Tags.htm

mcjwb
08-22-2007, 07:54 PM
Looks to me like there is a mistake in your code, I suspect this line:

cInp[i].setAttribute('name',cInp[0].getAttribute('name')+'_'+(allRows.length+1))
should be:

cInp[i].setAttribute('name',cInp[i].getAttribute('name')+'_'+(allRows.length+1))

Does that help?

There is an alternative method, you could use html arrays which are created by adding square brackets, [], to an input's name. This might make processing the form easier.
e.g.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/JavaScript">
function addRow(r){
var root = r.parentNode;//the root
var allRows = root.getElementsByTagName('tr');//the rows' collection
var cRow = allRows[0].cloneNode(true)//the clone of the 1st row
var cInp = cRow.getElementsByTagName('input');//the inputs' collection of the 1st row
root.appendChild(cRow);//appends the cloned row as a new row
}
function shownames(){
var allInp=document.getElementsByTagName('input');
for(var i=0;i<allInp.length;i++){
alert(allInp[i].name)
}
}
function delRow()
{
var tbl = document.getElementById('tblSample');
var lastRow = tbl.rows.length;
if (lastRow > 2) tbl.deleteRow(lastRow - 1);
}
</script>
</head>
<body>
<cfquery name="filter_copi" datasource="OSP">
SELECT principal_investigator.PI_lname+','+principal_investigator.PI_fname+','+ principal_investigator.PI_minitial+','+department.dept_name as thename,
department.dept_name as dept_name,
pi_dept.pi_id as pi_id,
pi_dept.dept_id as dept_id,
pi_dept.pi_and_dept as pi_dept
FROM department, principal_investigator, pi_dept
where principal_investigator.pi_id = pi_dept.pi_id
and department.dept_ID = PI_Dept.dept_ID
order by department.dept_name, principal_investigator.PI_lname+','+principal_investigator.PI_fname+','+ principal_investigator.PI_minitial;
</cfquery>
<form action="form_test.php" method="get">
<cfoutput>
<!--- Gets the value of getnumba from above --->
</cfoutput>
<table id="tblsample" width="766" border="0" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>Co_pi</th>
<th>&nbsp;</th>
<th>Direct</th>
<th>year</th>
<th>&nbsp;</th>
</tr>
</thead>

<tr>

<td width="98"><select name="select[]">
<option value="item1" selected="selected">item1</option>
<cfoutput query="filter_copi">
<option value="#pi_dept#">#thename#</option>
</cfoutput>
</select></td>
<td width="286">&nbsp;</td>
<td width="286"><input type="text" name="textfield_a[]" /></td>
<td width="286"><input type="text" name="textfield_b[]" /></td>
<td width="286"><input name="button22" type="button" onClick="delRow()" value= "Remove" />
<input name="button2" type="button" value="+" onClick="addRow(this.parentNode.parentNode)"></td>
</tr>
</table>
<br />
<input name="Input" type="submit" value="Submit" />
<input name="button" type="button" onclick="shownames()" value="Show names">
<input name="button3" type="button"
onClick="alert(document.getElementById('tblsample').rows.length);" value="Count Table Rows">
</form>
</body>
</html>
This would produce a GET/Request array as follows:

Array
(
[select] => Array
(
[0] => item1
[1] => item1
)

[textfield_a] => Array
(
[0] => 1a
[1] => 2a
)

[textfield_b] => Array
(
[0] => 1b
[1] => 2b
)

[Input] => Submit
)


This means you effectively have 3 arrays, select, textfield_a and textfield_b. You can then count the items in each array, make sure they all have the same number then go round a loop and process the same position in each array each time.
e.g.


//psudo code:
message="";
for(i=0; i<2; i++){
message+= select[i]+" "+textfield_a[i]+" "+textfield_b[i]+"\r\n";
}



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum