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.
271 lines
10 KiB
271 lines
10 KiB
10 years ago
|
Trabalhando com Formulários
|
||
|
===========================
|
||
|
|
||
|
Nesta seção descreve como se cria uma nova página com um formulário para obter
|
||
|
dados a partir dos usuários. A página exibirá uma formulário com um campo para
|
||
|
o nome e uma para o e-mail. Depois de obter essas duas informações a partir do
|
||
|
usuário, a página exibirá os valores inseridos de volta para a confirmação.
|
||
|
|
||
|
Para atingir este objetivo, além de criar uma [ação](structure-controllers.md) (action) e
|
||
|
duas [visões](structure-views.md) (view), você também criará uma [modelo](structure-models.md) (model).
|
||
|
|
||
|
Através deste tutorial, você aprenderá como:
|
||
|
|
||
|
* Criar um [modelo](structure-models.md) (model) para representar os dados inseridos pelo usuário por meio de um formulário
|
||
|
* Declarar regras (rules) para validar os dados inseridos
|
||
|
* Criar um formulário HTML em uma [visão](structure-views.md) (view)
|
||
|
|
||
|
|
||
|
Criando uma Modelo (Model) <a name="creating-model"></a>
|
||
|
----------------
|
||
|
|
||
|
Os dados a serem solicitados pelo usuário será representados por uma classe modelo
|
||
|
`EntryForm` como mostro a seguir e salvos no arquivo `models/EntryForm.php`. Por
|
||
|
favor consulte a seção [Autoloading de Classes](concept-autoloading.md) para mais
|
||
|
detalhes sobre convenção de nomenclatura dos arquivos de classes.
|
||
|
|
||
|
```php
|
||
|
<?php
|
||
|
|
||
|
namespace app\models;
|
||
|
|
||
|
use yii\base\Model;
|
||
|
|
||
|
class EntryForm extends Model
|
||
|
{
|
||
|
public $name;
|
||
|
public $email;
|
||
|
|
||
|
public function rules()
|
||
|
{
|
||
|
return [
|
||
|
[['name', 'email'], 'required'],
|
||
|
['email', 'email'],
|
||
|
];
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
A classe estende de [[yii\base\Model]], uma classe base fornecida pelo Yii,
|
||
|
comumente usados para representar dados do formulário.
|
||
|
|
||
|
> Informação: O [[yii\base\Model]] é usado como pai das classes modelos que *não*
|
||
|
são associadas com tabelas do banco de dados.
|
||
|
O [[yii\db\ActiveRecord]] é normalmente usado como pai das classes modelos que
|
||
|
correspondem a tabelas do banco de dados.
|
||
|
|
||
|
A classe `EntryForm` contém dois atributos públicos, `name` e `email`, que são
|
||
|
usados para guardar 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 permitem que:
|
||
|
|
||
|
* tanto os valores do `name` quanto do `email` sejam obrigatórios
|
||
|
* os dados do `email` devem ser um e-mail válido sintaticamente
|
||
|
|
||
|
Se você tiver um objeto `EntryForm` populado com dados fornecidos pelo usuário,
|
||
|
você pode chamar o [[yii\base\Model::validate()|validate()]] para iniciar as
|
||
|
rotinas de validação dos dados. A validação dos dados falhar, a propriedade
|
||
|
[[yii\base\Model::hasErrors|hasErrors]] será definida como *true* e você pode
|
||
|
saber quais erros ocorrerão pela validação através de [[yii\base\Model::getErrors|errors]].
|
||
|
|
||
|
```php
|
||
|
<?php
|
||
|
$model = new EntryForm();
|
||
|
$model->name = 'Qiang';
|
||
|
$model->email = 'bad';
|
||
|
if ($model->validate()) {
|
||
|
// Bom!
|
||
|
} else {
|
||
|
// Falha!
|
||
|
// Utilize $model->getErrors()
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
Criando uma Ação <a name="creating-action"></a>
|
||
|
------------------
|
||
|
|
||
|
Em seguida, você precisará criar uma ação `entry` no controlador `site` que será usado no novo modelo. O processo de criação e utilização das ações são explicadas na seção
|
||
|
[Como Fazer um "Hello World"](start-hello.md).
|
||
|
|
||
|
```php
|
||
|
<?php
|
||
|
|
||
|
namespace app\controllers;
|
||
|
|
||
|
use Yii;
|
||
|
use yii\web\Controller;
|
||
|
use app\models\EntryForm;
|
||
|
|
||
|
class SiteController extends Controller
|
||
|
{
|
||
|
// ...código existente...
|
||
|
|
||
|
public function actionEntry()
|
||
|
{
|
||
|
$model = new EntryForm;
|
||
|
|
||
|
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
|
||
|
// dados válidos recebidos pelo $model
|
||
|
|
||
|
// fazer alguma coisa aqui sobre $model ...
|
||
|
|
||
|
return $this->render('entry-confirm', ['model' => $model]);
|
||
|
} else {
|
||
|
// Ou a página é exibida inicialmente ou existe algum erro de validação
|
||
|
return $this->render('entry', ['model' => $model]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
A primeira ação cria um objeto `EntryForm`. Ele, então, tenta popular o modelo
|
||
|
(model) com os dados vindos do `$_POST`, fornecidos pelo [[yii\web\Request::post()]]
|
||
|
no Yii. Se o modelo (model) for populado com sucesso (por exemplo, se o usuário
|
||
|
enviar o formulário HTML), a ação chamará o [[yii\base\Model::validate()|validate()]]
|
||
|
para certifique-se que os valores fornecidos são válidos.
|
||
|
|
||
|
> Informação: A expressão `Yii::$app` representa a instância da
|
||
|
[aplicação](structure-applications.md), que é globalmente acessível via singleton.
|
||
|
Também é um [service locator](concept-service-locator.md) que fornece componentes
|
||
|
tais como `request`, `response`, `db`, etc. para suportar a funcionalidade específica.
|
||
|
No código acima, o componente `request` da instância da aplicação é usada para
|
||
|
acessar os dados do `$_POST`.
|
||
|
|
||
|
Se tudo tiver certo, a ação renderizará a visão chamada `entry-confirm` para
|
||
|
confirmar os dados enviados pelo usuário. Se ao enviar o formulário não
|
||
|
houver dados ou se os dados tiverem erros, a visão `entry` será renderizada,
|
||
|
em que o formulário será exibigo, juntamente com as mensagens de erros da
|
||
|
validação.
|
||
|
|
||
|
> Nota: Neste exemplo muito simples, acabamos de renderizar um página de confirmação
|
||
|
mediante a dados válidos enviados de uma formulário. Em prática, você poderia
|
||
|
considerar usar [[yii\web\Controller::refresh()|refresh()]] ou [[yii\web\Controller::redirect()|redirect()]]
|
||
|
para evitar [problemas ao reenviar formulários](http://en.wikipedia.org/wiki/Post/Redirect/Get).
|
||
|
|
||
|
|
||
|
Criando Visões <a name="creating-views"></a>
|
||
|
--------------
|
||
|
|
||
|
Finalmente, crie dois arquivos de visões chamados de `entry-confirm` e `entry`.
|
||
|
Estas visões serão renderizados pela ação `entry`, como descrito anteriormente.
|
||
|
|
||
|
A visão `entry-confirm` simplesmente exibe os dados dos campos `name` e `email`.
|
||
|
Deverá ser salvo no arquivo `views/site/entry-confirm.php`.
|
||
|
|
||
|
```php
|
||
|
<?php
|
||
|
use yii\helpers\Html;
|
||
|
?>
|
||
|
<p>You have entered the following information:</p>
|
||
|
|
||
|
<ul>
|
||
|
<li><label>Name</label>: <?= Html::encode($model->name) ?></li>
|
||
|
<li><label>Email</label>: <?= Html::encode($model->email) ?></li>
|
||
|
</ul>
|
||
|
```
|
||
|
|
||
|
A visão `entry` exibe um formulário HTML. Deverá ser salvo no arquivo `views/site/entry.php`.
|
||
|
|
||
|
```php
|
||
|
<?php
|
||
|
use yii\helpers\Html;
|
||
|
use yii\widgets\ActiveForm;
|
||
|
?>
|
||
|
<?php $form = ActiveForm::begin(); ?>
|
||
|
|
||
|
<?= $form->field($model, 'name') ?>
|
||
|
|
||
|
<?= $form->field($model, 'email') ?>
|
||
|
|
||
|
<div class="form-group">
|
||
|
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
|
||
|
</div>
|
||
|
|
||
|
<?php ActiveForm::end(); ?>
|
||
|
```
|
||
|
|
||
|
A visão usa o poderoso [widget](structure-widgets.md) chamado
|
||
|
[[yii\widgets\ActiveForm|ActiveForm]] para criar o formulário HTML. Os métodos
|
||
|
`begin()` e `end()` do widget renderizam a abertura e o fechamento da tag do
|
||
|
formulário. Entre os dois métodos chamados, os campos de entrada são criados pelo
|
||
|
método [[yii\widgets\ActiveForm::field()|field()]]. O primeiro campo de entrada
|
||
|
é para o "name" (nome) e o segundo é para o "email". Após os campos de entrada,
|
||
|
o método [[yii\helpers\Html::submitButton()]] é chamado para criar o botão
|
||
|
de enviar.
|
||
|
|
||
|
|
||
|
Testando <a name="trying-it-out"></a>
|
||
|
-------------
|
||
|
|
||
|
Para ver como ele funciona, utilize seu navegador para acessar a seguinte URL:
|
||
|
|
||
|
```
|
||
|
http://hostname/index.php?r=site/entry
|
||
|
```
|
||
|
|
||
|
Você verá uma página exibindo um formulário com dois campos de entrada. Na frente
|
||
|
de cada campo, um *label* indicando quais dados devem ser inseridos. Se você clicar
|
||
|
no botão de enviar sem informar nenhum dado, ou se você não fornecer um e-mail
|
||
|
válido, você verá uma mensagem de erro após cada campo de entrada.
|
||
|
|
||
|
![Form with Validation Errors](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ê.
|
||
|
|
||
|
![Confirmation of Data Entry](images/start-entry-confirmation.png)
|
||
|
|
||
|
|
||
|
|
||
|
### Explicação da Mágica <a name="magic-explained"></a>
|
||
|
|
||
|
Você pode querer saber como o formulário HTML trabalha por baixo dos panos, porque
|
||
|
parece quase mágica exibir um *label* para cada campo de entrada e mostrar mensagens
|
||
|
de erro quando você não informa dados corretos sem recarregar a página.
|
||
|
|
||
|
Sim, a validação dos dados inicialmente é feito no lado do cliente usando JavaScript
|
||
|
e posteriormente realizada no lado do servidor via PHP.
|
||
|
O [[yii\widgets\ActiveForm]] é inteligente o suficiente para extrair as regras de
|
||
|
validação declaradas no `EntryForm`, transformando-as em códigos JavaScript e utilizando
|
||
|
o JavaScript para realizar as validações dos dados. No caso do JavaScript estiver desabilitado
|
||
|
em seu navegador, a validação ainda será realizada pelo lado do servidor, como mostrado
|
||
|
no método `actionEntry()`. Isso garante que os dados serão validados em qualquer
|
||
|
circunstância.
|
||
|
|
||
|
> Aviso: A validação feita pelo lado do cliente é uma conveniência que fornece uma melhor
|
||
|
experiência para o usuário. A validação feita pelo lado do servidor é sempre necessária
|
||
|
com ou sem validação no lado do cliente.
|
||
|
|
||
|
Os *labels* dos campos de entrada são geradas pelo método `field()`, usando os nomes
|
||
|
das propriedades do modelo (model).
|
||
|
Por exemplo, um *label* chamado `Name` será gerado para a propriedade `name`.
|
||
|
|
||
|
Você pode personalizar um *label* em uma visão utilizando o seguinte código:
|
||
|
|
||
|
```php
|
||
|
<?= $form->field($model, 'name')->label('Your Name') ?>
|
||
|
<?= $form->field($model, 'email')->label('Your Email') ?>
|
||
|
```
|
||
|
|
||
|
> Informação: O Yii fornece muitos destes widgets para lhe ajudar a criar rapidamente
|
||
|
complexas e dinâmicos layouts.
|
||
|
Como você vai aprender mais tarde, escrever um novo widget é também extremamenet fácil.
|
||
|
Você pode querer transformar grande parte do seu código de visão em reutilizáveis
|
||
|
widget para simplificar o desenvolvimento de visões no futuro.
|
||
|
|
||
|
|
||
|
Resumo <a name="summary"></a>
|
||
|
-------
|
||
|
|
||
|
Nesta seção, você tocou em cada parte do padrão de arquitetura MVC.
|
||
|
Aprendeu como criar uma classe modelo (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. Esta é uma tarefa que poderia levar muito tempo ao desenvolver
|
||
|
uma aplicação, mas o Yii fornece widgets inteligentes para gerar estas tarefas de
|
||
|
forma simples.
|
||
|
Na próxima seção, você aprenderá como trabalhar com banco de dados, os quais são
|
||
|
necessários em quase todas as aplicações.
|