First off, what is your question? Are you getting an error? What results you are getting now - and how do they differ from what you expected?
Without knowing more about your form/data structure, I usually recommend using unique form field names in this case. When you use the same name for multiple fields, the field values are submitted as a comma delimited list. That can cause problems when the value itself contains a comma, because there is no way to determine where one value ends and the other begins.
To create unique field names, have your javascript append a counter number to each set of fields. So the fields will be named:
- FORM.GrandNum1, FORM.GrandNme1, FORM.sectCode1, FORM.txtComments1, ...
- FORM.GrandNum2, FORM.GrandNme2, FORM.sectCode2, FORM.txtComments2, ...
- FORM.GrandNum3, FORM.GrandNme3, FORM.sectCode3, FORM.txtComments3,...`
Then store the total number in a hidden field. On your action page, do a simple from/to loop. If needed, use cfparam
to set a default value for any fields that might not exist like checkboxes or radio buttons (text fields always exist). Then you can use null
attribute of cfqueryparam
which is a bit cleaner than isDefined
or structKeyExists
IMO.
<cfparam name="FORM.totalFields" default="0">
<cfloop from="1" to="#FORM.totalFields#" index="i">
<!--- extract current set of values --->
<cfset variables.txtComments = TRIM( FORM["txtComments"& i] )>
<cfset variables.sectCode = TRIM( FORM["sectCode"& i] )>
...
<cfquery name="AppendForm" datasource="TestSource">
INSERT INTO tblGrand (Comments, SectCode ....)
VALUES
(
<cfqueryparam cfsqltype="cf_sql_varchar" value="#variables.txtComments#" null="#not len(variables.txtComments)#">
, <cfqueryparam cfsqltype="cf_sql_varchar" value="#variables.sectCode#" null="#not len(variables.sectCode)#">
...
)
</cfquery>
</cfloop>
UPDATE:
Based on your updates, your existing code is very close to what I originally described above. You just need to add the hidden field, and update it each time you add a row. Then the cfloop code above should work just fine.
function addRow() {
// removed extra variables
var tbl = document.getElementById('tblSample');
var row = tbl.insertRow(tbl.rows.length);
// use hidden value to calculate total fields
var iteration = parseInt(document.getElementById('totalFields').value) + 1;
var cellLeft = row.insertCell(0);
var textNode = document.createTextNode(iteration);
... etcetera ...
// save new total
document.getElementById('totalFields').value = iteration;
}
...
<input type="hidden" id="totalFields" name="totalFields" value="0" />
UPDATE:
A few other comments
- There is no need for
cfoutput
around the query loop. The variables will be evaluated automatically - Always use
cfqueryparam
when processing user supplied values to prevent sql injection. Especially when looping.cfqueryparam
uses bind variables which can "enhance performance when executing a cfquery statement multiple times." - Do not use
DateFormat
in queries. It is designed for presentation and returns a string. Date strings can be misinterpreted depending on your database settings. To avoid ambiguity always insert date/time objects ie likenow()
and not strings. See Matt's example and his usage ofnow()
.