Zend Framework форма с использованием Bootstrap

Zend Framework форма с использованием Bootstrap
Для того, чтобы показать как работают стандартные декораторы формы на примере, я решил реализовать вполне реальную задачу: стилизировать форму используя Bootstrap.

Что такое Bootstrap?

Если Вы еще не знаете, что такое Bootstrap, попробую объяснить в двух словах. Bootstrap — это простой и легко настраиваемый HTML, CSS и Javascript фреймворк для более быстрой и удобной Web-разработки. Он содержит большое число компонентов, которые могут быть быть использованы почти в любом проекте. Bootstrap можно использовать как каркас для разработки фронтэнд части приложения. Подробнее читайте на официальном сайте Bootstrap.

Для начала создадим класс формы, в котором опишем основные элементы горизонтальной формы: поле ввода логина (email), поле ввода пароля, чекбокс Remember me и submit-кнопка.

class Default_Form_Bootstrap extends Zend_Form
{

    public function init()
    {

        $login = new Zend_Form_Element_Text('login');
        $login->setRequired('true')
                ->setLabel('Email:');

        $password = new Zend_Form_Element_Password('password');
        $password->setRequired('true')
                ->setLabel('Password:');

        $rememberMe = new Zend_Form_Element_Checkbox('remember_me');
        $rememberMe->setLabel('Remember me');

        $submit = new Zend_Form_Element_Submit('sign_in');
        $submit->setLabel('Sign In');

        $this->addElements(array($login, $password, $rememberMe, $submit));
    }

}
<form enctype="application/x-www-form-urlencoded" action="" method="post">
<dl class="zend_form">
<dt id="login-label">
        <label for="login" class="required">Email:</label>
        </dt>
<dd id="login-element">
            <input type="text" name="login" id="login" value="">
        </dd>
<dt id="password-label">
        <label for="password" class="required">Password:</label>
        </dt>
<dd id="password-element">
            <input type="password" name="password" id="password" value="">
        </dd>
<dt id="remember_me-label">
        <label for="remember_me" class="optional">Remember me</label>
        </dt>
<dd id="remember_me-element">
            <input type="hidden" name="remember_me" value="0"><input type="checkbox" name="remember_me" id="remember_me" value="1">
        </dd>
<dt id="sign_in-label"> </dt>
<dd id="sign_in-element">
            <input type="submit" name="sign_in" id="sign_in" value="Sign In">
        </dd>
</dl>
</form>

Теперь разберемся с формой. Избавимся от оборачивания содержимого формы в тег dl. Т.к. за это отвечает декоратор HtmlTag, необходимо отказаться от его использования. Поэтому зададим форме два декоратора FormElements и Form. А еще необходимо задать класс .form-horizontal форме и установить атрибут

role="form"

.

class Default_Form_Bootstrap extends Zend_Form
{

    public function init()
    {
        $this->setAttribs(array('class' => 'form-horizontal', 'role' => 'form'))
                ->setDecorators(array('FormElements', 'Form'));

        $login = new Zend_Form_Element_Text('login');
        $login->setRequired('true')
                ->setLabel('Email:');

        $password = new Zend_Form_Element_Password('password');
        $password->setRequired('true')
                ->setLabel('Password:');

        $rememberMe = new Zend_Form_Element_Checkbox('remember_me');
        $rememberMe->setLabel('Remember me');

        $submit = new Zend_Form_Element_Submit('sign_in');
        $submit->setLabel('Sign In');

        $this->addElements(array($login, $password, $rememberMe, $submit));
    }

}
<form enctype="application/x-www-form-urlencoded" class="form-horizontal" role="form" action="" method="post">
<dt id="login-label">
    <label for="login" class="required">Email:</label>
    </dt>
<dd id="login-element">
        <input type="text" name="login" id="login" value="">
    </dd>
<dt id="password-label">
    <label for="password" class="required">Password:</label>
    </dt>
<dd id="password-element">
        <input type="password" name="password" id="password" value="">
    </dd>
<dt id="remember_me-label">
    <label for="remember_me" class="optional">Remember me</label>
    </dt>
<dd id="remember_me-element">
        <input type="hidden" name="remember_me" value="0">
        <input type="checkbox" name="remember_me" id="remember_me" value="1">
    </dd>
