Zend Framework

Criando componentes HTML do Bootstrap com Zend\Form

Por em

Sobre o que é este tutorial

No post passado, falei de como gerenciar um menu pelo back-end, usando Zend\Navigation e Bootstrap, mas, há muitos programadores que se perguntam:

É possível renderizar no HTML componentes do Bootstrap também gerenciado pelo back-end?

Eu digo: Tem sim e é muito simples! Ás vezes por falta de conhecimento ou preguiça, acabamos por fazer muitas coisas no HTML esquecendo que no caso do Zend Framework 2, ou com a orientação por objetos, podemos estruturar um código para ser reaproveitado, este é o ponto.

É rápido realmente chegar no HTML e criar um botão ou um checkbox, mas e se nossa aplicação precisar reaproveitar aquele componente? Precisaríamos copiar e colar em toda parte, tornando esta ação chata, passível de erros e de difícil manutenção.

Não, isto não é legal, temos sempre que lembrar do conceito de reuso de código. Assim, o Zend Framework 2 traz um pacote que nos permite fazer isto, que é o Zend\Form; com ele, podemos criar formulários e componentes HTML e HTML5 em PHP, nos garantindo o reuso de código e estrutura para montagem dos componentes HTML da aplicação.

Neste tutorial, mostrarei como montar componentes do Bootstrap no Zend Framework 2. Como sabemos que o ZF 2 já vem configurado para trabalhar com Bootstrap, é mais fácil renderizar componentes do Bootstrap com ele, porém temos que normalmente utilizar mais código para esse tipo de tarefa, portanto, mostrarei uma outra maneira de fazer isto usando menos código e ainda e com mais funcionalidades.

Qual é a ideia?

A ideia é usar uma biblioteca de terceiro, chamada TwbBundle, que já traz uma série de facilidades para montagem dos componentes do Bootstrap, além de usar alguns View Helpers para facilitar também nossa vida como labels, alerts, etc.

O que faremos?

  1. Instalar e configurar o esqueleto do Zend Framework 2 em nossa máquina.
  2. Instalar o TwbBundle.
  3. Criar alguns elementos do Bootstrap com TwbBundle.
  4. Testar o que fizemos. 

Passos

  1. Instalar o esqueleto do Zend Framework 2 em nossa máquina (instalaremos via git).

Veja como instalar o Zend Framework 2

  1. Instalar o TwbBundle.

Para instalar o TwbBundle, abra seu terminal e digite:

composer require neilime/zf2-twb-bundle:2.*@stable

Isto irá instalar a versão estável mais alta dentro da versão 2 da biblioteca. Agora é só adicionar TwbBundle para o arquivo config/application.config.php na key ‘modules’.

Pronto! Está tudo instalado e configurado.

  1. Criar alguns elementos do Bootstrap com TwbBundle

Como o esqueleto do Zend Framework 2 já traz um módulo padrão chamado Application, usarei este módulo para mostrar alguns componentes Bootstrap que podemos criar.

Todas as renderizações estarão em ./module/Application/view/application/index/index.phtml.

3.1 – Formulário Horizontal

Esta biblioteca nos permite renderizar um formulário inteiro na horizontal nos moldes do Bootstrap, ou seja, já com envolvendo os campos com div.form-group e label.control-label, por padrão isto teria que ser feito na mão ou ser criado um View Helper específico. Esta estrutura nos permite renderizar erros de HTML logo abaixo do campo.

No caso do formulário criei um Zend\Form a parte apenas estruturar os campos:

<?php
namespace Application\Form;

use Zend\Form\Form;

class HorizontalForm extends Form
{

    public function __construct()
    {
        parent::__construct();

        $this->add([
            'name' => 'id',
            'type' => 'Text',
            'options' => [
                'label' => 'ID'
            ]
        ]);

        $this->add([
            'name' => 'nome',
            'type' => 'Select',
            'options' => [
                'label' => 'Nome',
                'value_options' => [
                    0 => 'Fulano',
                    1 => 'Cicrano'
                ]
            ]
        ]);

        $this->add([
            'name' => 'marque',
            'type' => 'Checkbox',
            'options' => [
                'label' => 'Marque esta opção'
            ]
        ]);

        $this->add([
            'name' => 'cor',
            'type' => 'Radio',
            'options' => [
                'label' => 'Escolha uma cor',
                'value_options' => [
                    0 => 'Verde',
                    1 => 'Branco'
                ]
            ]
        ]);

        $this->add([
            'name' => 'submit',
            'type' => 'Button',
            'options' => [
                'label' => 'Enviar'
            ]
        ]);
    }
}

