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

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

Старт! Честный VDS/VPS, на котором «Лунная База» живет уже 20+ лет

Задумываетесь о том, чтобы поднять свой pet-проект, сайт клиента или настроить окружение для разработки? Уже пора подумать, где арендовать железо.

Лунная База хостится на FirstVDS более 20 лет. Мыслей о том, чтобы перебраться на другой хостинг, не было ни разу (хотя опыт работы с другими вариантами, конечно, есть).

Бывали разные ситуации, но они бывают на любом железе. Главное, что нужно понять: здесь нет маркетинговой шелухи и сказок про «мы всё сделаем за вас». Если вы берете VDS — вам дают полный root, возможность накатить любую ОС и не лезут в ваши конфиги.

Если в саппорт написать с вопросом по вашему коду и получить ответ: «Читайте документацию и разбирайтесь сами» или «Обратитесь к профильному специалисту» — это не повод обижаться. Это повод углубить свои знания в DevOps и сайтостроении! Бегите от тех, кто пообещает: «Мы всё чиним и настраиваем абсолютно бесплатно!». Никто никогда не работает «по доброте душевной» в ущерб себе, а бесплатный сыр в администрировании обычно заканчивается сломанной базой данных.

Что по факту: Гибкое масштабирование ядер и RAM, экономия по сравнению с физическими серверами и адекватная панель ispmanager, если она вам нужна.



Основные формы ActiveRecord: ActiveForm

Основным способом использования форм в Yii является использование [[yii\widgets\ActiveForm]]. Этот подход должен быть применён, когда форма основана на модели. Кроме того, имеются дополнительные методы в [[yii\helpers\Html]], которые используются для добавления кнопок и текстовых подсказок к любой форме.

Форма, которая отображается на стороне клиента в большинстве случаев соответствует модели. Модель, в свою очередь, проверяет данные из элементов формы на сервере (смотрите раздел Валидация для более подробных сведений). Когда создаётся форма, основанная на модели, необходимо определить, что же является моделью. Модель может основываться на классе Active Record, который описывает некоторые данные из базы данных, или же на базовом классе Model (происходит от [[yii\base\Model]]), который позволяет использовать произвольный набор элементов формы (например, форма входа).

В следующем примере показано, как создать модель формы, основанной на базовом классе Model:

<?php

class LoginForm extends \yii\base\Model
{
    public $username;
    public $password;

    public function rules()
    {
        return [
            // тут определяются правила валидации
        ];
    }
}

В контроллере будем передавать экземпляр этой модели в представление для виджета [[yii\widgets\ActiveForm|ActiveForm]], который генерирует форму.

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

$form = ActiveForm::begin([
    'id' => 'login-form',
    'options' => ['class' => 'form-horizontal'],
]) ?>
    <?= $form->field($model, 'username') ?>
    <?= $form->field($model, 'password')->passwordInput() ?>

    <div class="form-group">
        <div class="col-lg-offset-1 col-lg-11">
            <?= Html::submitButton('Вход', ['class' => 'btn btn-primary']) ?>
        </div>
    </div>
<?php ActiveForm::end() ?>

В вышеприведённом коде [[yii\widgets\ActiveForm::begin()|ActiveForm::begin()]] не только создаёт экземпляр формы, но также и знаменует её начало. Весь контент, расположенный между [[yii\widgets\ActiveForm::begin()|ActiveForm::begin()]] и [[yii\widgets\ActiveForm::end()|ActiveForm::end()]], будет завёрнут в HTML-тег <form>. Вы можете изменить некоторые настройки виджета через передачу массива в его begin метод, также как и в любом другом виджете. В этом случае дополнительный CSS-класс и идентификатор будет прикреплён к открывающемуся тегу <form>. Для просмотра всех доступных настроек, пожалуйста, обратитесь к документации API [[yii\widgets\ActiveForm]].

Для создания в форме элемента с меткой и любой применимой валидацией с помощью JavaScript, вызывается [[yii\widgets\ActiveForm::field()|ActiveForm::field()]], который возвращает экземпляр [[yii\widgets\ActiveField]]. Когда этот метод вызывается непосредственно, то результатом будет текстовый элемент (input type="text"). Для того, чтобы настроить элемент, можно вызвать один за одним дополнительные методы [[yii\widgets\ActiveField|ActiveField]]:

// элемент формы для ввода пароля
echo $form->field($model, 'password')->passwordInput();
// добавлена подсказка (hint) и настроена метка (label)
echo $form->field($model, 'username')->textInput()->hint('Пожалуйста, введите имя')->label('Имя');
// создание элемента HTML5 для ввода email 
echo $form->field($model, 'email')->input('email');

Впоследствии будут созданы <label>, <input> и другие теги в соответствии с [[yii\widgets\ActiveField::$template|template]], который определён в элементе. Имя элемента формы определяется автоматически из моделей [[yii\base\Model::formName()|form name]] и их атрибутов. Например, имя элемента для атрибута username в коде, приведённом выше, будет LoginForm[username]. Это правило именования будет учитываться на стороне сервера при получении массива результатов $_POST['LoginForm'] для всех элементов формы входа (Login Form).