<dt id="sign_in-label"> </dt>
<dd id="sign_in-element">
        <input type="submit" name="sign_in" id="sign_in" value="Sign In">
    </dd>
</form>

Зададим базовые декораторы, которые необходимы для всех элементов формы: ViewHelper и HtmlTag, причем как видно в примере, HtmlTag должен оборачивать контент в тег div с классом .form-group. Также, присвоим класс .form-control полям ввода.

<?php

class Default_Form_Bootstrap extends Zend_Form
{

    private $baseElementDecorators = array(
        'ViewHelper',
        array('HtmlTag', array('tag' => 'div', 'class' => 'form-group'))
    );

    public function init()
    {
        $this->setAttribs(array('class' => 'form-horizontal', 'role' => 'form'))
                ->setDecorators(array('FormElements', 'Form'));

        $login = new Zend_Form_Element_Text('login');
        $login->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Email:')
                ->setDecorators($this->baseElementDecorators);

        $password = new Zend_Form_Element_Password('password');
        $password->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Password:')
                ->setDecorators($this->baseElementDecorators);

        $rememberMe = new Zend_Form_Element_Checkbox('remember_me');
        $rememberMe->setLabel('Remember me')
                ->setDecorators($this->baseElementDecorators);

        $submit = new Zend_Form_Element_Submit('sign_in');
        $submit->setLabel('Sign In')
                ->setDecorators($this->baseElementDecorators);

        $this->addElements(array($login, $password, $rememberMe, $submit));
    }

}
<form enctype="application/x-www-form-urlencoded" class="form-horizontal" role="form" action="" method="post">
<div class="form-group">
        <input type="text" name="login" class="form-control" id="login" value="">
    </div>
<div class="form-group">
        <input type="password" name="password" class="form-control" id="password" value="">
    </div>
<div class="form-group">
        <input type="hidden" name="remember_me" value="0"><input type="checkbox" name="remember_me" id="remember_me" value="1">
    </div>
<div class="form-group">
        <input type="submit" name="sign_in" id="sign_in" value="Sign In">
    </div>
</form>

Теперь оотбразим лэйблы для полей ввода. Для этого воспользуемся декоратором Label. Также сразу определим необходимые классы для него. Обратите внимание на теги, которые оборачивают поля ввода. Для того, чтобы добиться такого порядка вложенности тегов, необходимо последовательно применить декораторы: ViewHelper, Label, HtmlTag.

<?php

class Default_Form_Bootstrap extends Zend_Form
{

    private $baseElementDecorators = array(
        'ViewHelper'
    );
    private $htmlTagBaseDecorator = array(array('HtmlTag', array('tag' => 'div', 'class' => 'form-group')));
    private $inputDecorators = array(
                    array(
                        'Label',
                        array('class' => 'col-sm-2 control-label')
                        )
                    );

    public function init()
    {
        $this->setAttribs(array('class' => 'form-horizontal', 'role' => 'form'))
                ->setDecorators(array('FormElements', 'Form'));

        $login = new Zend_Form_Element_Text('login');
        $login->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Email:')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->inputDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $password = new Zend_Form_Element_Password('password');
        $password->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Password:')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->inputDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $rememberMe = new Zend_Form_Element_Checkbox('remember_me');
        $rememberMe->setLabel('Remember me')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $submit = new Zend_Form_Element_Submit('sign_in');
        $submit->setLabel('Sign In')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $this->addElements(array($login, $password, $rememberMe, $submit));
    }

}
<form enctype="application/x-www-form-urlencoded" class="form-horizontal" role="form" action="" method="post">
<div class="form-group"><label for="login" class="col-sm-2 control-label required">Email:</label>
        <input type="text" name="login" class="form-control" id="login" value="">
    </div>
<div class="form-group"><label for="password" class="col-sm-2 control-label required">Password:</label>
        <input type="password" name="password" class="form-control" id="password" value="">
    </div>
<div class="form-group">
        <input type="hidden" name="remember_me" value="0"><input type="checkbox" name="remember_me" id="remember_me" value="1">
    </div>
<div class="form-group">
        <input type="submit" name="sign_in" id="sign_in" value="Sign In">
    </div>
</form>