Agora é só instanciar o formulário no controller e passa-lo para o template:

$horizontalForm = new HorizontalForm();
return new ViewModel([
    'horizontalForm' => $horizontalForm
]);

No template vamos renderizar o formulário usando o $this->form:

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

formulario-horizontal

É necessário usar o método prepare() sempre antes de renderizar o formulário para concretizar todas as configurações necessárias à ele.

3.2 –  Formulário em Linha

Valendo a mesma regra que o formulário horizontal, porém, os campos serão ajustados em uma só linha na tela. Não coloquei labels nos campos, porque esta versão do TwbBundle renderiza-os causando uma desalinhamento por causa do CSS. Esta estrutura nos permite renderizar erros de HTML logo abaixo do campo.

Para o formulário em linha a mesma coisa:

<?php
namespace Application\Form;

use Zend\Form\Form;

class InlineForm extends Form
{

    public function __construct()
    {
        parent::__construct();

        $this->add([
            'name' => 'id',
            'type' => 'Text'
        ]);

        $this->add([
            'name' => 'nome',
            'type' => 'Select',
            'options' => [
                'value_options' => [
                    0 => 'Fulano',
                    1 => 'Cicrano'
                ]
            ]
        ]);

        $this->add([
            'name' => 'marque',
            'type' => 'Checkbox',
            'options' => [
                'label' => 'Marque aqui'
            ]
        ]);

        $this->add([
            'name' => 'cor',
            'type' => 'Radio',
            'options' => [
                'value_options' => [
                    0 => 'Verde',
                    1 => 'Branco'
                ]
            ]
        ]);

        $this->add([
            'name' => 'submit',
            'type' => 'Button',
            'options' => [
                'label' => 'Enviar'
            ]
        ]);
    }
}
$inlineForm = new InlineForm();
return new ViewModel([
    'inlineForm' => $inlineForm
]);

No template vamos renderizar o formulário, usando o $this->form e passando como segundo parâmetro a constante para informar que queremos a renderização em linha: TwbBundle\Form\View\Helper\TwbBundleForm::LAYOUT_INLINE:

<?php $this->inlineForm->prepare(); ?>
<?php echo $this->form($this->inlineForm, TwbBundle\Form\View\Helper\TwbBundleForm::LAYOUT_INLINE); ?>

formulario-em-linha

3.3 – Campo simples

Renderiza somente o campo HTML, sem div e sem label. Criei o elemento no controller, agora basta usar o $this->formElement:

use Zend\Form\Element;
$txtNome = new Element\Text('txtNome');
$txtNome->setLabel('Nome');
return new ViewModel([
    'txtNome' => $txtNome
]);
<?php echo $this->formElement($this->txtNome); ?>

campo-simples

3.4 – Campo envolto

Renderiza o campo HTML envolto de div.form-group e label.control-label. Esta estrutura nos permite renderizar erros de HTML logo abaixo do campo. Como já temos o txtNome, basta fazer a renderização com o $this->formRow:

<?php echo $this->formRow($this->txtNome); ?>

Campo-envoltado

3.5 – Grupo de botões

Cria um grupo de botões alinhados, é só passar um array de botões. É bastante simples, na mão daria bem mais trabalho. Da mesma forma criei os botões no controller, agora é só usar o $this->buttonGroup, passar os botões como array no primeiro parâmetro e o alinhamento do Bootstrap no segundo:

use Zend\Form\Element;
$btnGroup1=new Element\Button('btnGroup1');
$btnGroup1->setLabel('Esquerda');
$btnGroup2=new Element\Button('btnGroup2');
$btnGroup2->setLabel('Centro');
$btnGroup3=new Element\Button('btnGroup3');
$btnGroup3->setLabel('Direita');
return new ViewModel([
    'btnGroup1' => $btnGroup1,
    'btnGroup2' => $btnGroup2,
    'btnGroup3' => $btnGroup3
]);
<?php echo $this->buttonGroup([$this->btnGroup1, $this->btnGroup2, $this->btnGroup3], ['class' => 'pull-right']); ?>

