Per form stylesheet with Zend_Form

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

2 comments

  1. Jason Foo says:

    would you mind posting the content of your loginform.css as well? I’m still not quite sure how the element’s name maps to the css name?

  2. BinaryKitten says:

    my loginform.css cotains this:

    div.right { width: 310px; text-align: right;}
    label { float: left; display: block; width: 90px; padding-right: 10px; text-align: right;}

    my main form.css contains this:

    ul.errors {margin: 0; margin-bottom: 10px;margin-left: 10px;}
    ul.errors li { color: red; }
    .ui-widget ul.errors { list-style-type: none; }
    input[type=submit] { margin-top: 5px; margin-left: 10px;}

    Though for linking, Zend_Form_Elements usually use the name as the id as well, unless you change it using the attributes setter.

Leave a Reply

Your email address will not be published. Required fields are marked *

*