• Top
  • Reply

Zend Form - Making it Bend to your will

I assume you are pretty new to zend form or the methodology of MVC. Or if you are migrating from a different Framework. The following may be of some use. This small brief intends to outline the power of the Zend Forms and how to use them to your advantage.

To start any example or a tutorial I believe its important to have an end goal, and such the purpose of this short tutorial will be to provide a basic blog. To do this I will cover how to create a form module, moving on to create the elements (inputs, textarea, checkbox etc..), rendering the form object and finally validating and filtering the input.

The main advantage of zend form is that it clearly defines the MVC model for creating forms, and also separates validation and filtering of elements from your main MVC model. This way of thinking provides a much flexible collaboration of designers and developers working on a singular project.


The Setting

Our main goal is to have multiple elements that represent a blog. To create a very basic blog we will use three unique elements:

  • title - The title of our blog | Cannot be left empty, Must have atleast two words and the *length must be greater than 15 characters.
  • message - The physical content | We will strip HTML tags.
  • publish - A Checkbox that holds weather or not this blog is published | No checks need to be performed

To perform the following task in a classic fashion we always face the problem of defining changes to the view of the form using php, or adding multiple if conditions to our validation code, and finally we finish off with a call to our database in the end of our already polluted php file. The biggest advantage here is there is no code reuse, because all the validation filtering and updating is done in one script and to do this else where will require rewriting the code.

You can quickly see how this starts becoming a tangled web, in which thinking about it makes your head hurt. Zend form take the headache away and let you define validators and filters separately so they can be reused efficiently.

Zend provides you with pre-built common validators and filters, for example Zend_Validate_EmailAddress will check weather a field is a valid email address or Zend_Filter_StringTrim will trim the string that is passed by the user. Its always a good idea to familiarize yourself with the list of already available filters and validators because it will help you avoid writing your own types. Its always good to reuse.

A Simple Working Version

To start off with, we have a controller and we create an action editAction(). To this action we attach a simple view edit.phtml

application/Controller/IndexController.php

editAction()
{
    $this->view->form = "Testing"
}

application/views/scripts/index/edit.phtml

<div class='form'>
    <?php echo $this->form ?>
</div>

This gives us a Framework to work from and shows you where you should start. Let us now create a new file in application/form/Blog.php which can be done manually or by running the following zf command zf create form Blog. The generated file should look like:

<?php

class Application_Form_Blog extends Zend_Form
{    
    public function __construct($val = null){ loadDefault($val); }

    private function loadDefault($val = null) 
    { 
         /* ..Initialize our Form Here.. */ 
    }
}

As you can see from above, a simple class which extends Zend_Form and has a constructor with a call to a helper function, we will use $val variable later, so leave it for now. I will now show you a simple create of a textbox. Add the following code inside the loadDefault($val) function.

$title = new Zend_Form_Element_Text('title');
$title->setRequired(true)
    ->setLabel("Title");

$this->addElement($title);

In the loadDefault($val) function we first make a new instance of Zend_Form_Element_Text('title') where the title string is important as that will be its name in the rendered input. This value is also used by the form class to identify a unique object. After that you will notice setRequired(true) function. This sets title as a required field, and finally you will note setLabel() this sets the <label> element, which will be more clearer once you see the form rendered.

Near the end you notice a call to $this->addElement($title), $this is the reference to the form itself and you are adding a Text-Element to this form. You can also use $this->addElements(array($title)) which is a shorthand for adding multiple elements in one go. Another important point is that the order of the elements by default is determined by the sequence of the $this->addElements() call, or the order of the array.

One final step is to add a Submit button. Because without a submit button, our form is pointless. To add a submit button we add this below our $this->addElement($title) call.

$save = new Zend_Form_Element_Submit('save');
$this->addElement($save);

And walla, our form class is done, with two elements a save and a title. The problem is that we cant start running stuff as of yet. Because we need to reflect this in our controller, More specifically the IndexController and the ::editAction.

Master of Puppets

In our controller we have basically initialize our form, and pass the initialized form to our dormant $this->view->form variable as seen previously.

editAction()
{
    $this->view->form = new Applicaion_Form_Blog();
}

That's it, Yes that's write that's it. Go look at the view http://yoursite/index/edit see what happens...

Ok maybe i jumped a bit ahead, that's not quite it, but at least you can see things in action. If you remember I added a setRequired(true) function to our title element. However you will note nothing happens, infact when you submit, all goes well. and there are no checks. Well here is where things start getting clever and confusing, If we modify our controller and add a isValid function we will then see some error handling. The best way to explain this is to you by example. So open up your IndexController and modify the edit action to the following:

editAction()
{
    $this->view->form = new Applicaion_Form_Blog();

    if ($this->_request->isPost())
    {
        if ($this->view->form->isValid($this->_request->getPost()))
        {
            print "Yay!";
        }
    }
}

In the above we have added a check to see weather the request has been made, Hence weather the user has or has not clicked the send button, If he has, check to see if Values are valid according to our initialized rules. In other words is the title element filled in if so, return true; which in turn will print "Yay!" or else....wait what where is the else?!

...Thats right there is no else, we don't deal with validating fields or printing the errors zend does, And this is why it is amazing, All you do is call isValid($_POST) and let zend deal with the rest. Test your forms and see what what happens when you leave the value blank.

The isValid function is absolutely beautiful, gone or the days of validating the input. It does it all for you.

The Will

Now lets expand our example a little, Give it some meat. I will now add the message and publish fields after our call to create the text element. So in our application/form/Blog.php we change our loadDefault($val) to the following

public loadDefault($val)
{
    $title = new Zend_Form_Element_Text('title');
    $title->setRequired(true)
        ->setLabel("Title");

    $this->addElement($title);

    $message = new Zend_Form_Element_Textarea('msg');
    $message->setRequired(true)
        ->setLabel("Title");

    $this->addElement($title);

    $publish = new Zend_Form_Element_Checkbox('publish');
    $publish->setChecked(false)
        ->setLabel("Publish");

    $send = new Zend_Form_Element_Submit('save');
    $send->setLabel('Update');
    $this->addElement($send);

    $this->addElement($publish);
}

Now go and refresh your page and you will see all the new elements appear, without you having to manually define them in HTML. Try testing your validators to see if they work, and see if your "Yay!" gets printed at any point.

A good end to this would be to go and discover more validators, which can be found in $ZEND_FOLDER/Validator/*, here you can see many handy validators that let you do the important stuff. When I get a chance i will add a tutorial on how to create your own validators or filters. Till then I'm out!

By

23rd Oct 2011
© 2011 Shahmir Javaid - http://shahmirj.com/blog/18


Back to Top
All content is © copyrighted, unless stated otherwise.
Subscribe, @shahmirj, Shahmir Javaid+