PDA

View Full Version : Dynamic Add Form in Table



joedirty99504
03-29-2013, 07:57 PM
Several years ago, I was good with Javascript - now I am very rusty. I need to make a web form. I would like to keep all of the code for this form on a single page (ie. no .js files) (minus the eventual e-mail processing script of course). When someone chooses the "Number of Files to Attach", I want the page to dynamically create the "Document #:" text and corresponding 2-row table form.

Each three-line document form would need unique field names.

As you can see, I already have a script to populate a drop-down list after a first drop-down list's choice is selected. I would like this feature to work for however many documents are added.

I would greatly appreciate any help you can provide. I am unsure what further info is needed, but would be more than happy to answer further questions. Thank you!!!



<html>
<head>
<title>Car Design</title>
</head>
<!-- Second part of the dilemma: how to use this script if there are multiple documents -->
<script type="text/javascript">
function configureDropDownLists(ddl1,doc1_sys) {
var e1 = new Array('Bilge & Ballast (BL)', 'Boiler (B)', 'Vents & Sounds (V)', 'Other (GENR)');
var e2 = new Array('One Line Diagram (ONE)', 'Sound Powered Phone (SPP)', 'Other (GENR)');
var h1 = new Array('Damage Stability (DAM)', 'Intact Stability (INT)', 'Lightship (LTSH)', 'Other (GENR)');
switch (ddl1.value) {
case 'E1':
document.getElementById(doc1_sys).options.length = 0;
for (i = 0; i < e1.length; i++) {
createOption(document.getElementById(doc1_sys), e1[i], e1[i]);
}
break;
case 'E2':
document.getElementById(doc1_sys).options.length = 0;
for (i = 0; i < e2.length; i++) {
createOption(document.getElementById(doc1_sys), e2[i], e2[i]);
}
break;
case 'H1':
document.getElementById(doc1_sys).options.length = 0;
for (i = 0; i < h1.length; i++) {
createOption(document.getElementById(doc1_sys), h1[i], h1[i]);
}
break;
default:
document.getElementById(doc1_sys).options.length = 0;
break;
}
}
function createOption(ddl, text, value) {
var opt = document.createElement('option');
opt.value = value;
opt.text = text;
ddl.options.add(opt);
}
</script>
<form name="car" action="html_form_action.asp" method="get">
Submissions:<br>
Number of Files to Attach: <select name="numberoffiles">
<option value="0">0</option>
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option></select> Expedite? <input type="radio" name="nvic" value="Yes">Yes <input type="radio" name="nvic" value="No" checked>No
<br>
<!-- From here to the below comment is what needs to be dynamically added with each "number of files to attach" -->
Document 1:<br>
<table>
<tr>
<td>Name:</td>
<td><input type="text" size="60" name="doc1_name"></td>
<td><input type="file" name="doc1_file" size="72" allow="text"></td>
</tr>
<tr>
<td>Number:</td>
<td><input type="text" name="doc1_number"> Rev.: <input type="text" size="2" maxlength="2" name="doc1_rev"> Type: <select name="doc1_type">
<option value="Letter">Letter</option>
<option value="Manual">Manual</option>
<option value="Plans">Plans</option></select></td>
<td>Branch: <select id="ddl" onchange="configureDropDownLists(this,'doc1_sys')">
<option value=""></option>
<option value="E2">Electrical</option>
<option value="H1">Hull & Stability</option>
<option value="E1">Machinery & Piping</option>
</select>
System:
<select id="doc1_sys">
</select></td>
</tr>
</table>
<!-- End of what needs to be dynamically added with each "number of files to attach" -->
<br>
<br>
<input type="reset" value="Clear">
<input type="submit" value="Submit">
</form>
</body>
</html>

jscheuer1
03-31-2013, 06:40 AM
I don't think you want to add a form in a table, it looks to me that you want to add a table with additional form elements in in it to an existing form.

Anyways, this works pretty well for that:


<html>
<head>
<title>Car Design</title>
</head>
<!-- Second part of the dilemma: how to use this script if there are multiple documents -->
<script type="text/javascript">
function configureDropDownLists(ddl, doc_sys) {
doc_sys = document.getElementsByName('doc' + doc_sys + '_sys')[0];
var e1 = new Array('Bilge & Ballast (BL)', 'Boiler (B)', 'Vents & Sounds (V)', 'Other (GENR)');
var e2 = new Array('One Line Diagram (ONE)', 'Sound Powered Phone (SPP)', 'Other (GENR)');
var h1 = new Array('Damage Stability (DAM)', 'Intact Stability (INT)', 'Lightship (LTSH)', 'Other (GENR)');
switch (ddl.value) {
case 'E1':
doc_sys.options.length = 0;
for (i = 0; i < e1.length; i++) {
createOption(doc_sys, e1[i], e1[i]);
}
break;
case 'E2':
doc_sys.options.length = 0;
for (i = 0; i < e2.length; i++) {
createOption(doc_sys, e2[i], e2[i]);
}
break;
case 'H1':
doc_sys.options.length = 0;
for (i = 0; i < h1.length; i++) {
createOption(doc_sys, h1[i], h1[i]);
}
break;
default:
doc_sys.options.length = 0;
break;
}
}
function createOption(ddl, text, value) {
var opt = document.createElement('option');
opt.value = value;
opt.text = text;
ddl.options.add(opt);
}
function adddocs(num){
adddocs.docs = adddocs.docs || [document.getElementById('doc1')];
var numdocs = adddocs.docs.length, newdoc, lastdoc, needed, newname, newfile, oldfile, newnum, newrev, newtype, newbranch, newsys;
if(num == 0){num = 1;}
if(num < numdocs){
while(numdocs-- > num){
adddocs.docs[numdocs].parentNode.removeChild(adddocs.docs[numdocs]);
adddocs.docs.splice(numdocs, 1);
}
} else if (num > numdocs) {
needed = num - numdocs;
while(--needed > -1){
newdoc = adddocs.docs[0].cloneNode(true);
adddocs.docs.push(newdoc);
numdocs = adddocs.docs.length;
newdoc.id = 'doc' + numdocs;
newdoc.firstChild.nodeValue = 'Document ' + numdocs;
(lastdoc = adddocs.docs[numdocs - 2]).parentNode.insertBefore(newdoc, lastdoc.nextSibling);
(newname = document.getElementsByName('doc1_name')[1]).value = '';
newname.name = 'doc' + numdocs + '_name';
newfile = document.createElement('input');
newfile.type = 'file';
oldfile = document.getElementsByName('doc1_file')[1];
newfile.name = 'doc' + numdocs + '_file';
newfile.setAttribute('allow', oldfile.getAttribute('allow'), 0);
newfile.size = oldfile.size;
oldfile.parentNode.replaceChild(newfile, oldfile);
(newnum = document.getElementsByName('doc1_number')[1]).name = 'doc' + numdocs + '_number';
newnum.value = '';
(newrev = document.getElementsByName('doc1_rev')[1]).name = 'doc' + numdocs + '_rev';
newrev.value = '';
(newtype = document.getElementsByName('doc1_type')[1]).name = 'doc' + numdocs + '_type';
newtype.options.selectedIndex = 0;
(newbranch = document.getElementsByName('ddl1')[1]).name = 'ddl' + numdocs;
newbranch.onchange = function(){};
newbranch.options.selectedIndex = 0;
newbranch.onchange = (function(newbranch, numdocs){
return function(){
configureDropDownLists(newbranch, numdocs);
};
})(newbranch, numdocs);
(newsys = document.getElementsByName('doc1_sys')[1]).name = 'doc' + numdocs + '_sys';
newsys.options.length = 0;
}
}
}
function resetassist(){
adddocs(1);
document.getElementsByName('doc1_sys')[0].options.length = 0;
}
</script>
<form name="car" action="html_form_action.asp" method="get">
Submissions:<br>
Number of Files to Attach: <select name="numberoffiles" onchange="adddocs(this.value);">
<option value="0">0</option>
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option></select> Expedite? <input type="radio" name="nvic" value="Yes">Yes <input type="radio" name="nvic" value="No" checked>No
<br>
<!-- From here to the below comment is what needs to be dynamically added with each "number of files to attach" -->
<div id="doc1">Document 1:<br>
<table>
<tr>
<td>Name:</td>
<td><input type="text" size="60" name="doc1_name"></td>
<td><input type="file" name="doc1_file" size="72" allow="text"></td>
</tr>
<tr>
<td>Number:</td>
<td><input type="text" name="doc1_number"> Rev.: <input type="text" size="2" maxlength="2" name="doc1_rev"> Type: <select name="doc1_type">
<option value="Letter">Letter</option>
<option value="Manual">Manual</option>
<option value="Plans">Plans</option></select></td>
<td>Branch: <select name="ddl1" onchange="configureDropDownLists(this, 1)">
<option value=""></option>
<option value="E2">Electrical</option>
<option value="H1">Hull & Stability</option>
<option value="E1">Machinery & Piping</option>
</select>
System:
<select name="doc1_sys">
</select></td>
</tr>
</table>
<br>
</div>
<!-- End of what needs to be dynamically added with each "number of files to attach" -->
<br>
<input type="reset" value="Clear" onclick="resetassist(); return true;">
<input type="submit" value="Submit">
</form>
</body>
</html>

I changed the two id assignments to name assignments because it seemed easier to work with that way, and you will need those names on the receiving page in order for it to GET the values.

Everything is incremented and the select population function works for each created group of drop downs.

At least that's how it's working here. I might have missed something. Let me know, also if you have any questions.

jscheuer1
03-31-2013, 02:59 PM
Here's another version that's a little more elegant, cross browser, and flexible:


<!DOCTYPE html><!-- Standards invoking DOCTYPE required for IE 8, perhaps others -->
<html>
<head>
<title>Car Design</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
function configureDropDownLists(ddl, doc_sys) {
(doc_sys = document.getElementsByName('doc' + doc_sys + '_sys')[0]).options.length = 0;
var options = configureDropDownLists.options[ddl.value.toLowerCase()], i = -1;
if(options){ while (++i < options.length) { createOption(doc_sys, options[i]); } }
}
configureDropDownLists.options = {
e1: ['Bilge & Ballast (BL)', 'Boiler (B)', 'Vents & Sounds (V)', 'Other (GENR)'],
e2: ['One Line Diagram (ONE)', 'Sound Powered Phone (SPP)', 'Other (GENR)'],
h1: ['Damage Stability (DAM)', 'Intact Stability (INT)', 'Lightship (LTSH)', 'Other (GENR)']
};
function createOption(ddl, text, value) {
ddl.options.add(new Option(text, value || text));
}
function adddocs(num){
adddocs.docs = adddocs.docs || [document.getElementById('doc1')];
var numdocs = adddocs.docs.length, newdoc, lastdoc, needed, newinputs, input, newel, oldel, newselects, select;
if(num < 1){num = 1;}
if(num < numdocs){
--num;
while(--numdocs > num){
(lastdoc = adddocs.docs[numdocs]).parentNode.removeChild(lastdoc);
adddocs.docs.splice(numdocs, 1);
}
} else if (num > numdocs) {
needed = num - numdocs;
while(--needed > -1){
newdoc = adddocs.docs[0].cloneNode(true);
adddocs.docs.push(newdoc);
numdocs = adddocs.docs.length;
newdoc.id = 'doc' + numdocs;
newinputs = newdoc.getElementsByTagName('input');
input = newinputs.length;
while(--input > -1){
if((newel = newinputs[input]).type === 'text'){
newel.name = newel.name.replace('1', numdocs);
newel.value = '';
} else if ((oldel = newinputs[input]).type === 'file'){
newel = document.createElement('input');
newel.type = 'file';
newel.name = oldel.name.replace('1', numdocs);
newel.setAttribute('allow', oldel.getAttribute('allow'), 0);
newel.size = oldel.size;
oldel.parentNode.replaceChild(newel, oldel);
}
}
newselects = newdoc.getElementsByTagName('select');
select = newselects.length;
while(--select > -1){
newel = newselects[select];
if(newel.name === 'doc1_type'){
newel.options.selectedIndex = 0;
} else if (newel.name === 'ddl1'){
try{newel.removeAttribute('onchange', 0);}catch(e){}
newel.onchange = function(){};
newel.options.selectedIndex = 0;
newel.onchange = (function(newel, numdocs){
return function(){
configureDropDownLists(newel, numdocs);
};
})(newel, numdocs);
} else if (newel.name === 'doc1_sys'){
newel.options.length = 0;
}
if(newel.name){newel.name = newel.name.replace('1', numdocs);}
}
newdoc.firstChild.nodeValue = newdoc.firstChild.nodeValue.replace('1', numdocs);
(lastdoc = adddocs.docs[numdocs - 2]).parentNode.insertBefore(newdoc, lastdoc.nextSibling);
}
}
}
function resetassist(){
adddocs(1);
document.getElementsByName('doc1_sys')[0].options.length = 0;
}
</script>
</head>
<body>
<form name="car" action="html_form_action.asp" method="get">
Submissions:<br>
Number of Files to Attach: <select name="numberoffiles" onchange="adddocs(this.value);">
<option value="0">0</option>
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option></select> Expedite? <input type="radio" name="nvic" value="Yes">Yes <input type="radio" name="nvic" value="No" checked>No
<br>
<!-- Begin what's dynamically added with each "number of files" -->
<div id="doc1">Document 1:<br><!-- there can be no space, line break, or tag between <div id="doc1"> and the text "Document 1:" -->
<table>
<tr>
<td>Name:</td>
<td><input type="text" size="60" name="doc1_name"></td>
<td><input type="file" name="doc1_file" size="72" allow="text"></td>
</tr>
<tr>
<td>Number:</td>
<td><input type="text" name="doc1_number"> Rev.: <input type="text" size="2" maxlength="2" name="doc1_rev"> Type: <select name="doc1_type">
<option value="Letter">Letter</option>
<option value="Manual">Manual</option>
<option value="Plans">Plans</option></select></td>
<td>Branch: <select name="ddl1" onchange="configureDropDownLists(this, 1)">
<option value=""></option>
<option value="E2">Electrical</option>
<option value="H1">Hull & Stability</option>
<option value="E1">Machinery & Piping</option>
</select>
System:
<select name="doc1_sys">
</select></td>
</tr>
</table>
<br>
</div>
<!-- End what's dynamically added with each "number of files" -->
<br>
<input type="reset" value="Clear" onclick="resetassist(); return true;">
<input type="submit" value="Submit">
</form>
<script type="text/javascript">
document.forms.car.reset();
resetassist();
</script>
</body>
</html>