Поля ввода необходимо отдельно обернуть в div c классом col-sm-10. Для этого необходимо применить декоратор HtmlTag. Т.к. HtmlTag оборачивает весь контент элемента, применим декоратор в тот момент, когда сгенерируется только контент
<input type="text" name="login" class="form-control" id="login" value=""> т.е. после декоратора ViewHelper.

class Default_Form_Bootstrap extends Zend_Form
{

    private $baseElementDecorators = array(
        'ViewHelper'
    );
    private $htmlTagBaseDecorator = array(array('HtmlTag', array('tag' => 'div', 'class' => 'form-group')));
    private $inputDecorators = array(
                    array(
                        array('data' => 'HtmlTag'), array('tag' => 'div', 'class' => 'col-sm-10')
                    ),
                    array(
                        'Label',
                        array('class' => 'col-sm-2 control-label')
                        )
                    );

    public function init()
    {
        $this->setAttribs(array('class' => 'form-horizontal', 'role' => 'form'))
                ->setDecorators(array('FormElements', 'Form'));

        $login = new Zend_Form_Element_Text('login');
        $login->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Email:')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->inputDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $password = new Zend_Form_Element_Password('password');
        $password->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Password:')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->inputDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $rememberMe = new Zend_Form_Element_Checkbox('remember_me');
        $rememberMe->setLabel('Remember me')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $submit = new Zend_Form_Element_Submit('sign_in');
        $submit->setLabel('Sign In')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $this->addElements(array($login, $password, $rememberMe, $submit));
    }

}
<form enctype="application/x-www-form-urlencoded" class="form-horizontal" role="form" action="" method="post">
<div class="form-group">
        <label for="login" class="col-sm-2 control-label required">Email:</label>

<div class="col-sm-10">
            <input type="text" name="login" class="form-control" id="login" value="">
        </div>

</div>
<div class="form-group">
        <label for="password" class="col-sm-2 control-label required">Password:</label>

<div class="col-sm-10">
            <input type="password" name="password" class="form-control" id="password" value="">
        </div>

</div>
<div class="form-group">
        <input type="hidden" name="remember_me" value="0"><input type="checkbox" name="remember_me" id="remember_me" value="1">
    </div>
<div class="form-group">
        <input type="submit" name="sign_in" id="sign_in" value="Sign In">
    </div>
</form>

Теперь займемся декорированием чекбокса. Т.к. поместить input внутри label не выйдет, придется заменить метод setLabel на setDescription и убрать оборачивание в тег описания, задав опцию tag=false. Оборачивания чекбокса добиваемся при помощи декоратора HtmlTag, у которого опция

tag="label"

. По аналогии с полями ввода, применяем еще два декоратора типа HtmlTag.

class Default_Form_Bootstrap extends Zend_Form
{

    private $baseElementDecorators = array(
        'ViewHelper'
    );
    private $htmlTagBaseDecorator = array(array('HtmlTag', array('tag' => 'div', 'class' => 'form-group')));
    private $inputDecorators = array(
                    array(
                        array('data' => 'HtmlTag'), array('tag' => 'div', 'class' => 'col-sm-10')
                    ),
                    array(
                        'Label',
                        array('class' => 'col-sm-2 control-label')
                        )
                    );

    public function init()
    {
        $this->setAttribs(array('class' => 'form-horizontal', 'role' => 'form'))
                ->setDecorators(array('FormElements', 'Form'));

        $login = new Zend_Form_Element_Text('login');
        $login->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Email:')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->inputDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $password = new Zend_Form_Element_Password('password');
        $password->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Password:')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->inputDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $rememberMe = new Zend_Form_Element_Checkbox('remember_me');
        $rememberMe->setDescription('Remember me')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators(array(
                    array('Description', array('tag' => false)),
                    array(array('Input' => 'HtmlTag'), array('tag' => 'label')),
                    array(array('Checkbox' => 'HtmlTag'), array('tag' => 'div', 'class' => 'checkbox')),
                    array(array('Data' => 'HtmlTag'), array('tag' => 'div', 'class' => 'col-sm-offset-2 col-sm-10'))
                    ))
                ->addDecorators($this->htmlTagBaseDecorator);

        $submit = new Zend_Form_Element_Submit('sign_in');
        $submit->setLabel('Sign In')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $this->addElements(array($login, $password, $rememberMe, $submit));
    }

}
<form enctype="application/x-www-form-urlencoded" class="form-horizontal" role="form" action="" method="post">
<div class="form-group">
        <label for="login" class="col-sm-2 control-label required">Email:</label>

