Most web forms are static, as it's known in advance exactly what fields the form should show. In some cases however, you need a form that permits the user to enter a variable number of fields. Using JavaScript, you can add a button which the user can press when they need extra form fields. The button must trigger a JavaScript function to add the extra elements using the JS DOM.
In this example, we'll be looking at a form that is created within a table. The table has an
id of
formtable, and a few standard HTML fields. The HTML for the table is shown in the code listing below.
To test out the code, click the
Activate Demo button on the top-right of the code listing. You'll then see the table and form as they'll appear to the user. Select 'Links' or 'Buttons' in the dropdown, and the textboxes will appear, along with a small button labelled with a plus sign. Press this button to add new text boxes.
<form action="/" method="post" onsubmit="alert('Form submit disabled');return false;">
<table id="formtable" border="0" cellpadding="0" cellspacing="3">
<tr>
<td>
Title
</td>
<td>
Type
<span style="color:red;">*
</span>
</td>
</tr>
<tr>
<td>
<input name="title" type="text" size="40" value="title">
</td>
<td>
<select name="notice_type" onchange="show_link_boxes(this.value == 1 || this.value == 3);">
<option value="">Please select..
</option>
<option value="1">Links
</option>
<option value="2">Text only
</option>
<option value="3">Buttons
</option>
</select>
</td>
</tr>
<tr>
<td colspan="2">
Notes
</td>
</tr>
<tr>
<td colspan="2">
<textarea name="description" rows="3" cols="40">description
</textarea>
</td>
</tr>
<tr id="opt0" style="display:none">
<td>
Label
<span style="color:red;">*
</span>
</td>
<td>
Link
<span style="color:red;">*
</span>
</td>
</tr>
<tr id="opt1" style="display:none">
<td>
<input type="text" name="opt_title[]" maxlength="255" size="40">
</td>
<td>
<input type="text" name="opt_url[]" maxlength="255" size="40">
</td>
</tr>
<tr id="opt_controls" style="display:none">
<td align="right" colspan="2">
<input type="button" onclick="add_opt_row()" value="+">
</td>
</tr>
<tr>
<td align="right" colspan="2">
<input type="submit" value="Submit">
</td>
</tr>
</table>
</form>
The JavaScript Functions
Let's now have a look at the two JavaScript functions that provide this functionality. The first one,
show_link_boxes(), simply shows or hides the textboxes as well as the button for adding new textboxes. As you can see if you study the HTML code listing above, this function is called by the
onchange attribute of the dropdown list, such that the textboxes appear when the drop-down is set to either 'Links' or 'Buttons' and are hidden otherwise.
<script language="javascript">
function show_link_boxes
(visible
) {
// Iterate through all rows of the table
var rows
= document
.getElementById
('formtable').getElementsByTagName
('tr');
var total_rows
= rows
.length
;
for (var index
= 0; index
< total_rows
; index
++) {
// Set display property of all rows with an id beginning with 'opt'
if (rows
[index
].id
.substr(0, 3) == 'opt') {
rows
[index
].style
.display
= visible?
'' : 'none';
}
}
}
</script>
Adding Textboxes to the Form
The other function,
add_opt_row(), is more interesting to us. It adds a new table row, comprising two table cells each containing a new text box. It begins by iterating through all table rows of our table. Note how
getElementsByTagName() is again used to select only those rows that belong to the table with an
id of
formtable.
When we create the two new textboxes with
document.createElement('input'), we set the
name attribute to
opt_title[] and
opt_url[] respectively. Using names with a pair of empty square brackets like this means that in PHP, we can access all POST values that have this name as a single array, eg
$_POST['opt_title'][0], and therefore we can iterate through all such values using
foreach, thus allowing us to easily access however many fields the user chose to add.
We also set a few other attributes for the textboxes before each one is added to a separate table cell. The two table cells are then added to a new table row which is in turn added to the table using the
insertBefore() function on the last line of this function. At this point, the two new textboxes appear and are ready for the user to enter values.
<script language="javascript">
function add_opt_row
() {
var rows
= document
.getElementById
('formtable').getElementsByTagName
('tr');
var highest_id
= 0;
var total_rows
= rows
.length
;
for (var index
= 0; index
< total_rows
; index
++) {
if (rows
[index
].id
.substr(0, 3) == 'opt' && !isNaN
(rows
[index
].id
.substr(3))) {
if (Number
(rows
[index
].id
.substr(3)) > highest_id
) highest_id
= Number
(rows
[index
].id
.substr(3));
}
}
// Create 2 new table cells
var cell1
= document
.createElement
('td');
var cell2
= document
.createElement
('td');
// Create a new input textbox in each
var inputbox
= document
.createElement
('input');
inputbox
.type
= 'text';
inputbox
.name
= 'opt_title[]';
inputbox
.maxLength
= 255;
inputbox
.size
= 40;
cell1
.appendChild
(inputbox
);
inputbox
= document
.createElement
('input');
inputbox
.type
= 'text';
inputbox
.name
= 'opt_url[]';
inputbox
.maxLength
= 255;
inputbox
.size
= 40;
cell2
.appendChild
(inputbox
);
// Create new row & add tds to row
var newrow
= document
.createElement
('tr');
newrow
.id
= 'opt' + (highest_id
+1);
newrow
.appendChild
(cell1
);
newrow
.appendChild
(cell2
);
// Add rows to appropriate place
document
.getElementById
('opt_controls').parentNode
.insertBefore
(newrow
, document
.getElementById
('opt_controls'));
}
</script>