Per form stylesheet with Zend_Form

March 1, 2010 in Zend Framework

I needed to have certain form styles attached when a form is in use. I didn’t want to do this from the controller each and every time as it was really was only to do with the form and I might want to use the form with it’s own stylesheet in other places.

The Solution

The solution is to extend Zend_form and use the extended version as the basis for all the forms in the application. Here is my Form class.

<?php
class BinaryKitten_Form extends Zend_Form
{
    private $_stylesheets = array(
        'main'=>array('href'=>'/css/form.css', 'media'=>'screen')
    );

    public function addStylesheet($href,$media='screen')
    {
        $this->_stylesheets[basename($href)] = array(
            "href"=>$href,
            "media"=>$media
        );
    }

    public function removeStylesheet($href)
    {
        unset($this->_stylesheets[basename($href)]);
    }

    public function clearStylesheets()
    {
        $this->_stylesheets = array();
    }

    public function render(Zend_View_Interface $view = null)
    {
        if (null !== $view) {
            $this->setView($view);
        }
        else {
            $view = $this->getView();
        }

        foreach ($this->_stylesheets as $stylesheet) {
            $view->headLink()->appendStylesheet($stylesheet['href'], $stylesheet['media']);
        }

        $content = '';
        foreach ($this->getDecorators() as $decorator) {
            $decorator->setElement($this);
            $content = $decorator->render($content);
        }
        return $content;
    }
}

Of course you would extend it as usual to create a new form….

<?php
class BinaryKitten_Form_LoginForm extends BinaryKitten_Form
{
    public function __construct($option = null)
    {
        parent::__construct($option);
        $decorators = array(
            array('ViewHelper'),
            array('Label', array(
                'requiredSuffix'=>" *"
            )),
            array('HtmlTag', array('tag'=>'div'))
        );

        $username = new Zend_Form_Element_Text('username');
        $username
            ->setLabel('Username')
            ->setRequired(true)
            ->addValidator('NotEmpty', true)
            ->addFilter("StringTrim")
            ->addErrorMessage('Please Enter your Username')
            ->setDecorators($decorators);

        $password = new Zend_Form_Element_Password('password');
        $password
            ->setLabel('Password')
            ->setRequired(true)
            ->addValidator('NotEmpty', true)
            ->addFilter("StringTrim")
            ->addErrorMessage('Please Enter your Password')
            ->setDecorators($decorators);

        $loginButton = new Zend_Form_Element_Submit('login');
        $loginButton
            ->setValue('login');

        $this
            ->addElements(
                array(
                    $username,
                    $password,
                    $loginButton
                )
            )
            ->setMethod('post')
            ->setName('loginForm')
            ->addDecorator(
                array('mytag' => 'HtmlTag'), array('tag' => 'div')
            )
            ->removeDecorator('HtmlTag');

        $this->addStylesheet('/css/loginform.css','screen');
    }
}

And then as usual in you controller:

$form = new BinaryKitten_Form_LoginForm();
$this->view->form = $form;

and of course, echo it out in the view
[sourcecoe lang="php"]
echo $this->form;
[/sourcecode]

And that’s it, Simple.
Hopefully this will help someone out there