| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.form.quickstart">
- <title>Zend_Form Quick Start</title>
- <para>
- This quick start guide covers the basics of creating,
- validating, and rendering forms with <classname>Zend_Form</classname>.
- </para>
- <sect2 id="zend.form.quickstart.create">
- <title>Create a form object</title>
- <para>
- Creating a form object is very simple: simply instantiate
- <classname>Zend_Form</classname>:
- </para>
- <programlisting language="php"><![CDATA[
- $form = new Zend_Form;
- ]]></programlisting>
- <para>
- For advanced use cases, you may want to create a
- <classname>Zend_Form</classname> subclass, but for simple forms, you can
- create a form programmatically using a <classname>Zend_Form</classname>
- object.
- </para>
- <para>
- If you wish to specify the form action and method (always good
- ideas), you can do so with the <methodname>setAction()</methodname> and
- <methodname>setMethod()</methodname> accessors:
- </para>
- <programlisting language="php"><![CDATA[
- $form->setAction('/resource/process')
- ->setMethod('post');
- ]]></programlisting>
- <para>
- The above code sets the form action to the partial <acronym>URL</acronym>
- "<filename>/resource/process</filename>" and the form method to <acronym>HTTP</acronym>
- <acronym>POST</acronym>. This will be reflected during final rendering.
- </para>
- <para>
- You can set additional <acronym>HTML</acronym> attributes for the
- <emphasis><form></emphasis> tag by using the <methodname>setAttrib()</methodname>
- or <methodname>setAttribs()</methodname> methods. For instance, if you wish to set the
- id, set the "<property>id</property>" attribute:
- </para>
- <programlisting language="php"><![CDATA[
- $form->setAttrib('id', 'login');
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.form.quickstart.elements">
- <title>Add elements to the form</title>
- <para>
- A form is nothing without its elements. <classname>Zend_Form</classname>
- ships with some default elements that render <acronym>XHTML</acronym> via
- <classname>Zend_View</classname> helpers. These are as follows:
- </para>
- <itemizedlist>
- <listitem><para>button</para></listitem>
- <listitem>
- <para>checkbox (or many checkboxes at once with multiCheckbox)</para>
- </listitem>
- <listitem><para>hidden</para></listitem>
- <listitem><para>image</para></listitem>
- <listitem><para>password</para></listitem>
- <listitem><para>radio</para></listitem>
- <listitem><para>reset</para></listitem>
- <listitem><para>select (both regular and multi-select types)</para></listitem>
- <listitem><para>submit</para></listitem>
- <listitem><para>text</para></listitem>
- <listitem><para>textarea</para></listitem>
- </itemizedlist>
- <para>
- You have two options for adding elements to a form: you can
- instantiate concrete elements and pass in these objects, or you can
- pass in simply the element type and have <classname>Zend_Form</classname>
- instantiate an object of the correct type for you.
- </para>
- <para>
- Some examples:
- </para>
- <programlisting language="php"><![CDATA[
- // Instantiating an element and passing to the form object:
- $form->addElement(new Zend_Form_Element_Text('username'));
- // Passing a form element type to the form object:
- $form->addElement('text', 'username');
- ]]></programlisting>
- <para>
- By default, these do not have any validators or filters. This means
- you will need to configure your elements with at least validators,
- and potentially filters. You can either do this (a) before you pass
- the element to the form, (b) via configuration options passed in
- when creating an element via <classname>Zend_Form</classname>, or (c) by
- pulling the element from the form object and configuring it after
- the fact.
- </para>
- <para>
- Let's first look at creating validators for a concrete element
- instance. You can either pass in <classname>Zend_Validate_*</classname>
- objects, or the name of a validator to utilize:
- </para>
- <programlisting language="php"><![CDATA[
- $username = new Zend_Form_Element_Text('username');
- // Passing a Zend_Validate_* object:
- $username->addValidator(new Zend_Validate_Alnum());
- // Passing a validator name:
- $username->addValidator('alnum');
- ]]></programlisting>
- <para>
- When using this second option, you can pass constructor arguments in an array as the
- third parameter if the validator can accept tem:
- </para>
- <programlisting language="php"><![CDATA[
- // Pass a pattern
- $username->addValidator('regex', false, array('/^[a-z]/i'));
- ]]></programlisting>
- <para>
- (The second parameter is used to indicate whether or not failure of
- this validator should prevent later validators from running; by
- default, this is <constant>FALSE</constant>.)
- </para>
- <para>
- You may also wish to specify an element as required. This can be
- done using an accessor or passing an option when creating
- the element. In the former case:
- </para>
- <programlisting language="php"><![CDATA[
- // Make this element required:
- $username->setRequired(true);
- ]]></programlisting>
- <para>
- When an element is required, a 'NotEmpty' validator is added to the
- top of the validator chain, ensuring that the element has a value
- when required.
- </para>
- <para>
- Filters are registered in basically the same way as validators. For
- illustration purposes, let's add a filter to lowercase the final
- value:
- </para>
- <programlisting language="php"><![CDATA[
- $username->addFilter('StringtoLower');
- ]]></programlisting>
- <para>
- The final element setup might look like this:
- </para>
- <programlisting language="php"><![CDATA[
- $username->addValidator('alnum')
- ->addValidator('regex', false, array('/^[a-z]/'))
- ->setRequired(true)
- ->addFilter('StringToLower');
- // or, more compactly:
- $username->addValidators(array('alnum',
- array('regex', false, '/^[a-z]/i')
- ))
- ->setRequired(true)
- ->addFilters(array('StringToLower'));
- ]]></programlisting>
- <para>
- Simple as this is, repeating it this for every element in a form
- can be a bit tedious. Let's try option (b) from above. When we
- create a new element using <methodname>Zend_Form::addElement()</methodname> as
- a factory, we can optionally pass in configuration options. These
- can include validators and filters. To do all of the
- above implicitly, try the following:
- </para>
- <programlisting language="php"><![CDATA[
- $form->addElement('text', 'username', array(
- 'validators' => array(
- 'alnum',
- array('regex', false, '/^[a-z]/i')
- ),
- 'required' => true,
- 'filters' => array('StringToLower'),
- ));
- ]]></programlisting>
- <note>
- <para>
- If you find you are setting up elements using the same options in
- many locations, you may want to consider creating your own
- <classname>Zend_Form_Element</classname> subclass and utilizing that class
- instead; this will save you typing in the long-run.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.form.quickstart.render">
- <title>Render a form</title>
- <para>
- Rendering a form is simple. Most elements use a
- <classname>Zend_View</classname> helper to render themselves, and thus need a
- view object in order to render. Other than that, you have two
- options: use the form's render() method, or simply echo it.
- </para>
- <programlisting language="php"><![CDATA[
- // Explicitly calling render(), and passing an optional view object:
- echo $form->render($view);
- // Assuming a view object has been previously set via setView():
- echo $form;
- ]]></programlisting>
- <para>
- By default, <classname>Zend_Form</classname> and
- <classname>Zend_Form_Element</classname> will attempt to use the view object
- initialized in the <classname>ViewRenderer</classname>, which means you won't
- need to set the view manually when using the Zend Framework <acronym>MVC</acronym>.
- To render a form in a view, you simply have to do the following:
- </para>
- <programlisting language="php"><![CDATA[
- <?php echo $this->form ?>
- ]]></programlisting>
- <para>
- Under the hood, <classname>Zend_Form</classname> uses "decorators" to perform
- rendering. These decorators can replace content, append content, or
- prepend content, and can fully introspect the element passed
- to them. As a result, you can combine multiple decorators to
- achieve custom effects. By default, <classname>Zend_Form_Element</classname>
- actually combines four decorators to achieve its output; setup
- looks something like this:
- </para>
- <programlisting language="php"><![CDATA[
- $element->addDecorators(array(
- 'ViewHelper',
- 'Errors',
- array('HtmlTag', array('tag' => 'dd')),
- array('Label', array('tag' => 'dt')),
- ));
- ]]></programlisting>
- <para>
- (Where <HELPERNAME> is the name of a view helper to use, and varies
- based on the element.)
- </para>
- <para>
- The above creates output like the following:
- </para>
- <programlisting language="html"><![CDATA[
- <dt><label for="username" class="required">Username</dt>
- <dd>
- <input type="text" name="username" value="123-abc" />
- <ul class="errors">
- <li>'123-abc' has not only alphabetic and digit characters</li>
- <li>'123-abc' does not match against pattern '/^[a-z]/i'</li>
- </ul>
- </dd>
- ]]></programlisting>
- <para>
- (Albeit not with the same formatting.)
- </para>
- <para>
- You can change the decorators used by an element if you wish to
- have different output; see the section on decorators for more
- information.
- </para>
- <para>
- The form itself simply loops through the elements, and dresses them
- in an <acronym>HTML</acronym> <emphasis><form></emphasis>. The action and method
- you provided when setting up the form are provided to the
- <emphasis><form></emphasis> tag, as are any attributes you set via
- <methodname>setAttribs()</methodname> and family.
- </para>
- <para>
- Elements are looped either in the order in which they were
- registered, or, if your element contains an order attribute, that
- order will be used. You can set an element's order using:
- </para>
- <programlisting language="php"><![CDATA[
- $element->setOrder(10);
- ]]></programlisting>
- <para>
- Or, when creating an element, by passing it as an option:
- </para>
- <programlisting language="php"><![CDATA[
- $form->addElement('text', 'username', array('order' => 10));
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.form.quickstart.validate">
- <title>Check if a form is valid</title>
- <para>
- After a form is submitted, you will need to check and see if it
- passes validations. Each element is checked against the data
- provided; if a key matching the element name is not present, and
- the item is marked as required, validations are run with a <constant>NULL</constant>
- value.
- </para>
- <para>
- Where does the data come from? You can use <varname>$_POST</varname> or
- <varname>$_GET</varname>, or any other data source you might have at hand
- (web service requests, for instance):
- </para>
- <programlisting language="php"><![CDATA[
- if ($form->isValid($_POST)) {
- // success!
- } else {
- // failure!
- }
- ]]></programlisting>
- <para>
- With <acronym>AJAX</acronym> requests, you can sometimes get away with validating
- a single element, or groups of elements.
- <methodname>isValidPartial()</methodname> will validate a partial form. Unlike
- <methodname>isValid()</methodname>, however, if a particular key is not
- present, it will not run validations for that particular element:
- </para>
- <programlisting language="php"><![CDATA[
- if ($form->isValidPartial($_POST)) {
- // elements present all passed validations
- } else {
- // one or more elements tested failed validations
- }
- ]]></programlisting>
- <para>
- An additional method, <methodname>processAjax()</methodname>, can be used
- for validating partial forms. Unlike <methodname>isValidPartial()</methodname>,
- it returns a <acronym>JSON</acronym>-formatted string containing error messages on
- failure.
- </para>
- <para>
- Assuming your validations have passed, you can now fetch the
- filtered values:
- </para>
- <programlisting language="php"><![CDATA[
- $values = $form->getValues();
- ]]></programlisting>
- <para>
- If you need the unfiltered values at any point, use:
- </para>
- <programlisting language="php"><![CDATA[
- $unfiltered = $form->getUnfilteredValues();
- ]]></programlisting>
- <para>
- If you on the other hand need all the valid and filtered values of a partially valid
- form, you can call:
- </para>
- <programlisting language="php"><![CDATA[
- $values = $form->getValidValues($_POST);
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.form.quickstart.errorstatus">
- <title>Get error status</title>
- <para>
- Did your form have failed validations on submission? In most cases, you can simply
- render the form again, and errors will be displayed when using the
- default decorators:
- </para>
- <programlisting language="php"><![CDATA[
- if (!$form->isValid($_POST)) {
- echo $form;
- // or assign to the view object and render a view...
- $this->view->form = $form;
- return $this->render('form');
- }
- ]]></programlisting>
- <para>
- If you want to inspect the errors, you have two methods.
- <methodname>getErrors()</methodname> returns an associative array of element
- names / codes (where codes is an array of error codes).
- <methodname>getMessages()</methodname> returns an associative array of element
- names / messages (where messages is an associative array of error
- code / error message pairs). If a given element does not have any
- errors, it will not be included in the array.
- </para>
- </sect2>
- <sect2 id="zend.form.quickstart.puttingtogether">
- <title>Putting it together</title>
- <para>
- Let's build a simple login form. It will need elements
- representing:
- </para>
- <itemizedlist>
- <listitem><para>username</para></listitem>
- <listitem><para>password</para></listitem>
- <listitem><para>submit</para></listitem>
- </itemizedlist>
- <para>
- For our purposes, let's assume that a valid username should be
- alphanumeric characters only, start with a letter, have a minimum
- length of 6, and maximum length of 20; they will be normalized to
- lowercase. Passwords must be a minimum of 6 characters. We'll
- simply toss the submit value when done, so it can remain
- unvalidated.
- </para>
- <para>
- We'll use the power of <classname>Zend_Form</classname>'s configuration
- options to build the form:
- </para>
- <programlisting language="php"><![CDATA[
- $form = new Zend_Form();
- $form->setAction('/user/login')
- ->setMethod('post');
- // Create and configure username element:
- $username = $form->createElement('text', 'username');
- $username->addValidator('alnum')
- ->addValidator('regex', false, array('/^[a-z]+/'))
- ->addValidator('stringLength', false, array(6, 20))
- ->setRequired(true)
- ->addFilter('StringToLower');
- // Create and configure password element:
- $password = $form->createElement('password', 'password');
- $password->addValidator('StringLength', false, array(6))
- ->setRequired(true);
- // Add elements to form:
- $form->addElement($username)
- ->addElement($password)
- // use addElement() as a factory to create 'Login' button:
- ->addElement('submit', 'login', array('label' => 'Login'));
- ]]></programlisting>
- <para>
- Next, we'll create a controller for handling this:
- </para>
- <programlisting language="php"><![CDATA[
- class UserController extends Zend_Controller_Action
- {
- public function getForm()
- {
- // create form as above
- return $form;
- }
- public function indexAction()
- {
- // render user/form.phtml
- $this->view->form = $this->getForm();
- $this->render('form');
- }
- public function loginAction()
- {
- if (!$this->getRequest()->isPost()) {
- return $this->_forward('index');
- }
- $form = $this->getForm();
- if (!$form->isValid($_POST)) {
- // Failed validation; redisplay form
- $this->view->form = $form;
- return $this->render('form');
- }
- $values = $form->getValues();
- // now try and authenticate....
- }
- }
- ]]></programlisting>
- <para>
- And a view script for displaying the form:
- </para>
- <programlisting language="php"><![CDATA[
- <h2>Please login:</h2>
- <?php echo $this->form ?>
- ]]></programlisting>
- <para>
- As you'll note from the controller code, there's more work to do:
- while the submission may be valid, you may still need to do some authentication
- using <classname>Zend_Auth</classname> or another authorization mechanism.
- </para>
- </sect2>
- <sect2 id="zend.form.quickstart.config">
- <title>Using a Zend_Config Object</title>
- <para>
- All <classname>Zend_Form</classname> classes are configurable using
- <classname>Zend_Config</classname>; you can either pass a
- <classname>Zend_Config</classname> object to the constructor or pass it in
- with <methodname>setConfig()</methodname>. Let's look at how we might create the
- above form using an <acronym>INI</acronym> file. First, let's follow the
- recommendations, and place our configurations into sections
- reflecting the release location, and focus on the 'development'
- section. Next, we'll setup a section for the given controller
- ('user'), and a key for the form ('login'):
- </para>
- <programlisting language="ini"><![CDATA[
- [development]
- ; general form metainformation
- user.login.action = "/user/login"
- user.login.method = "post"
- ; username element
- user.login.elements.username.type = "text"
- user.login.elements.username.options.validators.alnum.validator = "alnum"
- user.login.elements.username.options.validators.regex.validator = "regex"
- user.login.elements.username.options.validators.regex.options.pattern = "/^[a-z]/i"
- user.login.elements.username.options.validators.strlen.validator = "StringLength"
- user.login.elements.username.options.validators.strlen.options.min = "6"
- user.login.elements.username.options.validators.strlen.options.max = "20"
- user.login.elements.username.options.required = true
- user.login.elements.username.options.filters.lower.filter = "StringToLower"
- ; password element
- user.login.elements.password.type = "password"
- user.login.elements.password.options.validators.strlen.validator = "StringLength"
- user.login.elements.password.options.validators.strlen.options.min = "6"
- user.login.elements.password.options.required = true
- ; submit element
- user.login.elements.submit.type = "submit"
- ]]></programlisting>
- <para>
- You would then pass this to the form constructor:
- </para>
- <programlisting language="php"><![CDATA[
- $config = new Zend_Config_Ini($configFile, 'development');
- $form = new Zend_Form($config->user->login);
- ]]></programlisting>
- <para>
- and the entire form will be defined.
- </para>
- </sect2>
- <sect2 id="zend.form.quickstart.conclusion">
- <title>Conclusion</title>
- <para>
- Hopefully with this little tutorial, you should now be well on your
- way to unlocking the power and flexibility of
- <classname>Zend_Form</classname>. Read on for more in-depth information!
- </para>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|