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.
Our main goal is to have multiple elements that represent a blog. To create a very basic blog we will use three unique elements:
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.
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
.
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.
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!