View Full Version : Remove dynamically generated fields

Mar 28th, 2007, 06:18 PM
Hi again.

This is a group registration form. The user can add rows of fields incrementally. Each field has incremental ID in the format (name + i).


I need to permit the user to remove the last row repeatedly until they are at (name + 0), just as they can generate rows repeatedly until the rows are at max.

My code isn't working, it generates a type mismatch Javascript error, and I just don't know what that means exactly.

var sumAttend is a global that tracks the number of registrants. My fields start with 0 (regisname0, regisemail0, registour0).

ID groupreg is the fieldset ID.

function removeRegistrant() {
alert("There are " + document.regisform.length + " fields in this form. This information is for testing purposes.")
document.getElementById('addregbutton').disabled = false;
var groupreg = document.getElementById('groupreg');
var lastrowname = 'regisname' + sumAttend;
var lastrowemail = 'regisemail' + sumAttend;
var lastrowtour = 'registour' + sumAttend;
while (groupreg.getElementsByTagName('br') > 0) {
var brs = groupreg.getElementsByTagName('br');
lastbr = (groupreg.getElementsByTagName('br').length) - 1;

The type mismatch error points to this line:


I also need to remove the last <br> tag, that is also generated by the add-a-row function. That part isn't working, either. I'm trying to get an array of <br>s in id=groupreg and remove the last one.

If someone can put me on the right track for proper syntax to remove a field whose id string is determined by another variable, I can get my logic sorted out.

Thanks in advance, you guys have helped me a LOT! I couldn't have gotten this far otherwise.


Mar 28th, 2007, 08:13 PM
removeChild function does not take in a string...it takes in an element. plus u can only remove the immediate child of a particular element

- table
-- tr
--- td
---- input
to remove the input element u've to call removeChild on the td not on the fieldset

Mar 28th, 2007, 10:27 PM
Thanks, Shyam!

You got me looking more closely at my Javascript reference books, and trying to understand the method/objects thing: not all methods apply to all objects, something like that. I took a better look at the parentNode/childNode thing. The created elements, by the way, are children of parentNode groupreg, not the table, they are not being created inside a table (for simplicity.)

Heh. I started replying to you here 4 times, and each time I looked at my code, saw something that made me go "Hmm," went back and tried something else... and... OMG I did it! THIS WORKS! (notice all the alerts showing me variable values, that helps on debugging!)

function removeRegistrant() {
if (rowCount > 0) {
alert("There are " + document.regisform.length + " fields in this form.
var rowCount =" + (rowCount));
document.getElementById('addregbutton').disabled = false;
var groupreg = document.getElementById('groupreg');
var lastrowname = 'regisname' + rowCount;
var lastrowemail = 'regisemail' + rowCount;
var lastrowtour = 'registour' + rowCount;
lastrowname = document.getElementById(lastrowname);
lastrowemail = document.getElementById(lastrowemail);
lastrowtour = document.getElementById(lastrowtour);
if (groupreg.getElementsByTagName('br') != null) {
var brs = groupreg.getElementsByTagName('br');
lastbr = (brs.length) - 1;
alert("number of <br> tags in groupreg: " + brs.length);
} else {
document.getElementById('remregbutton').disabled = true;
alert("At the end of removeRegistrant, there are " + document.regisform.length
+ " fields in this form. var rowCount =" + (rowCount));

ME HAPPY!!! woohoo! Real progress.

Not done yet, but getting there.


Mar 29th, 2007, 12:53 PM
way to go Opally :D

Mar 29th, 2007, 03:10 PM
As your form elements (in the added/removed) rows are not radio buttons or checkboxes (case in which IE produces some problems) you may have used the cloneNode(true) method to clone a row, then change the ids and names and then append the row. Keep in mind that a row must be appended to the TBODY, as the TBODY is required in javascript. But the TBODY is the parentNode of any row.

The remove process should be extremely simple:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<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">
maxNum = 20;
function addRegistrant(){
var allRows=document.getElementById('addregistrants').getElementsByTagName('tr');
var clone=allRows[1].cloneNode(true);
var allInp=clone.getElementsByTagName('input');
for(var i=allInp.length-1;i>=0;i--){
var sel = clone.getElementsByTagName('select')[0];
function removeRegistrant(){
var allRows=document.getElementById('addregistrants').getElementsByTagName('tr');
<form action="">
<table cellpadding="0" cellspacing="0" border="0" id="addregistrants">
<th>Email address </th>
<th>Tour selection </th>
<td><input name="regisname0" type="text" id="regisname0"></td>
<td><input name="regisemail0" id="regisemail0" type="text"></td>
<td><select name="registour0" id="registour0" size="1">
<option value="0" selected>Select Tour?</option>
<option value="tour1">Tour 1</option>
<option value="tour2">Tour 2</option>
<option value="tour3">Tour 3</option>
<td><input type="button" onclick="addRegistrant()" value="Add a registrant" id="addregbutton"></input></td>
<td><input name="button" type="button" id="remregbutton" onClick="removeRegistrant()" value="Delete last row"></td>

Mar 30th, 2007, 12:12 AM
wow, I'd need a commentary to understand that code. I'm just a coding-and-javascript newbie!

I realized I have a new problem, probably not to be solved here: when the user uses the back button (or window.history.back(-1)) to modify his form, the dynamically generated form fields are lost. That's going to annoy someone who spent a lot of time filling in fields.

Y'think I need to learn to write a session cookie, and pass data between the form and the CGI processor that way?