<div class="col-sm-10">
            <input type="text" name="login" class="form-control" id="login" value=""></div>

</div>
<div class="form-group">
        <label for="password" class="col-sm-2 control-label required">Password:</label>

<div class="col-sm-10">
            <input type="password" name="password" class="form-control" id="password" value=""></div>

</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
                <label>
                    <input type="hidden" name="remember_me" value="0">
                    <input type="checkbox" name="remember_me" id="remember_me" value="1">Remember me</label>
            </div>

</div>

</div>
<div class="form-group">
        <input type="submit" name="sign_in" id="sign_in" value="Sign In">
    </div>
</form>

Ну, и остается последний штрих — кнопка. Добавляем ей класс, а также применяем два декоратора HtmlTag, чтобы обернуть кнопку в div‘ы.

class Default_Form_Bootstrap extends Zend_Form
{

    private $baseElementDecorators = array(
        'ViewHelper'
    );
    private $htmlTagBaseDecorator = array(array('HtmlTag', array('tag' => 'div', 'class' => 'form-group')));
    private $inputDecorators = array(
                    array(
                        array('data' => 'HtmlTag'), array('tag' => 'div', 'class' => 'col-sm-10')
                    ),
                    array(
                        'Label',
                        array('class' => 'col-sm-2 control-label')
                        )
                    );

    public function init()
    {
        $this->setAttribs(array('class' => 'form-horizontal', 'role' => 'form'))
                ->setDecorators(array('FormElements', 'Form'));

        $login = new Zend_Form_Element_Text('login');
        $login->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Email:')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->inputDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $password = new Zend_Form_Element_Password('password');
        $password->setRequired('true')
                ->setAttrib('class', 'form-control')
                ->setLabel('Password:')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators($this->inputDecorators)
                ->addDecorators($this->htmlTagBaseDecorator);

        $rememberMe = new Zend_Form_Element_Checkbox('remember_me');
        $rememberMe->setDescription('Remember me')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorators(array(
                    array('Description', array('tag' => false)),
                    array(array('Input' => 'HtmlTag'), array('tag' => 'label')),
                    array(array('Checkbox' => 'HtmlTag'), array('tag' => 'div', 'class' => 'checkbox')),
                    array(array('Data' => 'HtmlTag'), array('tag' => 'div', 'class' => 'col-sm-offset-2 col-sm-10'))
                    ))
                ->addDecorators($this->htmlTagBaseDecorator);

        $submit = new Zend_Form_Element_Submit('sign_in');
        $submit->setLabel('Sign In')
                ->setAttrib('class', 'btn btn-default')
                ->setDecorators($this->baseElementDecorators)
                ->addDecorator(array('Button' => 'HtmlTag'), array('tag' => 'div', 'class' => 'col-sm-offset-2 col-sm-10'))
                ->addDecorators($this->htmlTagBaseDecorator);

        $this->addElements(array($login, $password, $rememberMe, $submit));
    }

}
<form enctype="application/x-www-form-urlencoded" class="form-horizontal" role="form" action="" method="post">
<div class="form-group">
        <label for="login" class="col-sm-2 control-label required">Email:</label>

<div class="col-sm-10">
            <input type="text" name="login" class="form-control" id="login" value=""></div>

</div>
<div class="form-group">
        <label for="password" class="col-sm-2 control-label required">Password:</label>

<div class="col-sm-10">
            <input type="password" name="password" class="form-control" id="password" value=""></div>

</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
                <label>
                    <input type="hidden" name="remember_me" value="0">
                    <input type="checkbox" name="remember_me" id="remember_me" value="1">Remember me</label>
            </div>

</div>

</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
            <input type="submit" name="sign_in" id="sign_in" value="Sign In" class="btn btn-default">
        </div>

</div>
</form>

А вот и результат.
bootstrap-zend-form
По желанию добавляем недостающие атрибуты (id, placeholder и прочие параметры) и на этом все.

Stas Kuryan

Web developer. Перфекционист в написании кода.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *