One is one's own refuge, who else could be the refuge?
Anyone who has created multi-select checkboxes knows that HTML forms support array values. But did you know you could use this handy feature to reduce complexity in your MVC application?
Today I'd like to introduce ways that I use structured HTML form data to simplify common CRUD operations in MVC architectures.
Let's start by reviewing how HTML form structuring works. The structuring mechanic is controlled through the form element name attribute.
Here is a simple form input and the resulting data structure sent in the post request when the form is submitted.
HTML
<input type="text" name="title" value="Hello World"/>
Post output
['title' => 'Hello World']
To create structured HTML forms we use array syntax for the input name.
HTML
<input type="text" name="form[title]" value="Hello World"/>
Post output
[
'form' => ['title' => 'Hello World']
]
At first glance this might not seem significant. However the real utility comes from the fact that the HTML form element supports both regular and associative arrays.
HTML
<input type=”hidden” name=”form[0][id]” value=”1”/>
<input type=”text” name=”form[0][title]” value=”Hello World”/>
<input type=”hidden” name=”form[1][id]” value=”2”/>
<input type=”text” name=”form[1][title]” value=”Hello Universe”/>
Post output
[
'form' =>
0 => [
'id' => 1,
'title' => 'Hello World'
]
1 => [
'id' => 2,
'title' => 'Hello Universe'
]
]
This allows you to update multiple records in a single post request using a simple foreach statement without having to reconstruct the data relationships from the post data.
$formData = $_POST['form'];
foreach ($form as $record) {
$model = new RecordModel($record['$id']);
$model->update($record);
}
This is very useful for ordering data in tabular data sets. Assuming we have a simple sortable table like the one below.
ID | Title | |
---|---|---|
1 | Hello World | |
2 | Hello Universe |
HTML
<table id="mySortableTable" class="uk-table uk-table-striped uk-table-divider">
<thead>
<tr>
<td></td>
<th>ID</th>
<th>Title</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span uk-icon="icon: table"></span>
<input type=”hidden” name=”form[][id]” value=”1”/>
</td>
<td>1</td>
<td>
Hello World
</td>
</tr>
<tr>
<td>
<span uk-icon="icon: table"></span>
<input type=”hidden” name=”form[][id]” value=”2”/>
</td>
<td> 2 </td>
<td>
Hello Universe
</td>
</tr>
</tbody>
</table>
Post output
[
'form' =>
0 => ['id' => 1],
1 => ['id' => 2]
]
With unstructured form data, you would have to calculate the new ordering and update the input values before submitting the form. Or manipulate the values on the server side.
However since we are using structured data we can use the natural order of the array to update the order of the records when we submit the form.
$formData = $_POST['form'];
foreach ($form as $newOrder => $record) {
$record['ordering'] = $newOrder+1;
$model = new RecordModel($record['$id']);
$model->update($record);
}
This approach has the double benefit of simplifying both the front-end and the back-end.
Another way we can use structured form data is to update relational data without complicating the models.
HTML
<input type=”hidden” name=”form[id]” value=”1”/>
<input type=”text” name=”form[title]” value=”Hello World”/>
<input type="text" name="form[related_record][name]" value="Related record name"/>
<input type="hidden" name="form[related_record][id]" value="1"/>
Post output
[
'form' =>
id => 1,
title => 'Hello world',
'related_record' => [
'name' => 'Related record name',
'id' => '1'
]
]
The idea is to keep the form data structure and the back-end data structure as close to the same as possible.
Now we can update both the main record and the related record in a single post by using depenecy delagation.
class myModel {
public function update($form) {
$this->save($form);
$relatedModel = new RelatedModel($form['related_record']['id');
$relatedModel->update($form['related_record']);
}
}
This apporach allows us to update child model records without changing the interface of the Model class.
And because the Controller class doesn't have to manipulate the post data, we have improve encapsulation of both the data and the relationship between Model and RelatedModel.
There are many other interesting ways to use structured form data to reduce system complexity, but it is 2:30 A.M. So further examples will have to come another day.
Thanks for reading and I hope you found this content useful. =^D