icingaweb2/doc/form.md

4.5 KiB

Forms

Abstract

This document describe how to develop forms in Icinga 2 Web. This is important if you want to write modules or extend Icinga 2 Web with your flavour of code.

Architecture

Forms are basically Zend_Form classes with Zend_Form_Element items as controls. To ensure common functionallity and control dependent fields Icinga 2 Web provides sub classes to build forms on that.

Basic form design

(Methods and attributes are exemplary and does not reflect the full class implementation)

Key design

Build of forms

Creating elements is done within protected function create() of your subclass. In here you can add elements to your form, add validations and filters of your choice. The creation method is invoked lazy just before a form is rendered or isValid() is called.

Calling is IsPostAndValid()

IsPostAndValid() is used to test of all needed parameters there. It combines testing for post request and pulls out the data from request object to handle over an array for Zend native method isValid()

Pre validation

To handle dependend fields you can just override preValid() or postValid() to dynamically add or remove validations. This behaviour reduces the overhead to write own validator classes.

  • preValidation() Work just before pre validation

Autoloading of form code

Because of forms are no library code we need to put them into application code. The application or the module has an reserved namespace for forms which loads code from special directories:

application/forms/Test/MyForm.phpmodules/forms/Test.php
Class name File path
\Icinga\Form\Test\MyForm
\MyModule\Form\Test

If you want to create custom elements or organize library code in form context use an other namesoace for, e.g.

\Icinga\Web\Form\Element\MySpecialElement
\MyModule\Web\Form\Element\FancyDatePicker

Example implementation

namespace MyModule\Form;

use Icinga\Web\Form;

class TestForm extends Form
{
    /**
     * Add elements to this form (used by extending classes)
     */
    protected function create()
    {
        $this->addElement(
            'checkbox',
            'flag',
            array(
                'label' => 'Check this box to user feature 1'
            )
        );

        $this->addElement(
            'text',
            'flagValue',
            array(
                'label' => 'Enter text'
            )
        );
    }

    /**
     * Check dependent fields
     * @param array $data
     */
    protected function preValidation(array $data)
    {
        if (isset($data['flag']) && $data['flag'] === '1') {
            $textField = $this->getElement('flagValue');
            $textField->setRequired(true);

            $textField->addValidator(
                'alnum',
                true,
                array(
                    'allowWhitespace' => true
                )
            );
        }
    }
}

The example above adds to elements to the form: A checkbox and a textfield. The function preValid() set the textfield required if checkbox was checked before.

Full overriding example

The following example shows form with most usefull method utilization of interface methods:

namespace MyModule\Form;

use Icinga\Web\Form;

class TestForm extends Form
{
    /**
     * When sub-classing replace the constructor
     */
    public function init()
    {
        // Do some initializing work here if needed
    }

    /**
     * Add elements to this form (used by extending classes)
     */
    protected function create()
    {
        // Add elements to form
    }

    /**
     * Pre validation
     * @param array $data
     */
    protected function preValidation(array $data)
    {
        // Add depending filters or validation here
    }
}

Additional resources