Don't you speak portuguese? Translate this site with Google Translator

Pensamento do Dia

A confissão das más acções é o primeiro passo para a prática de boas acções. (Sto. Agostinho)

9.3.1 - formHelper

9.3.1 – formHelper

Você nunca sabe a força que tem, até que a sua única alternativa é ser forte.

Johnny Depp

 

Tradução simplificada e resumida do original em:

http://book.cakephp.org/3.0/en/views/helpers/form.html

class Cake\View\Helper\FormHelper(View $view, array $config =[])

O FormHelper faz a maior parte do trabalho pesado na criação de formulários. O FormHelper foca na criação de formulários de forma rápida, de uma forma que irá agilizar a validação, re-população e layout. O FormHelper também é flexível - ele vai fazer quase tudo por você, utilizando convenções, ou você pode usar métodos específicos para obter apenas o que você precisa.

Iniciando um Formulário

Cake\View\Helper\FormHelper::create(mixed $model = null, array $options =[])

O primeiro método que você deve usar para tirar vantagem do FormHelper é o create(). Este método mostra uma tag de abertura de formulário.

Todos os parâmetros são opcionais. Caso create() seja chamado sem nenhum parâmetro, ele assume que você está construindo um form que submete para o controller atual, via URL atual. O método default para a submissão do form é o POST. Caso você chame o create dentro da view para UsersController::add(), com $this->Form->create() você deve ver a seguinte saída na view renderizada:

/<form method="post" action="/users/add">

Se create() é chamado sem parâmetros fornecidos, assume-se a construção de um formulário que submete dados via POST para a action add() (ou edit() no caso de um id estar incluído nos dados do formulário).

O argumento $model é usado como forma de contexto. Existem vários contextos embutidos para formulário e você pode adicionar seu próprio, o que nós vamos cobrir na próxima seção. O provedores internos mapeiam para os seguintes valores de $model:

- Uma instância de entidade ou um mapa de iterator para o EntityContext, neste contexto permite FormHelper trabalhar com os resultados do ORM embutido.

- Um array que contém a chave de esquema, mapeia para ArrayContext que permite a criação de estruturas de dados simples para construir forms contra.

- null e false mapeiam para o NullContext, esta classe de contexto simplesmente satisfizer a interface que a FormHelper requer. Este contexto é útil se você quiser construir um pequeno formulário que não requer persistência ORM.

Para criar um form para uma entity faça o seguinte:

// Se você está em /articles/add
// $article deve ser uma entidade vazia de Article.
echo $this->Form->create($article);

Isto irá postar os dados do formulário para o action add () de ArticlesController. No entanto, você também pode usar a mesma lógica para criar um formulário de edição. O FormHelper utiliza o objeto de entidade para detectar automaticamente se criará um form de adicionar ou editar. Se a entidade fornecido não é "novo", o formulário será criado como um formulário de edição. Se for novo será add.

Por exemplo, se navegar para

http://example.org/articles/edit/5, nós devemos fazer o seguinte:

// src/Controller/ArticlesController.php:

public function edit($id = null)
{
    if (empty($id)) {
        throw new NotFoundException;
    }
    $article = $this->Articles->get($id);
    // Save logic goes here
    $this->set('article', $article);
}

// View/Articles/edit.ctp:
// Since $article->isNew() is false, we will get an edit form

<?= $this->Form->create($article) ?>

Mudando o Método para o Form

echo $this->Form->create($article, ['type' => 'get']);

Quando existir algum campo do tipo file, precisará ser assim:

echo $this->Form->create($article, ['type' => 'file']);

Configurando a URL para o Form

echo $this->Form->create($article, ['url' => ['action' => 'login']]);

Caso o desejado form action não seja do controller atual, podemos especificar a completa URL para a action do form:

echo $this->Form->create(null, [
    'url' => ['controller' => 'Articles', 'action' => 'publish']
]);

Ou pode apontar para uma URL externa:

echo $this->Form->create(null, [
    'url' => 'http://www.google.com/search',
    'type' => 'get'
]);