Tip: Если в форме только одна модель, и вы хотите упростить имена полей ввода, то можете сделать это, переопределив метод [[yii\base\Model::formName()|formName()]] модели так, чтобы он возвращал пустую строку. Это может пригодиться для получения более красивых URL при фильтрации моделей в GridView.

Специфический атрибут модели может быть задан более сложным способом. Например, при загрузке файлов или выборе нескольких значений из списка, в качестве значений атрибуту модели нужно передать массив, для этого к имени можно добавить []:

// поддерживает загрузку нескольких файлов:
echo $form->field($model, 'uploadFile[]')->fileInput(['multiple'=>'multiple']);

// поддерживает выбор нескольких значений:
echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C']);

Имена элементов форм следует выбирать, учитывая, что могут возникнуть конфликты. Подробнее об этом в документации jQuery:

Имена и идентификаторы форм и их элементов не должны совпадать с элементами форм, такими как submit, length или method. Конфликты имен могут вызывать трудно диагностируемые ошибки. Подробнее о способах избегания подобных проблем смотрите DOMLint.

Дополнительные HTML-элементы можно добавить к форме, используя обычный HTML или методы из класса помощника [[yii\helpers\Html|Html]], как это было сделано с помощью [[yii\helpers\Html::submitButton()|Html::submitButton()]] в примере, приведённом выше.

Tip: Если вы использует Twitter Bootstrap CSS в своём приложении, то воспользуйтесь [[yii\bootstrap\ActiveForm]] вместо [[yii\widgets\ActiveForm]]. Он добавит к ActiveForm дополнительные стили, которые сработают в рамках bootstrap CSS.

Tip: для добавления "звёздочки" к обязательным элементам формы, воспользуйтесь следующим CSS:

div.required label.control-label:after {
    content: " *";
    color: red;
}

Создание выпадающего списка

Для создания выпадающего списка можно использовать метод ActiveForm [[yii\widgets\ActiveField::dropDownList()|dropDownList()]]:

use app\models\ProductCategory;

/* @var $this yii\web\View */
/* @var $form yii\widgets\ActiveForm */
/* @var $model app\models\Product */

echo $form->field($model, 'product_category')->dropdownList(
    ProductCategory::find()->select(['category_name', 'id'])->indexBy('id')->column(),
    ['prompt'=>'Select Category']
);

Текущее значение поля модели будет автоматически выбрано в списке.

Работа с Pjax

Виджет [[yii\widgets\Pjax|Pjax]] позволяет обновлять определённую область страницы вместо перезагрузки всей страницы. Вы можете использовать его для обновления формы после её отсылки.

Для того, чтобы задать, какая из форм будет работать через PJAX, можно воспользоваться опцией [[yii\widgets\Pjax::$formSelector|$formSelector]]. Если значение не задано, все формы с атрибутом data-pjax внутри PJAX-контента будут работать через PJAX.

use yii\widgets\Pjax;
use yii\widgets\ActiveForm;

Pjax::begin([
    // Опции Pjax
]);
    $form = ActiveForm::begin([
        'options' => ['data' => ['pjax' => true]],
        // остальные опции ActiveForm
    ]);

        // Содержимое ActiveForm

    ActiveForm::end();
Pjax::end();

Tip: Будьте осторожны с ссылками внутри виджета [[yii\widgets\Pjax|Pjax]] так как ответ будет также отображаться внутри виджета. Чтобы ссылка работала без PJAX, добавьте к ней HTML-атрибут data-pjax="0".

Значения кнопок отправки и загрузка файлов

В jQuery.serializeArray() имеются определённые проблемы при работе с файлами и значениями кнопок типа submit. Они не будут исправлены и признаны устаревшими в пользу классаFormData из HTML5.

Это означает, что поддержка файлов и значений submit-кнопок через AJAX или виджет [[yii\widgets\Pjax|Pjax]] зависит от поддержки в браузере класса FormData.

Ещё по теме

Следующая глава Валидация описывает валидацию отправленной формы как на стороне сервера, так и на стороне клиента.

Если вы хотите более подробно изучить информацию по использованию форм, то обратитесь к главам:

Самый честный хостинг за 20+ лет существования Лунной Базы

Задумываешься о том, чтобы поднять свой сайт в Интернете? Уже пора подумать о том, какой хостинг выбрать?

Лунная База хостится 20+ лет на firstDVS. При этом, мыслей о том, чтобы перебраться на другой хостинг не было. (Но, при этом есть опыт работы с другими вариантами.)

Бывали с firstDVS разные ситуации, но, они бывают на всех хостингах. Единственное, что тут важно понять, - это то, что никто ничего тебе не будет впаривать... Но, и работать за тебя тоже никто не станет. Если в саппорт ответили: «Читайте по ссылке и разбирайтесь сами...» или вообще «Обратитесь за помощью к специалисту», - это повод углубить свои знания в области сайтостроения, а не бежать к тем, что пообещают: «Мы всё чиним и всё делаем за своих клиентов абсолютно бесплатно!» Никто никогда ничего ни за кого "по доброте душевной" не делал, не делает и не будет делать!

Старт! Горячий старт на просторы интернета
Старт! Горячий старт на просторы интернета
Старт! Меню