grupo-de-botoes

3.6 – Botão com lista suspensa

Uma das funcionalidades que eu mais gosto. Ele cria um dropdown ou botão de lista suspensa. Muitas vezes criar um botão é chato, porque se tem que lembrar da estrutura HTML para cria-lo e eu acabo sempre consultando a documentação do Bootstrap para ver como é. Ele tem uma gama de opções, permite adicionar evento de click em todos os níveis do dropdown. Criei o campo no controller, agora é usar o $this->formButton para renderizar:

use Zend\Form\Element;
$dropDown=new Element\Button('dropDown');
$dropDown->setOptions([
    'label' => "Salvar e Concluir",
    'glyphicon' => 'new-window',
    'dropdown' => [
        'split' => true,
        'dropup' => true,
        'items' => [
            [
                'label' => 'Salvar',
                'item_attributes' => [
                    'title' => 'Salvar',
                ]
            ],
            [
                'label' => 'Salvar e Incluir',
                'item_attributes' => [
                    'title' => 'Salvar e Incluir um Novo',
                ]
            ],
        ]
    ]
]);
return new ViewModel([
    'dropDown' => $dropDown
]);

<?php echo $this->formButton($this->dropDown); ?>

botao-lista-suspensa

Veja que praticamente todas as configurações ficam na instância Element\Button e que é possível configurar uma gama de opção: ícones, ações, title, etc.

3.7 – Campo agregado

Outra funcionalidade muito bacana. Adicionar algo na frente ou atrás do campo. É chato também consultar a documentação para ver a estrutura, mas com TwbBundle é simples. Do mesmo jeito criei o campo no controller, aí é só renderizar com $this->formElement:

$inputGroup = new Element\Text('inputGroup',['add-on-prepend' => 'R$']);
$inputGroup->setLabel('Preço');
return new ViewModel([
    'dropDown' => $dropDown
]);
<?php echo $this->formElement($this->inputGroup); ?>

campo-agregado

3.8 – Mensagem

 Uma mão na roda. Reduz bastante o código para renderizar nossas famosas alerts. Basta usar no template $this->alert:

<?php echo $this->alert('Minha mensagem', ['class' => 'alert-success']); ?>

mensagem

Para mudar a cor da mensagem basta substituir o class por outra classe CSS do Bootstrap.

3.9 – Rótulos

 Outra mão na roda. Fica bastante simples renderizar labels na tela. Basta usar no template $this->label:

<?php echo $this->label('Meu Label', ['class' => 'label-primary']); ?>

rotulos

A mesma regra do alert, só mudar o class de acordo com as classes de labels que o Bootstrap provém.

3.10 – Glyphicon

Outra que acho bacana também, é a possibilidade de renderizar Glyphicon rapidamente sem precisar digitar praticamente nada. Basta usar no template:

<?php echo $this->glyphicon('star', ['class' => 'pull-left']); ?>

glyphicon

A mesma regra do alert, só mudar o class de acordo com os ícones provenientes do Glyphicon, ainda tem a facilidade que não precisa colocar o nome do Glyphicon completo.

  1. Testar o que fizemos

Para testar o que fizemos usaremos o php built-in-server para executar a aplicação no nosso browser. Faça em seu terminal:

php -S localhost:9999 -t public public/index.php

Agora é só abrir seu browser e digitar localhost:9999. Já quando acessarem poderão ver os componentes Bootstrap renderizados.

Se você quiser ver o código deste tutorial acesse http://github.com/codeedu/components-bootstrap.git

É isso aí pessoal, espero que tenham gostado. Vejam que esta biblioteca é uma mão na roda para agilizar a construção do front-end da aplicação, pois, gasta-se bem menos tempo

usando estes métodos e View Helpers pré-configurados pro Bootstrap, além de estruturar a aplicação com o Zend\Form aplicando o conceito de reuso de código e de boas práticas de programação, tornando as telas fáceis de manter visualmente.

Referências:

http://neilime.github.io/zf2-twb-bundle

http://framework.zend.com/manual/current/en/modules/zend.form.quick-start.html