Skip to content
taiwen edited this page Mar 14, 2013 · 1 revision

Form handling

In Pi, there are extra files to operate forms, such as file to initialize form, file to validate form. Therefore, we should create some classes to implement them.

Initializing forms

Generally, the add() method in Zend\Form\Form is used to add attributes for creating a form, so we could create a form class inherits from Zend\Form\Form, then call the add() method in init() function.

Supposing we want to create a login form:

namespace Module\Login\Form;

use Pi;
use Pi\Form\Form as BaseForm;
use Zend\Form\Form;
use Zend\Form\Element;

class LoginForm extends BaseForm
{
    public function init()
    {
        // Adding a text form
        $this->add(array(
            'name'          => 'username',
            'attributes'    => array(
                'type'  => 'text',               
            ),
            'options' => array(
                'label' => __('Username'),
            ),
        ));

        // Adding a password form
        $this->add(array(
            'name'          => 'password',
            'attributes'    => array(
                'type'  => 'password',                
            ),
            'options' => array(
                'label' => __('Password'),
            ),
        ));       

        // Adding a submit form
        $this->add(array(
            'name'          => 'submit',
            'attributes'    => array(
                'type'  => 'submit',
                'value' => 'Login',
            )
        ));
    }
}

The value of type field can be changed to create different forms:

// Adding a radio form
$this->add(array(
    'name'          => 'gender',
    'attributes'    => array(         
        'value'   => 'male',
        'options' => array(
            'male'   => __('Male'),
            'female' => __('Female'),
        ),
    ),
    'options'       => array(
        'label' => __('Gender'),
    ),
    'type'    => 'radio',
));

// Adding a file form
$this->add(array(
    'name'          => 'upload',
    'attributes'    => array(
        'type'  => 'file',              
    ),
    'options'       => array(
        'label' => __('Upload'),
    ),
));

// Adding a select form
$this->add(array(
    'name'         => 'country',
    'attributes'   => array(
        'type'    => 'select',               
        'options' => array(
            'CHN'     => __('China'),
            'USA'     => __('United States'),
        ),
    ),
    'options'      => array(
        'label' => 'Your country',
    ),
));               

// Adding a textarea form
$this->add(array(
    'name'          => 'message',
    'attributes'    => array(
        'type'  => 'textarea',
        'cols'  => '50',
        'rows'  => '10',               
    ),
    'options'       => array(
        'label' => __('Your details'),
    ),
));

// Adding a caotcha 
$this->add(array(
    'name'          => 'captcha',
    'type'          => 'captcha',
));

Note:

  1. There should add an options field in attributes array if you want to create a group of radio or checkbox as well as select.

  2. If you use formElement() or formRow() other than methods FormCheckbox to output checkbox and radio form in template, you should move the type field out of attributes array.

For exmple:

$this->add(array(
    'name'         => 'feedback',
    'attributes'   => array(
        'value' => '0',
    ),
    'options'       => array(
        'label' => __('Do you want to recieve our email?'),
    ),
    'type'  => 'checkbox', 
));

Creating Form instance

We now have initialized the form attribute, if you want to display a form, you should instantiate it in controller. You can add the following codes in you controller:

use Module\Login\Form\LoginForm;
...

public function indexAction()
{
    $form = new loginForm('login');
    $form->setAttribute('action', $this->url('', array('action' => 'process')));
    ...
}

The setAttribute() method helps to set the action url, you can use url() plugin to generate a url.

Displaying Forms

If you have create a form instance and assign it to a variable, suppose it is form, you can use this variable to display forms, there are mainly three methods to display forms:

  1. Displaying forms as well as label, for example: echo $this->formRow($form);
  2. Displaying more particularily, for example:
  • Displaying a text: echo $this->formInput($form);
  • Displaying a select: echo $this->formSelect($form);
  1. Displaying generally, for example: echo $this->formElement($form);

The code are:

<?php echo $this->form()->openTag($form); ?>

<!-- Displaying form as well as label -->
<div id='username'>
<?php $element = $form->get('username'); ?>      
    <div><?php
        echo $this->formRow($element); 
        echo $this->formElementErrors($element);
    ?></div>
</div>

<!-- Displaying more particularily -->
<div id='username'>
<?php $element = $form->get('username'); ?>
    <div><?php echo $this->formLabel($element); ?></div>
    <div><?php
        echo $this->formInput($element); 
        echo $this->formElementErrors($element);
    ?></div>
</div>

<!-- Displaying generally -->
<div id='submit'>
<?php $element = $form->get('submit'); ?>
    <div><?php 
        echo $this->formElement($element); 
        echo $this->formElementErrors($element);
    ?></div>
</div>

<?php echo $this->form()->closeTag(); ?>

Note: if formRow() method is used, you do not need to call formLabel() to output label.

Adding editor

Pi provides several types of editor for you to edit long text, the usage of editor is the same as other form elements, you should only change the type value, and add some attributes:

$this->add(array(
    'name'          => 'editor',
    'attributes'    => array(
        'type'  => 'editor',
    ),
    'options'       => array(
        'label'  => __('Editor'),
        'set'    => '',
        'editor' => 'html',
    ),
));

In the array, the type field is assigned with a value editor, this helps add an editor; the set field and the editor is a group of attributes, their value and function are list as:

Type $editor $set Description
html html '' HTML syntax is allowed
compound markitup 'html' Compound block, HTML and following syntx allowed: %block.name.title%, %block.name.content%, %block.name.link%, %block.name.class%
markdown markitup 'markdown' Markdown syntax is allowed
default textarea '' Only plain text is allowed

After initilized the form instance, you can use formElement() to display the editor in template.

Creating form filter and validator

This part we will introduce how to create a form filter and validator, it has the same operation as creating a form, you should intialize the attributes of filter and validator first, and then add the validation code in controller.

For example, initializing a filter and validator:

$this->add(array(
    'name'          => 'username',
    'required'      => true,
    'filters'       => array(
        array(
            'name'         => 'StringTrim',
        ),
    ),
    'validators'    => array(
        array(
            'name'         => 'Regex',
            'options'      => array(
                'pattern'       => '/^[a-zA-Z0-9][a-zA-Z0-9-_]{0,24}$/',
            ), 
        ),
        // Adding another validator 
        new StringLength(array(
            'min'          => '4',
            'max'          => '25',
        )),
    ),
));

In this code, the required field tells that whether the form needs an input data. The StringTrim in filters array tells that the form data will be trimmed. The Regex field in validators array allows you to standardize the input according to regular expression. If you want add another validator, you can instantiate an object, such as new StringLength, this object will restrict the input length by fields min and max.

Note: you can also add yourselves validators by this way, but you should implement the codes of validator first.

Now you can instantiate the filter object and add the validation code in controller:

$post = $this->request->getPost();
$form = new LoginForm('login');

$form->setData($post);
$form->setInputFilter(new LoginFilter);
if(!$form->isValid()) {
    // do something     
}
$values = $form->getData();

The getPost() method gets the form data by POST method. The setData() method sets the post data for filtering and validating. Here we should instantiate the filter object first and then use the isValid() method to check whether the input data are valid. The getData() method will return the filtered data.

Clone this wiki locally