Criando Controles para Forms

Cake\View\Helper\FormHelper::control(string $fieldName, array $options = [])

$fieldName – O nome do campo do form 'Modelname.fieldname'.

$options - Um array opcional que pode incluir ambos Options for Control, e options dos outros métodos (que o control() emprega internamente para gerar vários elementos HTML) como também atributos HTML válidos.

Em versões anteriores o Cake usava $this->form->input(), agora usa $this->form->control().

O método control() permite gerar todos os controles/inputs do formulário. Esses controles incluirão uma div para quebra automática, um rótulo, um widget de controle e validação de erro, se necessário. Usando os metadados no contexto do formulário, esse método escolherá um tipo de controle apropriado para cada campo. Internamente control() usa os outros métodos do FormHelper.

Observe que enquanto os campos gerados pelo método control() são chamados genericamente de “inputs” nesta página, tecnicamente falando, o método control() pode gerar não apenas todos os elementos de tipo input do HTML, mas também outros elementos de formulário HTML (por exemplo, selects, button, textarea).

Por default o método control() deve empregar os seguintes widget templates:

'inputContainer' => '<div class="input {{type}}{{required}}">{{content}}</div>'
'input' => '<input type="{{type}}" name="{{name}}"{{attrs}}/>'

Em caso de validação de erros ele também usa:

'inputContainerError' => '<div class="input {{type}}{{required}} error">{{content}}{{error}}</div>'

O tipo de controle criado (quando nós não provemos nenhum options adicional para especificar o tipo de elemento gerado) é inferido via introspecção do model e depende do tipo de dados do campo:

Column Type - Resulting Form Field
string, uuid (char, varchar, etc.) - text
boolean, tinyint(1) - checkbox
decimal - number
float - number
integer - number
text - textarea
text, with name of password, passwd - password
text, with name of email - email
text, with name of tel, telephone, or phone - tel
date - day, month, and year selects
datetime, timestamp - day, month, year, hour, minute, and meridian selects
time - hour, minute, and meridian selects
binary - file

O parâmetro $options segue sua escolha de um controle específico tipo caso necessite:

echo $this->Form->control('published', ['type' => 'checkbox']);

Exemplo de form:

Crie uma nova view em um template, chamada form.ctp, contendo

<?php
	echo $this->Form->create($user);
	// The following generates a Text input
	echo $this->Form->control('username');
	// The following generates a Password input
	echo $this->Form->control('password');
	// Assuming 'approved' is a datetime or timestamp field the following
	//generates: Day, Month, Year, Hour, Minute
	echo $this->Form->control('approved');
	// The following generates a Textarea element
	echo $this->Form->control('quote');
	echo $this->Form->button('Add');
	echo $this->Form->end();
?>

Adicione um action ao controller correspondente, assim:

public function form()

{

$customers =$this->Customers;

$this->set(compact('customers'));

}

Então chame pelo navegador assim:

http://localhost/clientes/controllerNome/form

Podemos especificar qualquer opção para o tipo do input e qualquer atributo HTML.

 

Criar um Select

Se você deseja criar um campo select enquanto usando uma relação belogTo ou hasOne você pode adicionar o seguinte para seu UsersController (assumindo que User belongTo Group):

$this->set('groups', $this->Users->Groups->find('list'));

Então na view do Template:

echo $this->Form->input('group_id', ['options' => $groups]);

 

Para um select em uma associação belongsToMany Groups você pode adicionar o seguinte para seu UsersController:

$this->set('groups', $this->Users->Groups->find('list'));

Na view:

echo $this->Form->input('groups._ids', ['options' => $groups]);

Se o nome do model consiste em duas ou mais palavras, por exemplo, "UserGroup", ao passar os dados usando set() você deve nomear os seus dados com um formato pluralizado e camelCase como se segue:

$this->set('userGroups', $this->UserGroups->find('list'));

Não usar input() para gerar submits

Para isso usar o método \View\Helper\FormHelper::submit().

Options do Input

$options['type']

echo $this->Form->input('field', ['type' => 'file']);
echo $this->Form->input('email', ['type' => 'email']);
$options['label']

echo $this->Form->input('name', [
    'label' => 'The User Alias'
]);
Outros:
echo $this->Form->input('name', [
    'label' => [
        'class' => 'thingy',
        'text' => 'The User Alias'
    ]
]);

 

Tipo select:
$sizes = ['s' => 'Small', 'm' => 'Medium', 'l' => 'Large'];
echo $this->Form->select('size', $sizes, ['default' => 'm']);
$options['value']
echo $this->Form->time('close_time', [
    'value' => '13:30:00'
]);
echo $this->Form->select('rooms', [
    'multiple' => true,
    // options with values 1 and 3 will be selected as default
    'default' => [1, 3]
]);
$options['empty']
echo $this->Form->select(
    'field',
    [1, 2, 3, 4, 5],
    ['empty' => '(choose one)']
);
$options['datetime']
echo $this->Form->input('time', [
    'type' => 'time',
    'interval' => 15
]);

Criando dois selects estáticos para os campos controller e action em Permissions/add.ctp

$options = ['Customers'=>'Customers','Groups'=>'Groups','Users'=>'Users','Permissions'=>'Permissions','Products'=>'Products','ProductItems'=>'ProductItems','value'=>'Selecione'];

echo $this->Form->input('controller',['options'=>$options,'required'=>'false', 'class'=>'col-md-12','empty'=>'Selecione']);

$options2 = ['index'=>'index','add'=>'add','edit'=>'edit','view'=>'view','delete'=>'delete'];

echo $this->Form->input('action', ['options'=>$options2,'required'=>'false', 'class'=>'col-md-12', 'empty'=>'Selecione']);

 

São estáticos, portanto sempre que precisar adicionar um novo controller ou action, precisa alterar este código.

 

Para que Html->Link permita CSS:

<?= $this->Html->Link('<span class="glyphicon glyphicon-plus"></span> Novo', ['controller'=>'Bookmaarks','action'=>'add'],

['class'=>'btn tbn-primary pull-right']);

 

Assim ele mostrará o código <span...</span>

Para que permita o CSS, use:

<?= $this->Html->link('<span class="glyphicon glyphicon-plus"></span> Novo', ['controller'=>'Bookmaarks','action'=>'add'],

['class'=>'btn tbn-primary pull-right', 'escape'=>false]);

 

Observação:

classe Html, método link. Classe com inicial maiúscula e método tudo em minúsculas.

 

Mudar o tipo de um campo

O Cake gerou um campo com o tipo textarea em um form.

Para mudar podemos fazer isso:

print $this->Form->input('url',['label', 'URL']);

 

Mudar para tipo text (campo texto) assim:

print $this->Form->input('url',['type'=>'text','label', 'URL']);

 

Pegando os Erros do Formulário

Uma vez sido validado, o formulário pode recuperar seus próprios erros:

$errors = $form->errors();

/* $errors contains

[

'email' => ['A valid email address is required']

]

*/

 

Form Helper

Form

$this->Form->control() - usado para criar elementos com o mesmo nome. Tem dois parâmetros:

Primeiro - nome do campo

Segundo - opcional, permite usar arrays com múltiplas opções

 

Para o CakePHP os campos do tipo data, datatime ou timestamp obrigatoriamente devem usar DEFAULT NULL:

nascimento date DEFAULT NULL

E também não podemos alterar sua validação para exigir preenchimento com notEmpty ou notBlank. Caso contrário o Cake não reconhece e não adiciona o registro.

src/Template/Clientes/add.ctp ou edit.ctp

 

Ano mínimo sendo 13 anos antes do atual e máximo sendo 100 anos antes do atual, ou seja, como estou em 2016 de 1916 até 2003

Select múltiplo (permite selecionar várias opções)

	print $this->Form->input('pilot_ratings',[
		'type' => 'select',
		'class' => 'listbox',
		'size' => 5,
		'id' => 'pilot_ratings',
		'multiple' => 'multiple',
		'options' => [
		    ['name' => 'Habilitación de Vuelo Nocturno Local', 'value' => '1'],
		    ['name' => 'Habilitación Cat. II / Cat. III', 'value' => '2'],
		    ['name' => 'Habilitación de Remolque de Planeador', 'value' => '5']
		]
	]);

src/Template/Clientes/add.ctp ou edit.ctp

 

Dicas sobre data e hora

Para o CakePHP os campos do tipo data, datatime ou timestamp obrigatoriamente devem usar DEFAULT NULL:

nascimento date DEFAULT NULL

 

E também não podemos alterar sua validação para exigir preenchimento com notEmpty ou notBlank. Caso contrário

o Cake não reconhece e não adiciona o registro.

src/Template/Clientes/add.ctp ou edit.ctp

Por padrão o Cake mostra apenas os anos de 2011 até 2021 na combo Ano.

Vamos alterar para que o ano mínimo seja 13 anos antes do atual

e máximo seja 100 anos antes do atual, ou seja, como estou em 2016,

que mostre de 1916 até 2003, mas isso deve ser pensado para atender ao requisito

da tabela/aplicativo. No nosso caso, do DNOCS, devemos usar 18 anos antes,

ou mais para o primeiro?

Criar o select controller e o action

<?php
            $controls = ['Groups'=>'Groups', 'Users'=>'Users', 'Permissions'=>'Permissions', 'Customers'=>'Customers'];			
            $actions = ['index'=>'index','add'=>'add','edit'=>'edit','delete'=>'delete'];
            echo $this->Form->input('group_id', ['options' => $groups, 'empty'=>'Grupo','class'=>'col2']);
            echo $this->Form->input('controller', ['options'=>$controls,'class'=>'col2','empty'=>'Controller']);
            echo $this->Form->input('action', ['options'=>$actions,'class'=>'col2','empty'=>'Action']);
        ?>

Actions em form

echo $form->create('Post', ['action' => 'whatever']);

echo $form->create('Post', ['url' => '/controller_name/action_name']);

echo $this->Form->create("Despesas",['url'=>'/despesas/despesas_mes']);

 

Quando usamos o método set() em nosso controller, definimos variáveis específicas para serem enviadas para a view/tempalte correspondente. A view/template fará com que todas as variáveis passadas estejam disponíveis no escopo do template como variáveis locais.

 

Mudando largura de campos

echo $this->Form->input['Busca',['type'=>'text','maxlength'=>'8','style'=>'width:50px; height:20px;']];

 

Criando link com o HtmlHelper:

Para o controller atual

<?= $this->Html->link(__('Lista de Usuário'), ['action' => 'index']) ?>

 

Para outro controller

<?= $this->Html->link(__('Lista de Usuário'), ['controller'=>'Users','action' => 'index']) ?>

 

Criando formulário com o FormHelper

<?= $this->Form->create($user) ?>

<legend><?= __('Editar Usuário') ?></legend>

<?php

echo $this->Form->input('username');

echo $this->Form->input('password');

echo $this->Form->input('role', ['admin'=>'Administrador','user'=>'Usuário']);

?>

<?= $this->Form->button(__('Submit')) ?>

<?= $this->Form->end() ?>

Campo input simular select em FormHelper e mudando o label:

 

echo $this->Form->label('Tipo'); // Criando o Label

echo $this->Form->select('role', ['user'=>'Usuário','admin'=>'Administrador'], ['default' => 'admin']);

 

Mais detalhes em:

http://book.cakephp.org/3.0/en/views/helpers/form.html

https://book.cakephp.org/3.0/pt/core-libraries/form.html

 

Comments fornecido por CComment

Novo Testamento

E Jesus lhes disse: Tampouco vos direi com que autoridade faço isto.
(Lc, 20:8)

Rotas no Mapa do Google

© 2015 Ribamar FS. All Rights Reserved. Designed By JoomShaper