Создание формы и валидация

Создание и вывод формы

Формы создаются в папке models/.

# models/FeedbackForm.php
namespace app\models;

use Yii;
use yii\base\Model;

class FeedbackForm extends Model
{
    // создание полей для формы
    public $name;
    public $email;
}

В контроллере надо загрузить объект FeedbackForm и передать его в шаблон.

# controllers/SiteController.php

// загрузка формы
use app\models\FeedbackForm;

class SiteController extends Controller
{

    public function actionFeedback()
    {
        // создание объекта формы и передача в шаблон
        $model = new FeedbackForm();
        return $this->render('feedback', ['model' => $model]);
    }

}

В шаблоне осталось вывести форму:

<!-- views/site/feedback.php -->

<?php
// загрузка объекта ActiveForm, для работы с формами
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
?>

Вывод формы:
<?php $form = ActiveForm::begin(['id' => 'feedback-form']); ?>
    <?=$form->field($model, 'name')?>
    <?=$form->field($model, 'email')?>
    <?=Html::submitButton('Отправить')?>
<?php ActiveForm::end(); ?>

В результате будет сгенерирована форма.

В коде выше был подключен компонент «yii\bootstrap\ActiveForm», который генерирует дополнительный HTML для Twitter Bootstrap. Если в проекте не используется Twitter Bootstrap, то можно использовать «yii\widgets\ActiveForm».

При необходимости можно указать класс для формы через параметр options.

$form = ActiveForm::begin([
    'id' => 'feedback-form',
    'options' => ['class' => 'form-horizontal'] // задать класс формы
]);

При отправки запроса, Yii автоматически проверяет форму на CSRF (подделка межсайтовых запросов).

Валидация

Валидация элементов форм указывается в методе rules().

# models/FeedbackForm.php

class FeedbackForm extends Model
{

    // создание полей для формы
    public $name;
    public $email;

    // правила валидации
    public function rules()
    {
        return array(
            ['name', 'required'], // обязательное поле
            ['email', 'email'],   // проверка, что введён email
        );
    }

}

Достаточно указать нужные параметры для валидации данных, и они автоматически будут применяться к форме и выводить ошибки (например, «поле должно быть заполнено» или «email введён неправильно»). Ошибки будут показываться без перезагрузки страницы.

Проверка формы на правильность введённых данных происходит через JavaScript. Если пользователь отключит JavaScript, то проверка на обязательное поле и другие указанные параметры будут пропускаться. Чтобы этого не происходило, проверять на валидацию также рекомендуется в контроллере.

# controllers/SiteController.php
use app\models\FeedbackForm;

class SiteController extends Controller
{

    // …

    public function actionFeedback()
    {
        $model = new FeedbackForm();

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            // выполнение кода, если данные введены правильно
            // иначе будет показа ошибка (Yii выводит ошибки автоматически)
            $model->name; // используется вместо $_POST['name']
        }

        return $this->render('feedback', ['model' => $model]);
    }

}

Метод $model->validate() возвращает «true» или «false».

При необходимости можно получить ошибки формы через метод $model->getErrors() или через свойство $model->errors.

Имена полей

Имена для элементов форм можно задать в модели через метод attributeLabels().

class FeedbackForm extends Model
{

    // создание полей для формы
    public $name;
    public $email;

    // имена для <label>
    public function attributeLabels()
    {
        return [
            'name' => 'Имя',
            'email' => 'Email',
        ];
    }

}

Также задать имя элементу формы можно через метод $form->field()->label().

$form->field($model, 'name')->label('Имя');

Сообщения об ошибках

Для каждого способа валидации уже выводится ошибка по умолчанию. Yii поддерживает вывод ошибок на русском языке, для этого в файле congif/web.php надо добавить параметр language:

# congif/web.php

$config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'language' => 'ru-RU', // указать язык сайта
    // …
];

Также можно задать свой текст ошибки через параметр message:

public function rules()
{
    return array(
        ['name', 'required', 'message' => 'Имя обязательно для заполнения'],
    );
}