wForms - Server-side handling of the Repeat Behavior (part 2)
The Repeat behavior is certainly the most powerful functionality of the wForms extension and enabling it in a web form is dead simple (class=’repeat’ anyone?). Processing the form submission is trickier though, but the real difficulty with repeated groups arises when you want to populate a form with previously submitted data. You basically need to re-engineer server-side what wForms does client-side.
The Form
Let’s start with a simple form and let’s make the fieldset repeatable by using wForms’ ‘repeat’ class.
<form action="">
<fieldset id="myfieldset" class="repeat“>
<label for=”field1″>Label 1: </label>
<input type=”text” id=”field1″ name=”field1″ />
<label for=”field2″>Label 2: </label>
<input type=”text” id=”field2″ name=”field2″ />
</fieldset>
</form>
Submitted Data
Now, assuming that this form was previously submitted with 3 rows, the data collected on the server contains the following fields:
| Field Name | Field Value | Comment |
|---|---|---|
| field1 | value1… | original row |
| field2 | value2… | |
| field1-2 | value3… | second row |
| field2-2 | value4… | |
| field1-3 | value5… | third row |
| field2-3 | value6… | |
| myfieldset-rc | 3 | row counter |
Populating back the form
In order to show the form back to the user, you need to :
- Loop 3 times over the <fieldset> element.
- Set the value of each field.
- Appends the row index suffix to the id, name and for attributes for every tag in the second and third rows (the first row is always left unchanged by wForms).
- Change the class from ‘repeat’ to ‘removeable’ (sic) for the second and third rows.
- Create the hidden counter field. The name of this field is constructed by adding ‘-RC’ to the id of the tag with the ‘repeat’ class (here ‘myfieldset’).
If the form is correctly set up, wForms will be able to carry on from there, allowing adding more rows or removing the existing ones.
Sequence gaps
Now, as I mentioned previously, the -RC field in wForms does not exactly behave like a row counter. It indicates the highest row index reached. If the user deleted a row before submitting the form, you’ll end up with a gap in the sequence that you need to accommodate for. In the loop logic, you can tell if the row was deleted if you can’t find any name/value pair in your submitted dataset for the given row index.
Code Sample (PHP)
Note: Updated on June 15th 2007.
<?php
$max = (int) $_POST["myfieldset-RC"];
for($i=1;$i<=$max;$i++) {
if($i==1) {
$repeatclass = "repeat";
$rowIndex = "";
}
else {
$repeatclass = "removeable";
$rowIndex = "-".$i;
}
if(isset($_POST["field1".$rowIndex]) && isset($_POST["field2".$rowIndex])) { // account for sequence gap.
?>
<fieldset id="myfieldset<?php echo($rowIndex)?>" class="<?php echo($repeatclass)?>">
<label for="field1<?php echo($rowIndex)?>">Label 1: </label>
<input type="text" id="field1<?php echo($rowIndex)?>" name="field1<?php echo($rowIndex)?>" value="<?php echo($_POST["field1".$rowIndex])?>" />
<label for="field2<?php echo($rowIndex)?>">Label 2: </label>
<input type="text" id="field2<?php echo($rowIndex)?>" name="field2<?php echo($rowIndex)?>" value="<?php echo($_POST["field2".$rowIndex])?>" />
</fieldset>
<?php
}
}
echo "“;
?>
Result
Update: Comments are now closed for this post, but you can go to the wForms forum if you have any question or comment. Thanks !
