We’ve looked at custom form filters and we’ve looked at the core form configuration. But what about the other form properties? What about:
- setting an element as readonly
- an element as required
- ignoring an element and
- love them or hate them, what about decorators
Outside of the options that we’ve looked at previously, there are a number of other options that we can consider implementing when configuring a Zend Form. Have a look at the table below for these other options:
- required – Is the element required to have a value when the form’s submitted? If yes and it doesn’t, then validation will fail.
- readonly – Set the element to readonly or not.
- allowEmpty – Allow the element to contain an empty value, even if it’s required to be present for validation.
- order – The order that the element is to be displayed in.
- description – A textual description of the purpose of the element to assist the user.
- autoInsertNotEmptyValidator – Whether to auto insert a not empty validator if the element is required
- ignore – Whether to ignore processing of the element (good for submit and reset buttons)
These elements all allow us to configure the behavior of the form and it’s elements with that much more finite control. Let’s consider these options in the context of a pseudo-real world example.
Let’s say we have a form which is for used signing up to a mailing list. The options we’ll have on the form are: name and email address. The email address will be required but the name element will be optional. So we’re going to set the email element to be required and allowEmpty on the name field.
Also, when we process the form, we aren’t likely to care about the submit button. All it’s needed for here is to submit the form. We only have one button, so we’re not getting smart and determining what it’s value is. So we’re going to set it to be ignored with the ignore property.
Taking time to consider our user, maybe they’re new to the web or new to forms. So to help them out, we’re going to set a description for the name and email fields with some appropriate text.
Now let’s address the order of the elements in the form. As the email is the most important and name second most, we’re going to set them to be rendered in that order, starting with email at 0 and name at 1.
Have a look at the XML form config below which has all of these options set with their appropriate values:
<?xml version="1.0" encoding="UTF-8"?> <forms> <simpleForm> <action>/forms/index/index/</action> <method>post</method> <id>simpleForm</id> <name>simpleForm</name> <class>simpleFormClass</class> <enctype>application/x-www-form-urlencoded</enctype> <accept-charset>UTF-8</accept-charset> <lang>en</lang> <accept>text/html</accept> <style>border: 1px solid #ccc;padding: 15px;</style> <title>Simple Form</title> <elements> <name> <type>text</type> <options> <label>Name:</label> <order>1</order> <size>30</size> <readonly>readonly</readonly> <description>The user's first, last or both names</description> <validators> <notempty> <validator>NotEmpty</validator> <options> <messages> <isEmpty>A name is required</isEmpty> </messages> </options> </notempty> </validators> <required>false</required> <allowEmpty>true</allowEmpty> <autoInsertNotEmptyValidator>false</autoInsertNotEmptyValidator> </options> </name> <email> <type>text</type> <options> <label>Email Address:</label> <size>30</size> <order>0</order> <description>The user's email address</description> <validators> <notempty> <validator>NotEmpty</validator> <options> <messages> <isEmpty>A name is required</isEmpty> </messages> </options> </notempty> </validators> <required>true</required> <allowEmpty>false</allowEmpty> </options> </email> <submit> <type>submit</type> <ignore>true</ignore> <order>2</order> <options> <label>Process</label> </options> </submit> </elements> </simpleForm> </forms>
You can see in the image below what the form looks like:
If you were looking closely, you’ll see that we’ve added an extra configuration option in to the autoInsertNotEmptyValidator. This is required if we set an element to be ‘required’, yet also allow it to have an empty value. If we don’t add this, even though we specify allowEmpty, this will result in the form failing validation.
I’ve highlighted this because it’s not always or immediately obvious from the documentation that this occurs. It tricked me up for a while because I overlooked this in the documentation. It seemed logical to me (and still does) that if you set required to be false, then it wouldn’t be an issue. Maybe I should chat this over with Matthew Weier O’Phinney or one of the other contributors.
But I digress…now we have implemented the other key options for configuring forms. But what about decorators?
Aaah decorators, love them or hate them, they’re a part of Zend Form and they’re not going away anytime soon. To be honest though, they provide a good role, when properly understood and do save us time and effort in doing a lot of the trivial and repeatable aspects of form design and layout.
But this post isn’t about weighing up the pros and cons of them. It’s about showing you how to implement them using Zend Config – right? So to make this example as practical as possible, we’re going to refine our existing form by specifying form-wide decorators, then override them for the submit button.
First we’re setting the form-wide decorators in the XML below:
<?xml version="1.0" encoding="UTF-8"?> <forms> <simpleForm> <action>/forms/index/index/</action> <method>post</method> <id>simpleForm</id> <name>simpleForm</name> <class>simpleFormClass</class> <enctype>application/x-www-form-urlencoded</enctype> <accept-charset>UTF-8</accept-charset> <lang>en</lang> <accept>text/html</accept> <style>border: 1px solid #ccc;padding: 15px;</style> <title>Simple Form</title> <elementDecorators> <viewHelper> <decorator>ViewHelper</decorator> </viewHelper> <errors> <decorator>Errors</decorator> </errors> <htmlTag> <decorator>HtmlTag</decorator> </htmlTag> <label> <decorator>Label</decorator> </label> <description> <decorator>Description</decorator> </description> </elementDecorators>
Though this is only re-implementing what Zend_Form does normally, it highlights how it’s done in a form config instance. In this example we’ve said that for all form elements will have the viewHelper, Errors, HtmlTag, Label and Description decorators.
It’s important to implement them in this order so that they render correctly and don’t give warped results.
You remember before that we said the submit button isn’t that important to us for form value validation? Well we also don’t need the description or label decorators as well.
The value of the form will say the whole story; we don’t need to say it twice with a prefixed label. So let’s remove both the label and the description decorators – if you’ve read over the Zend_Form initialisation code, you’ll know that we don’t actually remove the other decorators explicitly. What we actually do is only implement the HtmlTag and ViewHelper decorators.
The XML example below shows how this is done.
<submit> <type>submit</type> <ignore>true</ignore> <order>2</order> <options> <label>Process</label> <decorators> <viewHelper> <decorator>ViewHelper</decorator> </viewHelper> <htmlTag> <decorator>HtmlTag</decorator> </htmlTag> </decorators> </options> </submit>
Let’s reload the form with the new configuration and display the output. The visual and html output is available below:
<form id="simpleForm" enctype="application/x-www-form-urlencoded" action="/forms/index/index/" method="post" accept-charset="UTF-8" lang="en" accept="text/html" style="border: 1px solid #ccc;padding: 15px;" title="Simple Form"><dl> <label for="email">Email Address:</label> <div> <input type="text" name="email" id="email" value="" size="30"></div> <p>The user's email address</p> <label for="name">Name:</label> <div> <input type="text" name="name" id="name" value="" size="30" readonly="readonly"></div> <p>The user's first, last or both names</p> <div> <input type="submit" name="submit" id="submit" value="Process"></div></dl></form>
With this configuration change, we will now get a form that renders as below:
Changing the Decorator Order
But what if we wanted to do something a little fancy? What if, instead of the normal label/field order, we wanted to reverse it to be field/label? Well let’s have a look at one last example and do just that.
Going back to our XML form configuration,
But What If We Want Just a Bit More Control?
Say we want to add in a prefix when the field is required and one when it’s only optional. For example, when the field’s required, we want to add an asterisk to the label, but not when it’s optional. How do we do that?
And what if we want to add some custom classes in to the label, because we want to add further styling just to one element. How do we do that? In that case, we can add further options to the label decorator. Have a look at the element configuration below to see how it’s done:
<label> <decorator>Label</decorator> <options> <requiredSuffix>:*</requiredSuffix> <optionalSuffix>:</optionalSuffix> <tag>span</tag> <class>simple-label</class> </options> </label>
The options elements indicate that when the element is required, it will have a suffix of “:*”, when it’s optional, it will only have “:”. The label will be wrapped in a span tag and have a class of simple-label.
After we reload the page, we can see the changes implemented both visually and in the updated HTML output.
So in this, the third part of the series, you’ve seen how to set a series of other properties on form elements and set the default form-wide and element-specific form decorators. In the fourth part of the series next week, we’re going to cover configuring a number of the standard form validators. Join us then – we’re almost done.