PDA

View Full Version : Remove dynamically generated fields



Opally
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).

https://www.coreknowledge.org/secure/html_forms/confregform.htm

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;
groupreg.removeChild(lastrowname);
groupreg.removeChild(lastrowemail);
groupreg.removeChild(lastrowrtour);
while (groupreg.getElementsByTagName('br') > 0) {
var brs = groupreg.getElementsByTagName('br');
lastbr = (groupreg.getElementsByTagName('br').length) - 1;
groupreg.removeChild(brs[lastbr]);
}
}

The type mismatch error points to this line:

groupreg.removeChild(lastrowname);

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.

---Opally

shyam
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


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

Opally
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);
lastrowname.parentNode.removeChild(lastrowname);
lastrowemail.parentNode.removeChild(lastrowemail);
lastrowtour.parentNode.removeChild(lastrowtour);
if (groupreg.getElementsByTagName('br') != null) {
var brs = groupreg.getElementsByTagName('br');
lastbr = (brs.length) - 1;
alert("number of <br> tags in groupreg: " + brs.length);
brs[lastbr].parentNode.removeChild(brs[lastbr]);
}
--rowCount;
} 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.

---Opally

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

Kor
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">
<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">
maxNum = 20;
function addRegistrant(){
var allRows=document.getElementById('addregistrants').getElementsByTagName('tr');
if(allRows.length<(maxNum+1)){
var clone=allRows[1].cloneNode(true);
var allInp=clone.getElementsByTagName('input');
for(var i=allInp.length-1;i>=0;i--){
if(allInp[i].type=='button'){
allInp[i].parentNode.removeChild(allInp[i])
}
else{
allInp[i].name=allInp[i].name.replace(/0/g,allRows.length-1);
allInp[i].id=allInp[i].id.replace(/0/g,allRows.length-1);
allInp[i].value='';
}
}
var sel = clone.getElementsByTagName('select')[0];
sel.name=sel.name.replace(/0/g,allRows.length-1);
sel.id=sel.id.replace(/0/g,allRows.length-1);
sel.options[0].selected=true;
allRows[0].parentNode.appendChild(clone)
}
}
function removeRegistrant(){
var allRows=document.getElementById('addregistrants').getElementsByTagName('tr');
if(allRows.length>2){
allRows[0].parentNode.removeChild(allRows[allRows.length-1])
}
}
</script>
</head>
<body>
<form action="">
<table cellpadding="0" cellspacing="0" border="0" id="addregistrants">
<tr>
<th>Name</th>
<th>Email address </th>
<th>Tour selection </th>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<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>
</select></td>
<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>
</tr>
</table>
</form>
</body>
</html>

Opally
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?

---Opally