Формы в IO7 (FormBuilder)
Внимание
Данная статья документации написана нейросетью. Возможны некоторые расхождения и неточность информации!
IO7 предоставляет IO\Form\FormBuilder — fluent API для построения HTML-форм и валидации данных.
Создание формы
use IO\Form\FormBuilder;
$form = new FormBuilder();
Конфигурация формы
| Метод | Описание |
|---|---|
action(string) | URL обработчика |
method(string) | HTTP-метод (GET, POST) |
ajax(bool) | AJAX-режим |
enctype(string) | Тип кодирования |
id(string) | ID формы |
class(string) | CSS-класс |
$form = (new FormBuilder())
->action('/api/users/save')
->method('POST')
->ajax(true)
->id('user-form')
->class('form-horizontal io-form');
Поля ввода
Текстовые поля
$form->text('name', [
'label' => 'Имя',
'placeholder' => 'Введите имя',
'required' => true,
]);
$form->email('email', [
'label' => 'Email',
'required' => true,
]);
$form->password('password', [
'label' => 'Пароль',
'required' => true,
]);
$form->tel('phone', [
'label' => 'Телефон',
'placeholder' => '+7 (999) 123-45-67',
]);
$form->url('website', [
'label' => 'Сайт',
]);
$form->search('query', [
'label' => 'Поиск',
]);
$form->number('quantity', [
'label' => 'Количество',
'min' => 0,
'max' => 100,
'step' => 1,
]);
$form->range('rating', [
'label' => 'Рейтинг',
'min' => 0,
'max' => 5,
'step' => 1,
]);
Многострочные поля
$form->textarea('description', [
'label' => 'Описание',
'rows' => 5,
'cols' => 40,
]);
Выбор
// Выпадающий список
$form->select('country', [
'' => '-- Выберите --',
'RU' => 'Россия',
'KZ' => 'Казахстан',
], [
'label' => 'Страна',
'required' => true,
]);
// Мульти-выбор
$form->multiSelect('roles', [
'admin' => 'Администратор',
'editor' => 'Редактор',
], ['label' => 'Роли']);
// Чекбокс
$form->checkbox('agree', [
'label' => 'Согласен с условиями',
'required' => true,
]);
// Radio-кнопки
$form->radio('gender', [
'male' => 'Мужской',
'female' => 'Женский',
], ['label' => 'Пол']);
// Toggle-переключатель
$form->toggle('active', [
'label' => 'Активен',
'value' => 1,
]);
Дата и время
$form->date('birth_date', ['label' => 'Дата рождения']);
$form->time('start_time', ['label' => 'Время начала']);
$form->datetime('event_at', ['label' => 'Дата и время события']);
Файлы
$form->file('document', [
'label' => 'Документ',
'accept' => '.pdf,.doc,.docx',
'max_size' => 10485760,
]);
$form->image('avatar', [
'label' => 'Аватар',
'accept' => 'image/*',
]);
Прочие
$form->hidden('user_id', 123);
$form->color('theme_color', ['label' => 'Цвет темы']);
$form->json('settings', ['label' => 'Настройки (JSON)']);
Раскладка
// Группировка полей
$form->group('personal', [
'label' => 'Личные данные',
], ['first_name', 'last_name', 'email']);
// Горизонтальный ряд
$form->row('address_row', [], ['city', 'street', 'house']);
// Разделитель
$form->divider('sep1', ['label' => 'Дополнительная информация']);
// Произвольный HTML
$form->html('notice', '<div class="alert alert-info">Важная информация</div>');
Кнопки
$form->submit('Сохранить', ['class' => 'btn btn-primary']);
$form->button('Отмена', ['class' => 'btn btn-secondary', 'onclick' => 'history.back()']);
$form->reset('Очистить', ['class' => 'btn btn-outline']);
Заполнение данными
// Заполнение формы данными из массива
$form->fill([
'first_name' => 'Иван',
'last_name' => 'Петров',
'email' => 'ivan@example.com',
]);
// Установка значений нескольких полей
$form->setFieldValues([
'name' => 'Иван',
'email' => 'ivan@example.com',
]);
// Получение значения поля
$email = $form->getFieldValue('email');
Валидация
$result = $form->validate($_POST);
// $result = [
// 'valid' => false,
// 'errors' => ['email' => 'Некорректное значение поля "Email": неверный формат email'],
// 'sanitized' => ['name' => 'Иван', 'email' => 'ivan@example.com'],
// ]
if (!$result['valid']) {
foreach ($result['errors'] as $field => $message) {
echo "$field: $message\n";
}
}
Поддерживаемые проверки:
| Тип | Проверка |
|---|---|
email | FILTER_VALIDATE_EMAIL |
url | FILTER_VALIDATE_URL |
tel | Regex телефона |
number, range | Число, min, max |
json | Валидный JSON |
date | Формат YYYY-MM-DD |
time | Формат HH:MM |
datetime | Формат YYYY-MM-DD HH:MM |
color | Формат #RRGGBB |
file, image | max_size, accept |
Также поддерживается пользовательский regex через ключ pattern:
$form->text('code', [
'label' => 'Код',
'pattern' => '/^[A-Z]{3}-\d{4}$/',
]);
Рендеринг
Как HTML
echo $form->render();
Как массив (для Twig)
$data = $form->toArray();
// Передать в шаблон:
$html = $app->twig->render('@app/forms/user.twig', $data);
Формат массива:
[
'action' => '/api/users/save',
'method' => 'POST',
'isAjax' => true,
'enctype' => '',
'formId' => 'user-form',
'formClass' => 'form-horizontal',
'fields' => [
'name' => ['type' => 'text', 'name' => 'name', 'label' => 'Имя', ...],
'email' => ['type' => 'email', 'name' => 'email', 'label' => 'Email', ...],
],
'buttons' => [
'submit_0' => ['type' => 'submit', 'label' => 'Сохранить', 'class' => 'btn btn-primary'],
],
]
Полный пример
use IO\Form\FormBuilder;
class UserRoute extends \IO\Route
{
public function editForm(): \IO\Response
{
$user = \IO\Core::callAction('app.model.user.getByID', ['pkid' => $this->args['id']]);
$form = (new FormBuilder())
->action('/api/users/save')
->method('POST')
->id('edit-user-form')
->class('form-card')
->text('name', ['label' => 'Имя', 'required' => true])
->email('email', ['label' => 'Email', 'required' => true])
->tel('phone', ['label' => 'Телефон'])
->select('role', [
'user' => 'Пользователь',
'admin' => 'Администратор',
], ['label' => 'Роль'])
->toggle('active', ['label' => 'Активен'])
->hidden('pkid', $user['pkid'])
->submit('Сохранить', ['class' => 'btn btn-primary']);
$form->fill($user);
return $this->render('@app/pages/edit-user.twig', [
'form' => $form->toArray(),
]);
}
}