Simplify Form Validation and Reuse, Use Validation Groups

Zend Framework 2 Forms

Kicking off 2014, today we’re investigating a simple, yet powerful, aspect of forms - validation groups. This will be a simple tutorial, as it’s not a very complex topic.

If you’re not familiar with validation groups, they do two things:

  1. Encourage Form Reuse
  2. Filter Out Unrequired Data

How? By limiting the number of form elements required to be validated and the form information retrieved with getData().

Say we had a form, which validates a user. Normally such a form would contain fields such as first and last namesemail addressphone numbersaddress, maybe their social security number and so on. Let’s assume we’ve developed the form and tests verify it works properly.

Let’s say that the company’s growing really quickly and wants to build up its email list. Consequently, you’ve been tasked with adding an email signup form to the company website, a lot like the Malt Blue one from MailChimp.

What do you do? You could write another form, but they share some common elements, and an InputFilter class, causing code duplication. Why create it again and give us more to maintain? What do you do?

Enter Validation Groups.

As stated validation groups give us two key benefits:

Firstly form reuse. We can re-use the same form in both instances, and validation will only be required on the fields within the group, even if other fields have been specified as required.

Then there’s filtering out unrequired data. In most forms, there are other fields which are required during validation, but not in post-processing. For example, the submitreset, and cancel buttons. These aid in form usage, but not in processing the information after validation.

When present, we either need to remove them from the retrieved form data, or handle it in the post-processing functions (not desired).

By using a validation group, when getData() is called on the form object, the returned array contains only the fields specified in the validation group.

Quite handy - no? Let’s work through an example.

Code Example

In this gist you can see code for a simple UserRecord class, created using Zend Form Annotations. Note that a number of the fields are required.

Below are three entries in the array which is returned from a standard implementation of getServiceConfig in a Zend Framework module. Let’s look at how these allow us to reuse our form class in a variety of ways.

  'Form\Feed\UserRecordForm' => function ($sm) {
    $form = new Form\UserRecordForm();
    $form->setInputFilter(
      new InputFilter\UserRecordInputFilter()
    );
    return $form;
  }

In the example above, we’ve not set a validation group. In this case, the form will validate as we’d expect it to, asking for all the fields specified and returning them all with getData.

NB: It was pointed out on #zftalk on IRC, that getServiceConfig wasn’t the recommended place to configure forms. For a better way, have a look at Howto Handle External Form Element Dependencies with FormElementManager
  'Form\Feed\EmailSignupFormEmailOnly' => function ($sm) {
    $form = new Form\UserRecordForm();
    $form->setValidationGroup(array('email'));
    $form->setInputFilter(
      new InputFilter\UserRecordInputFilter()
    );
    return $form;
  }

In this example, we can render a form containing only the email address field. During validation, only the rules of this one will be enforced, and only this field will be returned from getData.

'Form\Feed\EmailSignupFormSmall' => function ($sm) {
  $form = new Form\UserRecordForm();
  $form->setValidationGroup(array(
    'email', 'firstName', 'lastName'
  ));
  $form->setInputFilter(
    new InputFilter\UserRecordInputFilter()
  );
  return $form;
}

In this final example, we’ve created an enhanced signup form. As with the last one, the email field will be validated, and we can also show the first and last name fields, validating them as well. getData will return all three, skipping the remaining form fields.

Winding Up

So that’s validation groups. They’re a quick, simple, yet efficient feature of \Zend\Form which allows you to reuse forms and limit the data returned to just what you need.

Over To You

Tell me what you think. Will this one, simple, feature make development of forms simpler and more efficient, requiring less code? Have you already tried it? Share your experience in the comments.

Beginner PHP Tutorial