Form
-
class
Cake\View\Helper\
FormHelper
(View $view, array $config = [])
FormHelper делает большую часть тяжелой работы по созданию формы.
FormHelper фокусируется на создании форм быстро, таким образом, чтобы упростить проверку,
перенаселение и компоновку. FormHelper также является гибким - он будет делать почти всё
за вас, используя соглашения, или вы можете использовать определенные методы, чтобы
получить только то, что вам нужно.
Запуск формы
-
Cake\View\Helper\FormHelper::
create
(mixed $context = null, array $options = [])
$context
- Контекст, для которого определяется форма. Может быть объектом ORM, набором результатов ORM, массивом метаданных или false/null
(чтобы сделать форму без модели).
$options
- Массив параметров и/или атрибутов HTML.
Первым методом, который вам нужно использовать для использования FormHelper, является create()
.
Этот метод выводит тег открытия формы.
Все параметры являются необязательными. Если create()
вызывается без заданных
параметров, предполагается, что вы создаёте форму, которая отправляется текущему
контроллеру через текущий URL-адрес. Метод отправки по умолчанию - POST.
Если вы вызвали create()
внутри представления для
UsersController::add()
, вы увидите что-то вроде следующего вывода в
визуализированном представлении:
<form method="post" action="/users/add">
Аргумент $context
используется как „контекст“ формы. Существует несколько
встроенных контекстов формы, и вы даже можете добавить свои собственные контексты,
которые мы рассмотрим ниже, в следующем разделе. Встроенные провайдеры отображают
следующие значения $context
:
Экземпляр Entity
или итератор будут отображаться в
EntityContext;
этот контекстный класс позволяет FormHelper работать с результатами встроенной ORM.
Массив, содержащий ключ schema
, будет отображаться в
ArrayContext,
который позволяет вам создание простых структур данных для ваших форм.
null
и false
будут отображаться в
NullContext;
этот контекстный класс требуется интерфейсу FormHelper. Этот контекст полезен,
если вы хотите создать короткую форму, которая не требует постоянной ORM.
Все классы контекста также имеют доступ к данным запроса, что упрощает создание форм.
Когда форма создана с контекстом, все созданные вами элементы управления будут
использовать активный контекст. В случае поддерживаемой формы ORM FormHelper может
обращаться к связанным данным, ошибкам проверки и метаданным схемы. Вы можете закрыть
активный контекст с помощью метода end()
и снова его вызвать create()
.
Чтобы создать форму для объекта, выполните следующие действия:
// Если вы находитесь на /articles/add
// $article должна быть пустым элементом статьи
echo $this->Form->create($article);
Вывод:
<form method="post" action="/articles/add">
Это будут POST данные формы для метода add()
экшена в ArticlesController.
И вы также можете использовать ту же логику для создания формы редактирования.
FormHelper использует объект Entity
для автоматического определения того,
следует ли создавать форму добавления или редактирования. Если предоставленный
объект не является новым, форма будет создана как форма для редактирования.
Например, если мы перейдем к http://example.org/articles/edit/5, мы можем сделать следующее:
// src/Controller/ArticlesController.php:
public function edit($id = null)
{
if (empty($id)) {
throw new NotFoundException;
}
$article = $this->Articles->get($id);
// Здесь логика сохранения
$this->set('article', $article);
}
// View/Articles/edit.ctp:
// Поскольку $article->isNew() является ложным, мы получим форму редактирования
<?= $this->Form->create($article) ?>
Вывод:
<form method="post" action="/articles/edit/5">
<input type="hidden" name="_method" value="PUT" />
Примечание
Поскольку это форма редактирования, то создаётся скрытое поле input
для переопределения метода HTTP по умолчанию.
Варианты создания формы
Массив $options
- это то, где происходит большая часть конфигурации формы.
Этот специальный массив может содержать несколько различных пар ключ-значение,
которые влияют на способ создания тега формы. Допустимые значения:
'type'
- Позволяет выбрать тип создаваемой формы. Если тип не указан, он
будет определён автоматически на основе контекста формы. Допустимые значения:
'get'
- Будет установлен метод формы HTTP GET.
'file'
- Будет установлен метод формы HTTP POST и 'enctype'
в
«multipart/form-data».
'post'
- Будет установлен метод формы HTTP POST.
'put', 'delete', 'patch'
- При передаче формы будет переопределять метод
HTTP с помощью PUT, DELETE или PATCH соответственно.
'method'
- Допустимые значения такие же, как указано выше. Позволяет явно
переопределить метод формы.
'url'
- Укажите URL-адрес, в который будут отправляться данные из формы. Может быть
строкой или массивом URL.
'encoding'
- Устанавливает кодировку accept-charset
для формы. По умолчанию используется
Configure::read('App.encoding')
.
'enctype'
- Позволяет явно установить кодировку формы.
'templates'
- Шаблоны, которые вы хотите использовать для этой формы. Любые предоставленные
шаблоны будут объединены поверх уже загруженных шаблонов. Может быть либо именем
файла (без расширения) из /config
, либо массивом шаблонов для использования.
'context'
- Дополнительные параметры для класса контекста формы. (Например, EntityContext
принимает параметр 'table'
, который позволяет вам установить конкретный класс
таблицы, на котором должна быть основана форма.)
'idPrefix'
- Префикс для генерирования атрибутов ID.
'templateVars'
- Позволяет предоставить шаблонные переменные для шаблона formStart
.
Совет
Помимо указанных выше опций вы можете указать в аргументе $options
любые допустимые атрибуты HTML, которые вы хотите передать созданному элементу form
.
Изменение метода HTTP для формы
С помощью опции type
вы можете изменить метод HTTP, который будет использоваться формой:
echo $this->Form->create($article, ['type' => 'get']);
Вывод:
<form method="get" action="/articles/edit/5">
Указание значения 'file'
для type
, изменяет метод отправки формы на „post“,
и включает в себя enctype
из «multipart/form-data» в теге формы. Это должно
использоваться, если в форме есть какие-либо элементы файла. Отсутствие правильного
атрибута enctype
приведёт к тому, что загрузка файла не будет функционировать.
Например:
echo $this->Form->create($article, ['type' => 'file']);
Вывод:
<form enctype="multipart/form-data" method="post" action="/articles/add">
При использовании значений 'put'
, 'patch'
или 'delete'
как значение 'type'
,
ваша форма будет функционально эквивалентна форме „post“, но тогда представленный,
метод HTTP-запроса будет переопределён как „PUT“, „PATCH“ или „DELETE“, соответственно.
Это позволяет CakePHP эмулировать правильную поддержку REST в веб-браузерах.
Установка URL-адреса для формы
Использование опции 'url'
позволяет указать путь до определенного экшена
в текущем контроллере или другом контроллере в вашем приложении.
Для примера, если вы хотите указать форму для метода login()
текущего контроллера,
вы должны написать массив $options
, например следующий:
echo $this->Form->create($article, ['url' => ['action' => 'login']]);
Вывод:
<form method="post" action="/users/login">
Если желаемое действие формы отсутствует в текущем контроллере, вы можете указать
полный URL-адрес до экшена для формы. Приведенный URL-адрес может относиться к
вашему приложению CakePHP:
echo $this->Form->create(null, [
'url' => ['controller' => 'Articles', 'action' => 'publish']
]);
Вывод:
<form method="post" action="/articles/publish">
Или вы можете указать внешний домен:
echo $this->Form->create(null, [
'url' => 'http://www.google.com/search',
'type' => 'get'
]);
Вывод:
<form method="get" action="http://www.google.com/search">
Используйте 'url' => false
, если вы не хотите использовать URL-адрес в качестве экшена формы.
Использование пользовательских валидаторов
Часто модели будут иметь множество наборов проверки, и вы захотите,
чтобы FormHelper маркировал необходимые поля, на основе определенных правил проверки,
которые будет действовать для ваших контроллеров. Например, таблица „users“ имеет
специальные правила проверки, которые применяются только при регистрации учетной
записи:
echo $this->Form->create($user, [
'context' => ['validator' => 'register']
]);
Вышеизложенное будет использовать правила, определенные в валидаторе
register
, которые определяются UsersTable::validationRegister()
,
для $user
и всех связанных ассоциаций. Если вы создаёте форму для
связанных объектов, вы можете определить правила проверки для каждой ассоциации,
используя массив:
echo $this->Form->create($user, [
'context' => [
'validator' => [
'Users' => 'register',
'Comments' => 'default'
]
]
]);
Вышеизложенное будет использовать register
для пользователя и default
для комментариев пользователя.
Создание классов контекста
Хотя встроенные классы контекста предназначены для охвата основных случаев,
с которыми вы столкнетесь, вам может понадобиться построить новый класс контекста,
если вы используете другую ORM. В этих ситуациях вам нужно реализовать
Cake\View\Form\ContextInterface .
После того как вы внедрили этот интерфейс, вы можете связать свой новый контекст
с FormHelper. Часто бывает лучше сделать это в прослушивателе событий
View.beforeRender
или в классе представления приложения:
$this->Form->addContextProvider('myprovider', function ($request, $data) {
if ($data['entity'] instanceof MyOrmClass) {
return new MyProvider($request, $data);
}
});
Контекстные фабричные функции - это то, где вы можете добавить логику для проверки
параметров формы для проверки правильности типа объекта. Если найдены совпадающие
входные данные, вы можете вернуть объект. Если нет совпадения, возвращаем null.
Создание элементов управления формы
-
Cake\View\Helper\FormHelper::
control
(string $fieldName, array $options = [])
$fieldName
- Имя поля в форме 'Modelname.fieldname'
.
$options
- Необязательный массив, который может включать как
Опции для Control, так и опции других методов
(которые control()
использует внутри для генерации различных элементов HTML),
а также любые допустимые атрибуты HTML.
Метод control()
позволяет создавать полные(законченные) элементы управления формой. Эти
элементы управления будут включать в себя обёртку div
, label
, виджет управления и ошибки проверки(валидации), если это
необходимо. Используя метаданные в контексте формы, этот метод выберет соответствующий тип управления для каждого поля. Внутри себя метод control()
использует другие методы FormHelper.
Совет
Обратите внимание, что, хотя поля, созданные методом control()
, называются в общем «inputs» на этой странице, технически говоря, метод control()
может генерировать не только одни input
элементы HTML, но также и другие элементы HTML-формы (Например select
, button
, textarea
).
По умолчанию метод control()
будет использовать следующие шаблоны виджетов:
'inputContainer' => '<div class="input {{type}}{{required}}">{{content}}</div>'
'input' => '<input type="{{type}}" name="{{name}}"{{attrs}}/>'
В случае ошибок проверки он также будет использовать:
'inputContainerError' => '<div class="input {{type}}{{required}} error">{{content}}{{error}}</div>'
Тип созданного элемента управления (когда мы не предоставляем никаких дополнительных опций для указания
типа сгенерированного элемента) выводится с помощью интроспекции модели и зависит от типа столбца:
- Column Type
Resulting Form Field
- string, uuid (char, varchar, etc.)
text
- boolean, tinyint(1)
checkbox
- decimal
number
- float
number
- integer
number
- text
textarea
- text, with name of password, passwd
password
- text, with name of email
email
- text, with name of tel, telephone, or phone
tel
- date
day, month, and year selects
- datetime, timestamp
day, month, year, hour, minute, and meridian selects
- time
hour, minute, and meridian selects
- binary
file
Параметр $options
позволяет вам выбрать конкретный тип управления,
который вам нужен:
echo $this->Form->control('published', ['type' => 'checkbox']);
Совет
Как небольшая тонкость, генерирование определенных элементов с помощью метода формы control()
всегда будет по умолчанию генерировать обёртку div
. Генерирование одного и того же типа элемента с помощью одного из методов конкретной формы (например, $this->Form->('published');
) в большинстве случаев не будет генерировать обёртку div
. В зависимости от ваших потребностей вы можете использовать тот или иной способ.
Оболочка div
будет иметь добавленное имя required
, если правила
валидации для поля модели указывают, что это необходимо и оно не должно
быть пустым. Вы можете отключить автоматическую пометку required
,
используя опцию `required`
:
echo $this->Form->control('title', ['required' => false]);
Чтобы пропустить запуск проверки браузера для всей формы, вы можете установить опцию
'formnovalidate' => true
для кнопки ввода, которую вы создаёте, используя
View\Helper\FormHelper::submit()
или установите 'novalidate' => true
в опции для View\Helper\FormHelper::create()
.
Например, предположим, что модель ваших пользователей содержит поля для
username (varchar), password (varchar), approved (datetime) и quote (text).
Вы можете использовать метод control()
FormHelper для создания соответствующих
элементов управления для всех этих полей формы:
echo $this->Form->create($user);
// Генерируем текстовый input
echo $this->Form->control('username');
// Генерируем парольный input
echo $this->Form->control('password');
// Предполагается, что 'approved' - это поле даты или времени,
// генерирующее: День, Месяц, Год, Час, Минуту
echo $this->Form->control('approved');
// Генерируем элемент textarea (текстовую область)
echo $this->Form->control('quote');
// Генерируем кнопку
echo $this->Form->button('Add');
echo $this->Form->end();
Более подробный пример, показывающий некоторые параметры для поля даты:
echo $this->Form->control('birth_dt', [
'label' => 'Date of birth',
'minYear' => date('Y') - 70,
'maxYear' => date('Y') - 18,
]);
Помимо специфических Опции для Control,
вы также можете указать любую опцию, принятую соответствующим специальным
методом для выбранного типа управления (или предполагаемого CakePHP) и
любого атрибута HTML (например, onfocus
).
Если вы хотите создать поле формы select
с использованием отношения
belongsTo (или hasOne), вы можете добавить следующее в свой
UserController (при условии, что ваш пользователь belongsTo -
принадлежит группе):
$this->set('groups', $this->Users->Groups->find('list'));
После этого добавьте в шаблон вида следующее:
echo $this->Form->control('group_id', ['options' => $groups]);
Чтобы сделать поле select
для ассоциации belongsToMany групп, вы можете
добавить следующее в свой UserController:
$this->set('groups', $this->Users->Groups->find('list'));
После этого, добавьте в шаблон вида следующее:
echo $this->Form->control('groups._ids', ['options' => $groups]);
Если имя вашей модели состоит из двух или более слов (например, «UserGroups»),
при передаче данных с помощью set()
вы должны называть свои данные в множественном
числе и нижнем camelCased и
lower camelCased
следующим образом:
$this->set('userGroups', $this->UserGroups->find('list'));
Соглашения об именах полей
При создании виджетов control вы должны указывать свои поля после соответствующих
атрибутов в объекте форм. Например, если вы создали форму для объекта $article
,
вы должны создать поля, названные в честь его свойств. Например. title
, body
и
published
.
Вы можете создавать элементы управления для связанных моделей или произвольных моделей,
передавая association.fieldname
первым параметром:
echo $this->Form->control('association.fieldname');
Любые точки в именах полей будут преобразованы в данные вложенных запросов.
Например, если вы создали поле с именем 0.comments.body
, вы получили бы
атрибут имени, который выглядит как 0[comments][body]
. Это соглашение
упрощает сохранение данных с помощью ORM. Подробности для различных типов
ассоциаций можно найти в разделе Создание инпутов для связанных данных section.
При создании элементов управления, связанных с датой, FormHelper добавит
field-suffix (суфик поля). Вы можете заметить дополнительные поля с именем
year
, month
, day
, hour
, minute
или meridian
.
Эти поля автоматически преобразуются в объекты DateTime
, когда
сортируются эти объекты.
Опции для Control
FormHelper::control()
поддерживает большое количество опций с помощью аргумента
$options
. В дополнение к своим собственным опциям control()
принимает опции
для выведенных/выбранных сгенерированных типов control (например, для checkbox
или textarea
), а также для атрибутов HTML.
В этом подразделе будут рассмотрены варианты, специфичные (исключительно) для
FormHelper::control()
.
$options['type']
- Строка, определяющая тип виджета, который будет сгенерирован.
В дополнение к типам полей, найденным в Создание элементов управления формы, вы также можете
создавать 'file'
, 'password'
и любой другой тип, поддерживаемый HTML5. Указав
'type'
, вы будете вынуждать тип сгенерированного элемента control, переопределять
интроспекцию модели. По умолчанию используется значение null
.
Например:
echo $this->Form->control('field', ['type' => 'file']);
echo $this->Form->control('email', ['type' => 'email']);
Вывод:
<div class="input file">
<label for="field">Field</label>
<input type="file" name="field" value="" id="field" />
</div>
<div class="input email">
<label for="email">Email</label>
<input type="email" name="email" value="" id="email" />
</div>
$options['label']
- Либо заголовок строки, либо массив ссылок
options for the label. Вы можете установить этот
ключ в строку, которую вы хотите отобразить в label, который обычно
сопровождает HTML элемент input
. По умолчанию используется значение null
.
Например:
echo $this->Form->control('name', [
'label' => 'The User Alias'
]);
Вывод:
<div class="input">
<label for="name">The User Alias</label>
<input name="name" type="text" value="" id="name" />
</div>
Кроме того, можно установить этот ключ в false
, чтобы отключить генерацию
элемента label
.
Например:
echo $this->Form->control('name', ['label' => false]);
Вывод:
<div class="input">
<input name="name" type="text" value="" id="name" />
</div>
Установите это в массив, чтобы предоставить дополнительные параметры для
элемента `` label``. Если вы это сделаете, вы можете использовать ключ 'text'
в массиве для настройки текста label.
Например:
echo $this->Form->control('name', [
'label' => [
'class' => 'thingy',
'text' => 'The User Alias'
]
]);
Вывод:
<div class="input">
<label for="name" class="thingy">The User Alias</label>
<input name="name" type="text" value="" id="name" />
</div>
$options['options']
- Здесь вы можете указать массив, содержащий элементы,
которые должны быть сгенерированы для виджетов, таких как radio
или select
,
для которых требуется массив элементов в качестве аргумента (см Создание radio кнопок
и Создание селектов (выборщиков) для получения более подробной информации).
По умолчанию используется значение null
.
$options['error']
- Использование этого ключа позволяет переопределить сообщения об
ошибках модели по умолчанию и может использоваться, например, для установки сообщений i18n.
Чтобы отключить вывод сообщения об ошибках и полевые классы, установите ключ 'error'
в
false
. По умолчанию используется значение null
.
Например:
echo $this->Form->control('name', ['error' => false]);
Чтобы переопределить сообщения об ошибках модели, используйте массив с ключами,
соответствующими исходным сообщениям об ошибках валидации.
Например:
$this->Form->control('name', [
'error' => ['Not long enough' => __('This is not long enough')]
]);
Как видно выше, вы можете установить сообщение об ошибке для каждого правила валидации,
которое у вас есть в ваших моделях. Кроме того, вы можете предоставить сообщения i18n
для своих форм.
$options['nestedInput']
- Используется с флажками и переключателями. Контролирует,
генерируется ли элемент ввода внутри или вне элемента label
. Когда control()
генерирует флажок или переключатель, вы можете установить это значение в false
,
чтобы заставить генерировать HTML элемент input
вне элемента label
.
С другой стороны, вы можете установить это значение в true
для любого типа control,
чтобы принудительно сгенерировать элемент ввода внутри label. Если вы измените это для
переключателей, вам также необходимо изменить шаблон по умолчанию
radioWrapper. В зависимости от сгенерированного типа control,
он по умолчанию имеет значение true
или false
.
$options['templates']
- Шаблоны, которые вы хотите использовать для этого input.
Любые указанные шаблоны будут объединены поверх уже загруженных шаблонов. Этот параметр
может быть либо именем файла (без расширения) в /config
, который содержит шаблоны,
которые вы хотите загрузить, так и массивом шаблонов.
$options['labelOptions']
- Установите для этого параметра значение false
, чтобы
отключить метки (label) вокруг nestedWidgets
или установить его в массив атрибутов, который
будет передан тегу label
.
Создание специализированных элементов управления
В дополнение к общему методу control()
, FormHelper
имеет специальные методы для создания
нескольких различных типов элементов управления. Они могут быть использованы для создания собственно
виджета управления и в сочетании с другими методами, такими как
View\Helper\FormHelper::label()
и
View\Helper\FormHelper::error()
для создания полностью настраиваемых макетов форм.
Общие параметры для специализированных элементов управления
Многие из различных методов элемента управления поддерживают общий набор опций,
которые в зависимости от используемого метода формы должны быть предоставлены
внутри $options
или в массиве аргументов $attributes
. Все эти опции также
поддерживаются методом control()
.
Чтобы уменьшить повторение, используемых всеми методами управления одинаковых параметров, опишем их:
'id'
- Установите этот ключ, чтобы принудительно установить значение идентификатора
DOM для элемента управления. Это переопределит 'idPrefix'
, который может быть установлен.
'default'
- Используется для установки значения по умолчанию для поля управления.
Значение используется, если данные, переданные в форму, не содержат значения для поля
(или если данные вообще не передаются). Явное значение по умолчанию переопределит любые значения
по умолчанию, определенные в схеме.
Пример использования:
echo $this->Form->text('ingredient', ['default' => 'Sugar']);
Пример с полем select
(«Medium» размер будет выбран по умолчанию):
$sizes = ['s' => 'Small', 'm' => 'Medium', 'l' => 'Large'];
echo $this->Form->select('size', $sizes, ['default' => 'm']);
Примечание
Вы не можете использовать default
для проверки checkbox - вместо этого вы можете установить значение в $this->request->getData()
в своём контроллере или установить параметр управления 'checked'
в true
.
Остерегайтесь использования false
для назначения значения по умолчанию. Значение false
используется для отключения/исключения опций поля управления, поэтому 'default' => false
не будет устанавливать никакого значения вообще. Вместо этого используйте 'default' => 0
.
'value'
- Form, Entity или request->getData()
например,
используется для установки определенного значения для поля управления.
Это переопределит любое значение, которое может быть добавлено из контекста,
например Form, Entity или request->getData()
и т.д.
Примечание
Если вы хотите, чтобы поле не отображало его значение из контекста или valuesSource
, вам нужно установить 'value'
в ''
(вместо того, чтобы устанавливать его в null
).
В дополнение к вышеуказанным параметрам вы можете микшировать любой атрибут HTML,
который хотите использовать. Любое неспециализированное имя опции будет рассматриваться
как атрибут HTML и применяться к сгенерированному элементу управления HTML.
Изменено в версии 3.3.0: Начиная с версии 3.3.0, FormHelper автоматически будет использовать любые значения по умолчанию,
определенные в схеме базы данных. Вы можете отключить это поведение, установив опцию
schemaDefault
в false
.
Создание ярлыков
-
Cake\View\Helper\FormHelper::
label
(string $fieldName, string $text, array $options)
Создаёт элемент label
. Аргумент $fieldName
используется для генерации
HTML атрибута for
для элемента; если $text
не определено, $fieldName
также будет использоваться для изменения атрибута text
.
Например:
echo $this->Form->label('User.name');
echo $this->Form->label('User.name', 'Your username');
Вывод:
<label for="user-name">Name</label>
<label for="user-name">Your username</label>
Когда вы устанавливаете $options
как строку, она будет использоваться
как имя класса:
echo $this->Form->label('User.name', null, ['id' => 'user-label']);
echo $this->Form->label('User.name', 'Your username', 'highlight');
Вывод:
<label for="user-name" id="user-label">Name</label>
<label for="user-name" class="highlight">Your username</label>
Отображение и проверка ошибок
FormHelper предоставляет несколько методов, которые позволяют нам легко
проверять ошибки полей и при необходимости отображать индивидуальные
сообщения об ошибках.
Отображение ошибок
-
Cake\View\Helper\FormHelper::
error
(string $fieldName, mixed $text, array $options)
$fieldName
- Имя поля в форме 'Modelname.fieldname'
.
$text
- Необязательный. Строка или массив, содержащие сообщения
об ошибках. Если массив, то он должен быть хэшем имён ключей => сообщений.
По умолчанию используется значение null
.
$options
- Необязательный массив, который может содержать только логическое значение с ключом
'escape'
, который определит, будет ли HTML выводить содержимое сообщения об ошибке.
По умолчанию используется true
.
Показывает сообщение об ошибке проверки, заданное в $text
, для данного поля в
случае ошибки проверки. Если $text
не указан, будет использовано сообщение об
ошибке проверки по умолчанию для этого поля.
Использует следующие шаблоны виджетов:
'error' => '<div class="error-message">{{content}}</div>'
'errorList' => '<ul>{{content}}</ul>'
'errorItem' => '<li>{{text}}</li>'
Шаблоны 'errorList'
и 'errorItem'
используются для форматирования нескольких сообщений
об ошибках в поле.
Пример:
// Если в TicketsTable у вас есть правило проверки 'notEmpty':
public function validationDefault(Validator $validator)
{
$validator
->requirePresence('ticket', 'create')
->notEmpty('ticket');
}
// И внутри Templates/Tickets/add.ctp у вас есть:
echo $this->Form->text('ticket');
if ($this->Form->isFieldError('ticket')) {
echo $this->Form->error('ticket', 'Полностью настраиваемое сообщение об ошибке!');
}
Если вы нажмёте кнопку Отправить своей формы, не указав значение поля Ticket,
ваша форма выведет:
<input name="ticket" class="form-error" required="required" value="" type="text">
<div class="error-message">Полностью настраиваемое сообщение об ошибке!</div>
Примечание
При использовании View\Helper\FormHelper::control()
, ошибки отображаются по умолчанию, поэтому вам не нужно использовать isFieldError()
или вручную вызывать error()
.
Совет
Если вы используете определенное поле модели для создания нескольких полей
формы через control()
, и вы хотите, чтобы одно и то же сообщение об ошибке
проверки было отображено для каждого из них, вам, вероятно, будет лучше
определить собственное сообщение об ошибке внутри соответствующего номера
validator rules.
Проверка ошибок
-
Cake\View\Helper\FormHelper::
isFieldError
(string $fieldName)
Возвращает true
, если в $fieldName
найдена ошибка,
иначе возвращает false
.
Example:
if ($this->Form->isFieldError('gender')) {
echo $this->Form->error('gender');
}
Создание кнопок и элементов submit
Создание элементов Submit
-
Cake\View\Helper\FormHelper::
submit
(string $caption, array $options)
$caption
- Необязательная строка, содержащая текстовую подпись кнопки
или путь к изображению. По умолчанию используется 'Submit'
.
$options
- Необязательный массив, включающий любые
Общие параметры для специализированных элементов управления, или конкретные параметры отправки (см. ниже),
а также любые допустимые атрибуты HTML.
Создаёт элемент input
типа submit
, с $caption
в качестве значения.
Если представленная $caption
является URL-адресом, указывающим на изображение
(т е. если строка содержит „://“ или содержит какие-либо расширения
„.jpg, .jpe, .jpeg, .gif“), изображение кнопки submit будет сгенерировано с
использованием указанного изображения, если оно существует. Если первым символом
является „/“, то путь изображения относится к webroot, иначе если первый символ
не является „/“, то путь изображения относится к webroot/img.
По умолчанию будут использоваться следующие шаблоны виджета:
'inputSubmit' => '<input type="{{type}}"{{attrs}}/>'
'submitContainer' => '<div class="submit">{{content}}</div>'
Опции для Submit
'type'
- Установите эту опцию на 'reset'
, чтобы создать кнопки сброса.
По умолчанию используется 'submit'
.
'templateVars'
- Установите этот массив для предоставления дополнительных
переменных шаблона для входного элемента и его контейнера.
Любые другие предоставленные атрибуты будут назначены элементу input
.
Следующее:
echo $this->Form->submit('Click me');
Выведет:
<div class="submit"><input value="Click me" type="submit"></div>
Вы можете передать относительный или абсолютный URL-адрес изображения
в параметр caption вместо текста подписи:
echo $this->Form->submit('ok.png');
Вывод:
<div class="submit"><input type="image" src="/img/ok.png"></div>
Submit полезен, когда вам нужен только базовый текст или изображения.
Если вам нужно более сложное содержимое кнопки, вы должны использовать button()
.
Создание элементов кнопок
-
Cake\View\Helper\FormHelper::
button
(string $title, array $options = [])
Создаёт кнопку HTML с указанным заголовком и по умолчанию типом 'button'
.
Опции кнопки
$options['type']
- Вы можете установить это для одного из следующих
трёх возможных значений:
'submit'
- Подобно методу $this->Form->submit()
он создаст кнопку отправки. Однако это не создаст обёртку div
, как в submit()
. Это тип по умолчанию.
'reset'
- Создаёт кнопку сброса формы.
'button'
- Создаёт стандартную кнопку.
$options['escape']
- Boolean. Если установлено значение true
,
HTML кодирует значение, указанное внутри $title
. По умолчанию
используется false
.
Для примера:
echo $this->Form->button('Кнопка');
echo $this->Form->button('Другая кнопка', ['type' => 'button']);
echo $this->Form->button('Сбросить форму', ['type' => 'reset']);
echo $this->Form->button('Отправить форму', ['type' => 'submit']);
Вывод:
<button type="submit">Кнопка</button>
<button type="button">Другая кнопка</button>
<button type="reset">Сбросить форму</button>
<button type="submit">Отправить форму</button>
Пример использования опции 'escape'
:
// Выведет экранированный HTML.
echo $this->Form->button('<em>Отправить форму</em>', [
'type' => 'submit',
'escape' => true
]);
Закрытие формы
-
Cake\View\Helper\FormHelper::
end
($secureAttributes = [])
Метод end()
закрывает и завершает форму. Часто end()
выводит только
тег закрывающей формы, но использование end()
является хорошей практикой,
поскольку позволяет FormHelper вставлять скрытые элементы формы, которые требует
Cake\Controller\Component\SecurityComponent
:
<?= $this->Form->create(); ?>
<!-- Элементы формы идут сюда -->
<?= $this->Form->end(); ?>
Если вам нужно добавить дополнительные атрибуты к сгенерированным скрытым полям input,
вы можете использовать аргумент $secureAttributes
.
Например:
echo $this->Form->end(['data-type' => 'hidden']);
Вывод:
<div style="display:none;">
<input type="hidden" name="_Token[fields]" data-type="hidden"
value="2981c38990f3f6ba935e6561dc77277966fabd6d%3AAddresses.id">
<input type="hidden" name="_Token[unlocked]" data-type="hidden"
value="address%7Cfirst_name">
</div>
Примечание
Если вы используете Cake\Controller\Component\SecurityComponent
в вашем приложении вы всегда должны заканчивать свои формы с помощью end()
.
Создание автономных кнопок и POST-ссылок
Создание POST-кнопок
-
Cake\View\Helper\FormHelper::
postButton
(string $title, mixed $url, array $options = [])
$title
- Обязательная строка, содержащая текстовую подпись кнопки.
По умолчанию не кодируется HTML.
$url
- URL-адрес формы, представленной в виде строки или массива.
$options
- Необязательный массив, включающий любой из
Общие параметры для специализированных элементов управления, или конкретных параметров (см. ниже),
а также любых допустимых атрибутов HTML.
Создаёт тег <button>
окружённый элементами <form>
, который отправляется
через POST по умолчанию. Кроме того, по умолчанию он генерирует скрытые поля ввода
для SecurityComponent.
Опции для кнопки POST
'data'
- Массив с ключом/значением для передачи скрытого ввода.
'method'
- Используемый метод запроса. Например, для 'delete'
для имитации HTTP/1.1 DELETE запроса. По умолчанию используется 'post'
.
'form'
- Массив с любой опцией, которую FormHelper::create()
может принимать.
Кроме того, метод postButton()
принимает параметры, которые действительны для метода button()
.
Для примера:
// В Templates/Tickets/index.ctp
<?= $this->Form->postButton('Delete Record', ['controller' => 'Tickets', 'action' => 'delete', 5]) ?>
Выведет HTML, похожий на:
<form method="post" accept-charset="utf-8" action="/Rtools/tickets/delete/5">
<div style="display:none;">
<input name="_method" value="POST" type="hidden">
</div>
<button type="submit">Delete Record</button>
<div style="display:none;">
<input name="_Token[fields]" value="186cfbfc6f519622e19d1e688633c4028229081f%3A" type="hidden">
<input name="_Token[unlocked]" value="" type="hidden">
<input name="_Token[debug]" value="%5B%22%5C%2FRtools%5C%2Ftickets%5C%2Fdelete%5C%2F1%22%2C%5B%5D%2C%5B%5D%5D" type="hidden">
</div>
</form>
Поскольку этот метод генерирует элемент form
, не используйте этот метод
в уже открытой форме. Вместо этого используйте
Cake\View\Helper\FormHelper::submit()
or Cake\View\Helper\FormHelper::button()
для создания кнопок
внутри открытых форм.
Создание POST-ссылок
-
Cake\View\Helper\FormHelper::
postLink
(string $title, mixed $url = null, array $options = [])
$title
- Обязательная строка, предоставляющая текст, который будет обёрнут
в теги <a>
.
$url
- Необязательный. Строка или массив,
содержащий URL-адрес формы (Cake-relative или внешний URL-адрес, начинающийся с http://
).
$options
- Необязательный массив, включающий любой из
Общие параметры для специализированных элементов управления, или конкретных параметров (см. ниже), а также любых
допустимых атрибутов HTML.
Создает HTML-ссылку, но обращается к URL-адресу, используя указанный вами метод
(по умолчанию - POST). Требуется включить JavaScript в браузере.
Опции для POST-ссылки
'data'
- Массив с ключом/значением для передачи скрытого ввода.
'method'
- Используемый метод запроса. Например, для 'delete'
для имитации HTTP/1.1 DELETE запроса. По умолчанию используется 'post'
.
'confirm'
- Сообщение подтверждения отображается при нажатии. По
умолчанию null
.
'block'
- Установите этот параметр в true
, чтобы добавить форму
для просмотра блока 'postLink'
или указать имя настраиваемого блока.
По умолчанию используется значение `` null``.
Кроме того, метод postLink()
будет принимать параметры, которые
действительны для метода link()
.
Этот метод создаёт элемент <form>
. Если вы хотите использовать этот
метод внутри существующей формы, вы должны использовать опцию block
,
чтобы новая форма была установлена в view block,
которые могут отображаться вне основной формы.
Если всё, что вы ищете, это кнопка для отправки вашей формы, то вы должны
использовать вместо этого Cake\View\Helper\FormHelper::button()
или Cake\View\Helper\FormHelper::submit()
.
Примечание
Не ставьте postLink в открытую форму. Вместо этого используйте параметр block
для буферизации формы в view block
Создание цельных форм
Создание нескольких элементов управления
-
Cake\View\Helper\FormHelper::
controls
(array $fields = [], $options = [])
$fields
- Массив полей для генерации. Позволяет настраивать
настраиваемые типы, метки и другие параметры для каждого указанного поля.
$options
- Необязательный. Множество опций. Допустимые ключи:
'fieldset'
- Установите для этого параметра значение false
,
чтобы отключить набор полей. Если пуст, набор полей будет включен.
Также может быть массив параметров, которые будут применяться как HTML
атрибуты к тегу fieldset
.
legend
- Строка используется для настройки текста legend
.
Установите это в false
, чтобы отключить легенду для сгенерированного
набора входных данных.
Создаёт набор элементов управления для данного контекста, завёрнутых в fieldset
.
Вы можете указать сгенерированные поля, включив их:
echo $this->Form->controls([
'name',
'email'
]);
Вы можете настроить текст легенды, используя опцию:
echo $this->Form->controls($fields, ['legend' => 'Update news post']);
Вы можете настроить сгенерированные элементы управления, указав дополнительные
параметры в параметре $fields
:
echo $this->Form->controls([
'name' => ['label' => 'custom label']
]);
При настройке $fields
вы можете использовать параметр $options
для
управления сгенерированным набором легенд/полей.
Для примера:
echo $this->Form->controls(
[
'name' => ['label' => 'custom label']
],
['legend' => 'Update your post']
);
Если вы отключите fieldset
, legend
не будет напечатан.
Создание элементов управления для всего объекта
-
Cake\View\Helper\FormHelper::
allControls
(array $fields, $options = [])
$fields
- Необязательный. Массив настроек для полей,
которые будут сгенерированы. Позволяет настраивать настраиваемые типы,
метки и другие параметры.
$options
- Необязательный. Множество опций. Допустимые ключи:
'fieldset'
- Установите для этого параметра значение false
,
чтобы отключить набор полей. Если пуст, набор полей будет включен.
Также может быть массив параметров, которые будут применяться в
качестве атрибутов HTML для тега fieldset
.
legend
- Строка используется для настройки текста legend
.
Установите её в false
, чтобы отключить легенду для сгенерированного
набора управления.
Этот метод тесно связан с controls()
, однако аргумент $fields
по умолчанию
имеет все поля в текущем объекте верхнего уровня. Чтобы исключить определенные
поля из созданных элементов управления, установите их в false
в параметре
$fields
:
echo $this->Form->allControls(['password' => false]);
// Или до 3.4.0:
echo $this->Form->allInputs(['password' => false]);
Добавление пользовательских виджетов
CakePHP упрощает добавление пользовательских элементов управления в ваше приложение
и использует их, как и любой другой тип управления. Все основные типы управления
реализованы как виджеты, что означает, что вы можете переопределить любой основной
виджет вашей собственной реализацией.
Создание класса виджета
Классы виджетов имеют очень простой интерфейс. Они должны реализовать
Cake\View\Widget\WidgetInterface
. Для этого интерфейса необходимы
методы render(array $data)
и secureFields(array $data)
. Метод render()
ожидает массив данных для создания виджета и, как ожидается, вернёт строку HTML
для виджета. Метод secureFields()
ожидает также массив данных, и ожидается,
что он вернёт массив, содержащий список полей для защиты этого виджета. Если
CakePHP создаёт ваш виджет, вы можете получить экземпляр Cake\View\StringTemplate
в качестве первого аргумента, за которым следуют любые зависимости, которые вы
определяете. Если вы захотите создать виджет Autocomplete
, вы можете сделать следующее:
namespace App\View\Widget;
use Cake\View\Form\ContextInterface;
use Cake\View\Widget\WidgetInterface;
class AutocompleteWidget implements WidgetInterface
{
protected $_templates;
public function __construct($templates)
{
$this->_templates = $templates;
}
public function render(array $data, ContextInterface $context)
{
$data += [
'name' => '',
];
return $this->_templates->format('autocomplete', [
'name' => $data['name'],
'attrs' => $this->_templates->formatAttributes($data, ['name'])
]);
}
public function secureFields(array $data)
{
return [$data['name']];
}
}
Очевидно, что это очень простой пример, но он демонстрирует, как можно создать
пользовательский виджет. Этот виджет будет отображать шаблон строки «autocomplete»,
такой как:
$this->Form->setTemplates([
'autocomplete' => '<input type="autocomplete" name="{{name}}" {{attrs}} />'
]);
Для получения дополнительной информации о строковых шаблонах, смотрите Настройка использования шаблонов FormHelper.
Использование виджетов
Вы можете загружать пользовательские виджеты при загрузке FormHelper или с помощью метода
addWidget()
. При загрузке FormHelper виджеты определяются как настройка:
// В классе View
$this->loadHelper('Form', [
'widgets' => [
'autocomplete' => ['Autocomplete']
]
]);
Если ваш виджет требует других виджетов, вы можете использовать FormHelper
для заполнения этих зависимостей, объявив их:
$this->loadHelper('Form', [
'widgets' => [
'autocomplete' => [
'App\View\Widget\AutocompleteWidget',
'text',
'label'
]
]
]);
В приведенном выше примере виджет autocomplete
будет зависеть от виджетов text
и label
. Если вашему виджету нужен доступ к представлению, вы должны использовать
„widget“ _view
. Когда будет создан виджет autocomplete
, ему будут переданы
объекты виджетов, которые связаны с именами text
и label
. Чтобы добавить
виджеты с помощью addWidget()
, метод будет выглядеть так:
// Использование имени класса.
$this->Form->addWidget(
'autocomplete',
['Autocomplete', 'text', 'label']
);
// Использование экземпляра - требует разрешения зависимостей.
$autocomplete = new AutocompleteWidget(
$this->Form->getTemplater(),
$this->Form->widgetRegistry()->get('text'),
$this->Form->widgetRegistry()->get('label'),
);
$this->Form->addWidget('autocomplete', $autocomplete);
После добавления/замены виджеты могут использоваться в качестве „type“ (типа) контроля:
echo $this->Form->control('search', ['type' => 'autocomplete']);
Это создаст пользовательский виджет с label
и обёрткой div
так же, как всегда
делает controls()
. Кроме того, вы можете создать виджет управления, используя даже только магический метод:
echo $this->Form->autocomplete('search', $options);
Работа с SecurityComponent
Cake\Controller\Component\SecurityComponent
предлагает несколько функций,
которые делают ваши формы более защищёнными и безопасными. Просто включив в свой контроллер
SecurityComponent
, вы автоматически воспользуетесь функциями защиты от
несанкционированного доступа.
Как упоминалось ранее, при использовании SecurityComponent, вы всегда должны закрывать
свои формы, используя View\Helper\FormHelper::end()
. Это обеспечит
создание специальных _Token
инпутов.
-
Cake\View\Helper\FormHelper::
unlockField
($name)
Разблокирует поле, освобождая его от хэширования SecurityComponent
.
Это также позволяет манипулировать полями с помощью JavaScript. Параметр $name
должен быть именем свойства объекта для поля:
$this->Form->unlockField('id');
-
Cake\View\Helper\FormHelper::
secure
(array $fields = [], array $secureAttributes = [])
$fields
- Необязательный. Массив, содержащий список полей для использования
при генерации хеша. Если не указано, то будут использоваться $this->fields
.
$secureAttributes
- Необязательный. Массив атрибутов HTML для передачи в
сгенерированные скрытые элементы ввода.
Создаёт скрытое поле input
с хэшем безопасности на основе полей, используемых
в форме или пустой строке, когда защищенные формы не используются. Если установлены $secureAttributes
, то
эти HTML атрибуты будут объединены в скрытые теги ввода, созданные для SecurityComponent.
Это особенно полезно для установки атрибутов HTML5, таких как 'form'
.