Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
10 KiB

Trabalhando com Formulários
===========================
Esta seção descreve como criar uma nova página com um formulário para receber
dados dos usuários. A página exibirá um formulário com um campo para o nome e outro para o e-mail. Depois de obter essas duas informações do usuário, a página exibirá os valores inseridos de volta para confirmação.
Para alcançar esse objetivo, além de criar uma [action](structure-controllers.md) e
duas [views](structure-views.md), você também criará um [model](structure-models.md).
No decorrer deste tutorial, você aprenderá como:
* criar um [model](structure-models.md) para representar os dados que o usuário insere por meio de um formulário
* declarar regras (rules) para validar os dados inseridos
* criar um formulário HTML em uma [view](structure-views.md)
Criando um Model <span id="creating-model"></span>
----------------
Os dados a serem solicitados do usuário serão representados por uma classe model
`FormularioDeRegistro`, como visto a seguir, que será salva no arquivo `models/FormularioDeRegistro.php`. Por
favor, consulte a seção [Autoloading de Classes](concept-autoloading.md) para mais
detalhes sobre convenção de nomenclatura de arquivos de classes.
```php
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class FormularioDeRegistro extends Model
{
public $nome;
public $e_mail;
public function rules()
{
return [
[['nome', 'e_mail'], 'required'],
[['e_mail'], 'email'],
];
}
}
```
A classe estende de [[yii\base\Model]], uma classe base fornecida pelo Yii comumente usada para representar dados de formulários.
> Info: [[yii\base\Model]] é usado como pai das classes de models que *não*
são associadas com tabelas de bancos de dados.
Enquanto [[yii\db\ActiveRecord]], como pai das classes de models que correspondem a tabelas de bancos de dados.
A classe `FormularioDeRegistro` contém dois atributos públicos, `nome` e `e_mail`, que são
usados para armazenar os dados fornecidos pelo usuário. Ele também contém um método
chamado `rules()`, que retorna um conjunto de regras para validação dos dados.
As regras de validação declaradas no código acima declaram que:
* tanto o `nome` quanto o `e_mail` são obrigatórios
* o `e_mail` deve ser preenchido com um e-mail sintaticamente válido (por exemplo, um valor sem @ não pode ser considerado válido para um e-mail, etc.)
Se você tem um objeto `FormularioDeRegistro` preenchido com dados fornecidos pelo usuário,
você pode chamar seu método [[yii\base\Model::validate()|validate()]] para iniciar as rotinas de validação dos dados. Se a validação de dados falhar, a propriedade
[[yii\base\Model::hasErrors|hasErrors]] será definida como *true* e você pode
saber quais erros de validação ocorreram por consultar [[yii\base\Model::getErrors|errors]].
```php
<?php
$model = new FormularioDeRegistro();
$model->nome = 'Fulano';
$model->e_mail = 'emailruim';
if ($model->validate()) {
// Bom!
} else {
// Falhou!
// Utilize $model->getErrors()
}
```
Criando uma Action <span id="creating-action"></span>
------------------
Em seguida, você precisará criar uma action `registro` no controller `site` que usará o novo model. O processo de criação e utilização de ações foi explicado na seção
[Dizendo "Olá!"](start-hello.md).
```php
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\FormularioDeRegistro;
class SiteController extends Controller
{
// ...código existente...
public function actionRegistro()
{
$model = new FormularioDeRegistro();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// dados válidos recebidos no $model
// faça alguma coisa significativa com o $model aqui ...
return $this->render('confirmar-registro', ['model' => $model]);
} else {
// Ou a página esta sendo exibida inicial ou houve algum erro de validação
return $this->render('registro', ['model' => $model]);
}
}
}
```
A primeira action cria um objeto `FormularioDeRegistro`. Ele, então, tenta preencher o model com os dados de `$_POST`, fornecidos no Yii por [[yii\web\Request::post()]].
Se o model for preenchido (observe o método `load()`) com sucesso, ou seja, se o usuário
enviou o formulário HTML, a action chamará o [[yii\base\Model::validate()|validate()]]
para se certificar de que os valores fornecidos são válidos.
> Info: A expressão `Yii::$app` representa a instância da
[aplicação](structure-applications.md), que é um "singleton" globalmente acessível.
Ao mesmo tempo, é um [service locator](concept-service-locator.md) que fornece componentes
tais como `request`, `response`, `db`, etc., para permitir funcionalidades específicas.
No código acima, o componente `request` da instância da aplicação é usado para acessar os dados do `$_POST`.
Se tudo estiver certo, a action renderizará a view chamada `confirmar-registro` para confirmar ao usuário que os dados foram enviados corretamente. Se nenhum dado foi enviado ou se tiverem erros, a view `registro` será renderizada novamente
e seu formulário HTML voltará a ser exibido mas, dessa vez, juntamente com as mensagens de erro de validação.
> Nota: Neste exemplo muito simples, renderizamos a página de confirmação somente se os dados enviados eram válidos. Na prática, você deve considerar usar [[yii\web\Controller::refresh()|refresh()]] ou [[yii\web\Controller::redirect()|redirect()]]
para evitar [problemas de reenvio de formulário](http://en.wikipedia.org/wiki/Post/Redirect/Get).
Criando Views <span id="creating-views"></span>
--------------
Por fim, crie dois arquivos de views chamados `confirmar-registro` e `registro`. Essas serão as views renderizadas pela action `registro`, como acabamos de descrever acima.
A view `confirmar-registro` simplesmente exibe os dados dos campos `nome` e `e_mail` e deve ser salva no arquivo `views/site/confirmar-registro.php`.
```php
<?php
use yii\helpers\Html;
?>
<p>Você enviou as seguintes informações:</p>
<ul>
<li><label>Nome</label>: <?= Html::encode($model->nome) ?></li>
<li><label>E-mail</label>: <?= Html::encode($model->e_mail) ?></li>
</ul>
```
A view `registro` exibe um formulário HTML e deve ser salva no arquivo `views/site/registro.php`.
```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'nome') ?>
<?= $form->field($model, 'e_mail') ?>
<div class="form-group">
<?= Html::submitButton('Enviar', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
```
A view usa um poderoso [widget](structure-widgets.md) chamado
[[yii\widgets\ActiveForm|ActiveForm]] para construir o formulário HTML. Os métodos
`begin()` e `end()` do widget renderizam as tags de abertura e de fechamento do formulário.
Entre as duas chamadas de métido, campos são criados pelo
método [[yii\widgets\ActiveForm::field()|field()]]. O primeiro campo é para o nome e o segundo é para o e-mail. Após os campos,
o método [[yii\helpers\Html::submitButton()]] é chamado para criar um botão de envio do formulário (submit).
Conferindo <span id="trying-it-out"></span>
-------------
Para ver como funciona, utilize seu navegador para acessar a seguinte URL:
```
http://hostname/index.php?r=site/registro
```
Você verá uma página exibindo um formulário com dois campos. Na frente de cada campo, um *label* indica quais dados devem ser inseridos. Se você clicar
no botão Enviar sem informar nenhum dado, ou se você não fornecer um e-mail
válido, você verá uma mensagem de erro próxima a cada campo com problema.
![Formulário com Erros de Validação](images/start-form-validation.png)
Após informar um nome e e-mail válidos e clicar no botão de enviar, você verá uma
nova página exibindo os dados informados por você.
![Confirmação de Registro](images/start-entry-confirmation.png)
### Mágica Explicada <span id="magic-explained"></span>
Você talvez se pergunte como o formulário HTML trabalha por trás das cortinas, já que parece
quase mágica exibir um *label* para cada campo e mostrar mensagens
de erro sem recarregar a página quando você não informa os dados corretamente.
Sim, a validação de dados inicialmente é feita no cliente usando JavaScript e, posteriormente, realizada no servidor via PHP.
O [[yii\widgets\ActiveForm]] é esperto o suficiente para extrair as regras de
validação que você declarou no `FormularioDeRegistro`, transformá-las em código JavaScript executável e usar esse
código JavaScript para realizar a validação de dados. Caso você tenha desabilitado o JavaScript em seu navegador, a validação ainda será realizada no servidor, como mostrado
no método `actionRegistro()`. Isso garante a validade dos dados em todas as circunstâncias.
> Warning: (Alerta!) A validação feita no cliente é uma conveniência que fornece uma melhor
experiência para o usuário. A validação feita no servidor é sempre necessária, quer a validação no cliente aconteça, quer não.
Os *labels* dos campos são gerados pelo método `field()`, usando os nomes
das propriedades do model.
Por exemplo, um *label* chamado `Nome` será gerado para a propriedade `nome`.
Você pode personalizar um *label* em uma view utilizando o seguinte código:
```php
<?= $form->field($model, 'nome')->label('Seu Nome') ?>
<?= $form->field($model, 'e_mail')->label('Seu E-mail') ?>
```
> Info: O Yii fornece muitos desses widgets para ajudá-lo a construir rapidamente views dinâmicas e complexas.
Conforme você vai aprender mais tarde, escrever um novo widget também é extremamente fácil.
Você talvez queira transformar grande parte do código de suas views em widgets reutilizáveis
para simplificar o desenvolvimento de views no futuro.
Resumo <span id="summary"></span>
-------
Nesta seção do guia, você teve uma introduçao à última parte do padrão de arquitetura MVC. Você aprendeu como criar uma classe model para representar os dados do usuário e validá-los.
Também aprendeu como obter os dados enviados pelos usuários e como exibi-los de
volta no navegador. Essa é uma tarefa que poderia tomar muito tempo ao desenvolver uma aplicação, mas o Yii fornece widgets poderosos que tornam o processo muito simples.
Na próxima seção, você aprenderá como trabalhar com bancos de dados, que são
necessários em quase todas as aplicações.