Page Contents

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.

Получение значений формы из строки запроса

Добавлено в версии 3.4.0.

Источники значений FormHelper определяют, откуда его отображаемые элементы, такие как входные теги, получают свои значения.

По умолчанию FormHelper извлекает значения из контекста. Контексты по умолчанию, такие как EntityContext, будут извлекать данные из текущего объекта или из $request->getData().

Однако, если, вы создаёте форму, которая должна читать данные из строки запроса, вы можете использовать valueSource() для изменения того, где FormHelper считывает вводимые данные:

// Строка запроса приоритета по контексту:
echo $this->Form->create($article, [
    'valueSources' => ['query', 'context']
]);

// Тот же эффект:
echo $this->Form
    ->setValueSources(['query', 'context'])
    ->create($articles);

// Чтение данных только из строки запроса:
echo $this->Form->create($article);
$this->Form->setValueSources('query');

// Тот же эффект:
echo $this->Form->create($article, ['valueSources' => 'query']);

Поддерживаемые источники - context, data и query. Вы можете использовать один или несколько источников. Любые виджеты, сгенерированные FormHelper, собирают свои значения из источников в том порядке, в котором вы это настроили.

Источники значений будут сброшены до значения по умолчанию (['context']), когда вызывается end().

Изменение метода 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'));

Примечание

Вы не должны использовать FormHelper::control() для создания кнопок отправки. Используйте вместо этого: View\Helper\FormHelper::submit().

Соглашения об именах полей

При создании виджетов 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.

Создание элементов input

Остальные методы, доступные в FormHelper, предназначены для создания определенных элементов формы. Многие из этих методов также используют специальный параметр $options или $attributes. Однако, в этом случае, этот параметр используется в основном для указания атрибутов HTML-тегов (таких как значение или DOM-идентификатор элемента в форме).

Создание текстовых инпутов

Cake\View\Helper\FormHelper::text(string $name, array $options)

Создаёт простой HTML элемент input, text (текстового) типа.

Например:

echo $this->Form->text('username', ['class' => 'users']);

Вывод:

<input name="username" type="text" class="users">

Создание input типа password

Cake\View\Helper\FormHelper::password(string $fieldName, array $options)

Создаёт простой HTML элемент input, типа password.

Например:

echo $this->Form->password('password');

Вывод:

<input name="password" value="" type="password">

Создание скрытого input

Cake\View\Helper\FormHelper::hidden(string $fieldName, array $options)

Создаёт скрытый input для формы.

Например:

echo $this->Form->hidden('id');

Вывод:

<input name="id" type="hidden" />

Создание текстовых полей

Cake\View\Helper\FormHelper::textarea(string $fieldName, array $options)

Создаёт поле управления textarea. Используемый шаблон виджета по умолчанию:

'textarea' => '<textarea name="{{name}}"{{attrs}}>{{value}}</textarea>'

Для примера:

echo $this->Form->textarea('notes');

Вывод:

<textarea name="notes"></textarea>

Если форма редактируется (т.е. массив $this->request->getData() содержит информацию, ранее сохранённую для объекта User), значение, соответствующее полю notes, будет автоматически добавляться в сгенерированный HTML-код.

Пример:

<textarea name="notes" id="notes">
    Этот текст подлежит редактированию.
</textarea>

Опции для textarea

В дополнение к Общие параметры для специализированных элементов управления, textarea() поддерживает несколько специфичных опций:

  • 'escape' - Определяет, следует ли экранировать содержимое текстового поля. По умолчанию используется true.

    Например:

    echo $this->Form->textarea('notes', ['escape' => false]);
    // OR....
    echo $this->Form->control('notes', ['type' => 'textarea', 'escape' => false]);
    
  • 'rows', 'cols' - Вы можете использовать эти два ключа для установки атрибутов HTML, которые определяют количество строк и столбцов для поля textarea.

    Например:

    echo $this->Form->textarea('comment', ['rows' => '5', 'cols' => '5']);
    

    Вывод:

    <textarea name="comment" cols="5" rows="5">
    </textarea>
    

Создание элементов select, checkbox и radio

Эти элементы управления разделяют некоторые общие черты и несколько вариантов, и поэтому все они сгруппированы в этом подразделе для упрощения ссылок.

Опции элементов select, checkbox и radio

Ниже вы можете найти опции, которые являются одинаковыми для методов select(), checkbox() и radio() (параметры же, относящиеся только к одному из методов, описаны в отдельном разделе каждого метода).

  • 'value' - Устанавливает или выбирает значение затронутого элемента(ов):

    • Для чекбоксов, он устанавливает HTML атрибут 'value', назначенный элементу input, независимо от того, что вы предоставляете в качестве значения.

    • Для переключателей(radio) или select он определяет, какой элемент будет выбран при визуализации формы (в этом случае 'value' должно быть присвоено действительное значение существующего элемента). Может также использоваться в сочетании с любым типом управления select-type, таким как date(), time(), dateTime():

      echo $this->Form->time('close_time', [
          'value' => '13:30:00'
      ]);
      

    Примечание

    Ключ 'value' для элементов date() и dateTime() может также иметь значение как временной метки UNIX или объекта DateTime.

    Для элемента select, где вы устанавливаете атрибут 'multiple' в true, вы можете предоставить массив со значениями, которые вы хотите выбрать по умолчанию:

    // Элементы HTML <option> со значениями 1 и 3 будут отображаться предварительно выбранными
    echo $this->Form->select(
        'rooms',
        [1, 2, 3, 4, 5],
        [
            'multiple' => true,
            'value' => [1, 3]
        ]
    );
    
  • 'empty' - Используется для radio() и select(). По умолчанию используется false.

    • Когда он передаётся в radio() и устанавливается в true, он создаёт дополнительный входной элемент в качестве первого переключателя со значением '' и надпись метки, равную строке 'empty'. Если вы хотите управлять надписью ярлыка, установите этот параметр вместо строки.

    • Когда он передаётся методу select(), это создаёт пустой HTML элемент option с пустым значением в раскрывающемся списке. Если вы хотите иметь пустое значение с отображаемым текстом, а не просто пустым option, передайте строку 'empty':

      echo $this->Form->select(
          'field',
          [1, 2, 3, 4, 5],
          ['empty' => '(choose one)']
      );
      

      Вывод:

      <select name="field">
          <option value="">(choose one)</option>
          <option value="0">1</option>
          <option value="1">2</option>
          <option value="2">3</option>
          <option value="3">4</option>
          <option value="4">5</option>
      </select>
      
  • 'hiddenField' - Для флажков и переключателей по умолчанию также создаётся скрытый элемент input вместе с основным элементом, так что ключ в $this->request->getData() будет существовать даже без указанния его значения. Для флажков(radio) его значение по умолчанию равно 0, а для переключателей(select) - ''.

    Пример вывода по умолчанию:

    <input type="hidden" name="published" value="0" />
    <input type="checkbox" name="published" value="1" />
    

    Это можно отключить, установив 'hiddenField' в false:

    echo $this->Form->checkbox('published', ['hiddenField' => false]);
    

    Результат:

    <input type="checkbox" name="published" value="1">
    

    Если вы хотите создать несколько блоков элементов управления в форме, которые сгруппированы вместе, вы должны установить этот параметр в false для всех элементов управления, кроме первого. Если скрытый ввод находится на странице в нескольких местах, будет сохранена только последняя группа значений input.

    В этом примере будут пропускаться только третичные цвета, а основные цвета будут переопределены:

    <h2>Primary Colors</h2>
    <input type="hidden" name="color" value="0" />
    <label for="color-red">
        <input type="checkbox" name="color[]" value="5" id="color-red" />
        Red
    </label>
    
    <label for="color-blue">
        <input type="checkbox" name="color[]" value="5" id="color-blue" />
        Blue
    </label>
    
    <label for="color-yellow">
        <input type="checkbox" name="color[]" value="5" id="color-yellow" />
        Yellow
    </label>
    
    <h2>Tertiary Colors</h2>
    <input type="hidden" name="color" value="0" />
    <label for="color-green">
        <input type="checkbox" name="color[]" value="5" id="color-green" />
        Green
    </label>
    <label for="color-purple">
        <input type="checkbox" name="color[]" value="5" id="color-purple" />
        Purple
    </label>
    <label for="color-orange">
        <input type="checkbox" name="color[]" value="5" id="color-orange" />
        Orange
    </label>
    

    Отключение 'hiddenField' во второй контрольной группе предотвратит это поведение.

    Вы можете установить значение для скрытого поля, отличное от 0, например в „N“:

    echo $this->Form->checkbox('published', [
        'value' => 'Y',
        'hiddenField' => 'N',
    ]);
    

Создание переключателей (чекбоксов)

Cake\View\Helper\FormHelper::checkbox(string $fieldName, array $options)

Создаёт элемент checkbox формы . Используемый шаблон виджета:

'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>'

Опции для переключателей

  • 'checked' - Boolean, чтобы указать, будет ли этот флажок установлен. По умолчанию используется false.
  • 'disabled' - Создать отключенный флажок.

Этот метод также генерирует связанный скрытый элемент input для принудительного представления данных для указанного поля.

Например:

echo $this->Form->checkbox('done');

Вывод:

<input type="hidden" name="done" value="0">
<input type="checkbox" name="done" value="1">

Можно указать значение флажка, используя массив $options.

Например:

echo $this->Form->checkbox('done', ['value' => 555]);

Вывод:

<input type="hidden" name="done" value="0">
<input type="checkbox" name="done" value="555">

Если вы не хотите, чтобы FormHelper создавал скрытый input, используйте „false“ для 'hiddenField'.

Например:

echo $this->Form->checkbox('done', ['hiddenField' => false]);

Вывод:

<input type="checkbox" name="done" value="1">

Создание radio кнопок

Cake\View\Helper\FormHelper::radio(string $fieldName, array $options, array $attributes)
  • $fieldName - Имя поля в форме 'Modelname.fieldname'.
  • $options - Необязательный массив, содержащий как минимум метки для переключателей. Может также содержать значения и атрибуты HTML. Когда этот массив отсутствует, метод будет генерировать только скрытый input (если 'hiddenField' в true) или вообще не элемент (если 'hiddenField' в false).
  • $attributes - Необязательный массив, включающий любой из Общие параметры для специализированных элементов управления, или Опции элементов select, checkbox и radio, определенных атрибутов переключателя (см. ниже), а также любых допустимых атрибутов HTML.

Создаёт набор инпутов для радиокнопки. Используемые шаблоны виджетов:

'radio' => '<input type="radio" name="{{name}}" value="{{value}}"{{attrs}}>'
'radioWrapper' => '{{label}}'

Аттрибуты для радиокнопок

  • 'label' - Boolean, чтобы указать, должны ли отображаться метки для виджетов. По умолчанию true.
  • 'hiddenField' - Если установлено значение true, то будет включён скрытый ввод со значением ''. Это полезно для создания наборов радиокнопок, которые не являются непрерывными (бесконечными). По умолчанию true.
  • 'disabled' - Установите true или 'disabled', чтобы отключить все переключатели. По умолчанию используется false.

Вы должны предоставить подписи ярлыков(label) для переключателей с помощью аргумента $options.

Для примера:

$this->Form->radio('gender', ['Masculine','Feminine','Neuter']);

Вывод:

<input name="gender" value="" type="hidden">
<label for="gender-0">
    <input name="gender" value="0" id="gender-0" type="radio">
    Masculine
</label>
<label for="gender-1">
    <input name="gender" value="1" id="gender-1" type="radio">
    Feminine
</label>
<label for="gender-2">
    <input name="gender" value="2" id="gender-2" type="radio">
    Neuter
</label>

Обычно $options содержит простые пары key => value. Однако, если вам нужно поместить пользовательские атрибуты на свои переключатели, вы можете использовать расширенный формат.

Например:

echo $this->Form->radio(
    'favorite_color',
    [
        ['value' => 'r', 'text' => 'Red', 'style' => 'color:red;'],
        ['value' => 'u', 'text' => 'Blue', 'style' => 'color:blue;'],
        ['value' => 'g', 'text' => 'Green', 'style' => 'color:green;'],
    ]
);

Вывод:

<input type="hidden" name="favorite_color" value="">
<label for="favorite-color-r">
    <input type="radio" name="favorite_color" value="r" style="color:red;" id="favorite-color-r">
    Red
</label>
<label for="favorite-color-u">
    <input type="radio" name="favorite_color" value="u" style="color:blue;" id="favorite-color-u">
    Blue
</label>
<label for="favorite-color-g">
    <input type="radio" name="favorite_color" value="g" style="color:green;" id="favorite-color-g">
    Green
</label>

Создание селектов (выборщиков)

Cake\View\Helper\FormHelper::select(string $fieldName, array $options, array $attributes)
  • $fieldName - Имя поля в форме 'Modelname.fieldname'. Это даст атрибут name элемента select.
  • $options - Необязательный массив, содержащий список элементов для select. Когда этот массив отсутствует, метод будет генерировать только пустой HTML элемент select без каких-либо опционных элементов внутри него.
  • $attributes - Необязательный массив, включающий любой из Общие параметры для специализированных элементов управления, или Опции элементов select, checkbox и radio, определенных атрибутов переключателя (см. ниже), а также любых допустимых атрибутов HTML.

Создаёт элемент select, заполненный элементами из массива $options. Если задано $attributes['value'], то HTML элемент(ы) option, которые имеют указанное значение(я), будут отображаться как выбранные.

По умолчанию select использует следующие шаблоны виджета:

'select' => '<select name="{{name}}"{{attrs}}>{{content}}</select>'
'option' => '<option value="{{value}}"{{attrs}}>{{text}}</option>'

Может также использовать:

'optgroup' => '<optgroup label="{{label}}"{{attrs}}>{{content}}</optgroup>'
'selectMultiple' => '<select name="{{name}}[]" multiple="multiple"{{attrs}}>{{content}}</select>'

Аттрибуты для select

  • 'multiple' - Если установлено значение true, вы можете выбрать несколько вариантов select. Если установлен флажок 'checkbox', вместо этого будут созданы несколько чекбоксов. По умолчанию используется значение null.
  • 'escape' - Boolean. Если true, содержимое элементов option внутри select будет кодироваться в HTML-объекте. По умолчанию используется true.
  • 'val' - Позволяет предварительно выбрать значение в элементе select.
  • 'disabled' - Управляет атрибутом disabled. Если установлено значение true, отключается весь select. Если он установлен в массив, он отключит только те конкретные элементы option, значения которых указаны в массиве.

Аргумент $options позволяет вам вручную указывать содержимое элементов option элемента select.

Например:

echo $this->Form->select('field', [1, 2, 3, 4, 5]);

Вывод:

<select name="field">
    <option value="0">1</option>
    <option value="1">2</option>
    <option value="2">3</option>
    <option value="3">4</option>
    <option value="4">5</option>
</select>

Массив для $options также может быть представлен как пары ключ-значение.

Например:

echo $this->Form->select('field', [
    'Value 1' => 'Label 1',
    'Value 2' => 'Label 2',
    'Value 3' => 'Label 3'
]);

Вывод:

<select name="field">
    <option value="Value 1">Label 1</option>
    <option value="Value 2">Label 2</option>
    <option value="Value 3">Label 3</option>
</select>

Если вы хотите сгенерировать select с группами опций, просто передайте данные в иерархическом формате (вложенный массив). Это работает также с несколькими флажками и переключателями, но вместо optgroup он обёртывает элементы в элементах fieldset.

For example:

$options = [
    'Group 1' => [
        'Value 1' => 'Label 1',
        'Value 2' => 'Label 2'
    ],
    'Group 2' => [
        'Value 3' => 'Label 3'
    ]
];
echo $this->Form->select('field', $options);

Вывод:

<select name="field">
    <optgroup label="Group 1">
        <option value="Value 1">Label 1</option>
        <option value="Value 2">Label 2</option>
    </optgroup>
    <optgroup label="Group 2">
        <option value="Value 3">Label 3</option>
    </optgroup>
</select>

Чтобы генерировать HTML-атрибуты в теге option:

$options = [
    ['text' => 'Description 1', 'value' => 'value 1', 'attr_name' => 'attr_value 1'],
    ['text' => 'Description 2', 'value' => 'value 2', 'attr_name' => 'attr_value 2'],
    ['text' => 'Description 3', 'value' => 'value 3', 'other_attr_name' => 'other_attr_value'],
];
echo $this->Form->select('field', $options);

Вывод:

<select name="field">
    <option value="value 1" attr_name="attr_value 1">Description 1</option>
    <option value="value 2" attr_name="attr_value 2">Description 2</option>
    <option value="value 3" other_attr_name="other_attr_value">Description 3</option>
</select>

Управление селектами с помощью атрибутов

Используя определенные параметры в параметре $attributes, вы можете управлять определенным поведением метода select().

  • 'empty' - Установите ключ 'empty' в аргументе $attributes в true (значение по умолчанию false), чтобы добавить пустой параметр с пустым значением в верхней части вашего выпадающего списка.

    Например:

    $options = ['M' => 'Male', 'F' => 'Female'];
    echo $this->Form->select('gender', $options, ['empty' => true]);
    

    Вывод:

    <select name="gender">
        <option value=""></option>
        <option value="M">Male</option>
        <option value="F">Female</option>
    </select>
    
  • 'escape' - Метод select() позволяет использовать атрибут 'escape', который принимает логическое значение и определяет, кодирует ли объект select HTML содержимое элементов option.

    Например:

    // Это предотвратит HTML-кодирование содержимого опции каждого элемента
    $options = ['M' => 'Male', 'F' => 'Female'];
    echo $this->Form->select('gender', $options, ['escape' => false]);
    
  • 'multiple' - Если установлено значение true, select позволит выбрать несколько вариантов.

    Например:

    echo $this->Form->select('field', $options, ['multiple' => true]);
    

    Кроме того, установите 'multiple' в 'checkbox', чтобы вывести список связанных чекбоксов(флажков):

    $options = [
        'Value 1' => 'Label 1',
        'Value 2' => 'Label 2'
    ];
    echo $this->Form->select('field', $options, [
        'multiple' => 'checkbox'
    ]);
    

    Вывод:

    <input name="field" value="" type="hidden">
    <div class="checkbox">
        <label for="field-1">
            <input name="field[]" value="Value 1" id="field-1" type="checkbox">
            Label 1
        </label>
    </div>
    <div class="checkbox">
        <label for="field-2">
            <input name="field[]" value="Value 2" id="field-2" type="checkbox">
            Label 2
        </label>
    </div>
    
  • 'disabled' - Эта опция может быть установлена для того, чтобы отключить все или некоторые элементы option в select . Чтобы отключить все элементы, установите 'disabled' в true. Чтобы отключить только определенные элементы, назначьте 'disabled' массив, содержащий ключи элементов, которые необходимо отключить.

    Например:

    $options = [
        'M' => 'Masculine',
        'F' => 'Feminine',
        'N' => 'Neuter'
    ];
    echo $this->Form->select('gender', $options, [
        'disabled' => ['M', 'N']
    ]);
    

    Вывод:

    <select name="gender">
        <option value="M" disabled="disabled">Masculine</option>
        <option value="F">Feminine</option>
        <option value="N" disabled="disabled">Neuter</option>
    </select>
    

    Эта опция также работает, когда 'multiple' установлен в 'checkbox':

    $options = [
        'Value 1' => 'Label 1',
        'Value 2' => 'Label 2'
    ];
    echo $this->Form->select('field', $options, [
        'multiple' => 'checkbox',
        'disabled' => ['Value 1']
    ]);
    

    Вывод:

    <input name="field" value="" type="hidden">
    <div class="checkbox">
        <label for="field-1">
            <input name="field[]" disabled="disabled" value="Value 1" type="checkbox">
            Label 1
        </label>
    </div>
    <div class="checkbox">
        <label for="field-2">
            <input name="field[]" value="Value 2" id="field-2" type="checkbox">
            Label 2
        </label>
    </div>
    

Создание input для файла

Cake\View\Helper\FormHelper::file(string $fieldName, array $options)

Создаёт, в форме, поле для загрузки файла. Шаблон виджета, используемый по умолчанию:

'file' => '<input type="file" name="{{name}}"{{attrs}}>'

Чтобы добавить поле загрузки файла в форму, вы должны сначала убедиться, что в enctype формы установлено значение 'multipart/form-data'.

Поэтому начните с метода create(), например, так:

echo $this->Form->create($document, ['enctype' => 'multipart/form-data']);
// Или
echo $this->Form->create($document, ['type' => 'file']);

Затем добавьте строку, которая выглядит как одна из двух следующих строк в файле шаблона вида формы:

echo $this->Form->control('submittedfile', [
    'type' => 'file'
]);

// Или
echo $this->Form->file('submittedfile');

Примечание

Из-за ограничений самого HTML, невозможно поместить значения по умолчанию в поля ввода типа „file“. Каждый раз, когда отображается форма, значение внутри будет пустым.

После представления поля файла, предоставляют расширенный массив данных для скрипта, получающего данные формы.

Для приведённого выше примера, значения в представленном массиве данных будут организованы следующим образом, если CakePHP был установлен на сервере Windows (ключ 'tmp_name' будет содержать другой путь в среде Unix):

$this->request->data['submittedfile']

// будет содержать следующий массив:
[
    'name' => 'conference_schedule.pdf',
    'type' => 'application/pdf',
    'tmp_name' => 'C:/WINDOWS/TEMP/php1EE.tmp',
    'error' => 0, // В Windows это может быть строка.
    'size' => 41737,
];

Этот массив генерируется самим PHP, поэтому для более подробной информации о том, как PHP обрабатывает данные, переданные через поля файла прочитайте раздел руководства PHP по загрузке файлов.

Примечание

При использовании $this->Form->file(), не забудьте установить тип кодировки формы, установив опцию 'type' для 'file' в $this->Form->create().

Создание элементов управления связанных с датой и временем

Методы, связанные с датой и временем, разделяют ряд общих черт и опций и поэтому группируются вместе в этот подраздел.

Общие параметры для элементов управления даты и времени

Эти параметры являются общими для элементов управления, связанных с датой и временем:

  • 'empty' - Если true лишний , пустой, HTML элемент option добавится внутри select в верхнюю часть списка. Если строка, то эта строка отображается как пустой элемент. По умолчанию используется true.
  • 'default' | value - Используйте одно из двух, чтобы установить значение по умолчанию для поля. Значение в $this->request->getData(), соответствующее имени поля, переопределит это значение. Если не задано значение по умолчанию, будет использоваться time().
  • 'year', 'month', 'day', 'hour', 'minute', 'second', 'meridian' - Эти параметры позволяют вам контролировать, какие элементы управления будут сгенерированы, а какие нет. Установив любую из этих опций в false, вы можете отключить генерацию конкретного параметра (если по умолчанию он будет отображаться в используемом методе). Кроме того, каждый параметр позволяет передавать HTML атрибуты к этому конкретному элементу select.

Опции для элементов управления, связанных с датой

Эти варианты относятся к методам, связанным с датой - тоесть year(), month(), day(), dateTime() и date():

  • 'monthNames' - Если false, вместо текста для отображения месяцев в select будут использоваться 2 цифры. Если задано значение массива (например, ['01' => 'Jan', '02' => 'Feb', ...]), будет использоваться данный массив.
  • 'minYear' - Самое низкое значение, которое нужно использовать в выборе года.
  • 'maxYear' - Самое большое значение, которое нужно использовать в выборе года.
  • 'orderYear' - Порядок значений года в select. Возможные значения: 'asc' и 'desc'. По умолчанию используется 'desc'.

Опции для управления временем

Эти варианты касаются методов времени - hour(), minute(), second(), dateTime() и time():

  • 'interval' - Интервал в минутах между значениями, отображаемыми в элементах option. По умолчанию 1.
  • 'round' - Установите значение up или down, если вы хотите заставить округлять минуты в любом направлении, когда значение не соответствует аккуратности в интервале. По умолчанию используется значение null.
  • timeFormat - Используется для dateTime() и time(). Формат времени для использования в элементе select: либо 12, либо 24. Если для этой опции установлено что угодно, кроме 24, формат будет автоматически установлен в 12, а селектор выбора meridian будет отображаться автоматически справа от выбора секунд. По умолчанию - 24.
  • format - Применяется к hour(). Используемый формат времени: либо 12, либо 24. Если он установлен в 12, meridian не будет отображаться автоматически. Вам решать либо добавить его, либо предоставить средства для вывода из контекста формы правильного периода дня. По умолчанию - 24.
  • second - Используется для dateTime() и time(). Установите значение true, чтобы отключить секунды. По умолчанию используется false.

Создание элементов управления DateTime

Cake\View\Helper\FormHelper::dateTime($fieldName, $options = [])

Создаёт набор элементов select для даты и времени.

Чтобы контролировать порядок элементов управления и любые элементы/содержимое между элементами управления, вы можете переопределить шаблон DateWidget. По умолчанию шаблон DateWidget:

{{year}}{{month}}{{day}}{{hour}}{{minute}}{{second}}{{meridian}}

Вызов метода без дополнительных опций приведёт к созданию по умолчанию 5-ти элементов select для: года (4 цифры), месяца (полное английское имя), дня (числа), часа (число), минут (число).

Для примера:

<?= $this->form->dateTime('registered') ?>

Вывод:

<select name="registered[year]">
    <option value="" selected="selected"></option>
    <option value="2022">2022</option>
    ...
    <option value="2012">2012</option>
</select>
<select name="registered[month]">
    <option value="" selected="selected"></option>
    <option value="01">January</option>
    ...
    <option value="12">December</option>
</select>
<select name="registered[day]">
    <option value="" selected="selected"></option>
    <option value="01">1</option>
    ...
    <option value="31">31</option>
</select>
<select name="registered[hour]">
    <option value="" selected="selected"></option>
    <option value="00">0</option>
    ...
    <option value="23">23</option>
</select>
<select name="registered[minute]">
    <option value="" selected="selected"></option>
    <option value="00">00</option>
    ...
    <option value="59">59</option>
</select>

Чтобы создать элементы управления datetime с пользовательскими классами/атрибутами в определённом поле выбора, вы можете предоставить их как массивы параметров для каждого компонента в аргументе $options.

Для примера:

echo $this->Form->dateTime('released', [
    'year' => [
        'class' => 'year-classname',
    ],
    'month' => [
        'class' => 'month-class',
        'data-type' => 'month',
    ],
]);

Что создаст следующие два селекта:

<select name="released[year]" class="year-class">
    <option value="" selected="selected"></option>
    <option value="00">0</option>
    <option value="01">1</option>
    <!-- .. snipped for brevity .. -->
</select>
<select name="released[month]" class="month-class" data-type="month">
    <option value="" selected="selected"></option>
    <option value="01">January</option>
    <!-- .. snipped for brevity .. -->
</select>

Создание элементов управления датой

Cake\View\Helper\FormHelper::date($fieldName, $options = [])

Создаёт по умолчанию три элемента select, заполненных значениями: год (4 цифры), месяц (полное английское имя) и день (число), соответственно.

Вы можете дополнительно управлять сгенерированными элементами select, предоставляя дополнительные параметры.

Для примера:

    // Предполагая, что текущий год - 2017 год; это отключает выбор дня,
    // удаляет пустую опцию для года, выбирает минимальный год, добавляет HTML
    // атрибуты для года, добавляет строку 'empty' вариант для месяца, меняет
    // месяц на числовой
<?php
    echo $this->Form->date('registered', [
        'minYear' => 2018,
        'monthNames' => false,
        'empty' => [
            'year' => false,
            'month' => 'Choose month...'
        ],
        'day' => false,
        'year' => [
            'class' => 'cool-years',
            'title' => 'Registration Year'
        ]
    ]);
?>

Вывод:

<select class= "cool-years" name="registered[year]" title="Registration Year">
    <option value="2022">2022</option>
    <option value="2021">2021</option>
    ...
    <option value="2018">2018</option>
</select>
<select name="registered[month]">
    <option value="" selected="selected">Choose month...</option>
    <option value="01">1</option>
    ...
    <option value="12">12</option>
</select>

Создание элементов управления временем

Cake\View\Helper\FormHelper::time($fieldName, $options = [])

Создаёт по умолчанию два элемента select (hour и minute), заполненные значениями из 24 часов и 60 минут, соответственно. Кроме того, атрибуты HTML могут быть предоставлены в $options для каждого конкретного компонента. Если $options['empty'] в false, select не будет содержать пустую опцию по умолчанию.

Например, чтобы создать временной диапазон с минутами, выбираемыми с шагом в 15 минут, и применить классы к полям выбора, вы можете сделать следующее:

echo $this->Form->time('released', [
    'interval' => 15,
    'hour' => [
        'class' => 'foo-class',
    ],
    'minute' => [
        'class' => 'bar-class',
    ],
]);

Что создаст следующие два элемента выбора:

<select name="released[hour]" class="foo-class">
    <option value="" selected="selected"></option>
    <option value="00">0</option>
    <option value="01">1</option>
    <!-- .. snipped for brevity .. -->
    <option value="22">22</option>
    <option value="23">23</option>
</select>
<select name="released[minute]" class="bar-class">
    <option value="" selected="selected"></option>
    <option value="00">00</option>
    <option value="15">15</option>
    <option value="30">30</option>
    <option value="45">45</option>
</select>

Создание элементов управления годом

Cake\View\Helper\FormHelper::year(string $fieldName, array $options = [])

Создаёт элемент select, заполненный годами от minYear до maxYear (если эти параметры предоставлены), а также значения от -5 лет до +5 лет, отсчитываемые от сегодняшнего дня. Кроме того, атрибуты HTML могут быть предоставлены в $options. Если $options['empty'] в false, то элемент select не будет содержать пустой элемент в списке.

Например, чтобы создать диапазон лет от 2000 до текущего года, вы должны сделать следующее:

echo $this->Form->year('purchased', [
    'minYear' => 2000,
    'maxYear' => date('Y')
]);

If it was 2009, you would get the following:

<select name="purchased[year]">
    <option value=""></option>
    <option value="2009">2009</option>
    <option value="2008">2008</option>
    <option value="2007">2007</option>
    <option value="2006">2006</option>
    <option value="2005">2005</option>
    <option value="2004">2004</option>
    <option value="2003">2003</option>
    <option value="2002">2002</option>
    <option value="2001">2001</option>
    <option value="2000">2000</option>
</select>

Создание элементов управления месяцем

Cake\View\Helper\FormHelper::month(string $fieldName, array $attributes)

Создает элемент select, заполненный именами месяцев.

Для примера:

echo $this->Form->month('mob');

Вывод:

<select name="mob[month]">
    <option value=""></option>
    <option value="01">January</option>
    <option value="02">February</option>
    <option value="03">March</option>
    <option value="04">April</option>
    <option value="05">May</option>
    <option value="06">June</option>
    <option value="07">July</option>
    <option value="08">August</option>
    <option value="09">September</option>
    <option value="10">October</option>
    <option value="11">November</option>
    <option value="12">December</option>
</select>

Вы можете задать свой собственный массив месяцев, который будет использоваться, установив атрибут 'monthNames' или отобразить месяцы числами, передав false.

Например:

echo $this->Form->month('mob', ['monthNames' => false]);

Примечание

Месяцы по умолчанию могут быть локализованы с помощью функций CakePHP Internationalization & Localization.

Создание элементов управления днями

Cake\View\Helper\FormHelper::day(string $fieldName, array $attributes)

Создаёт элемент select, заполненный (числовыми) днями месяца.

Чтобы создать пустой элемент option с пригласительным текстом по вашему выбору (например, первый вариант - „День“), вы можете предоставить текст в параметре 'empty'.

Для примера:

echo $this->Form->day('created', ['empty' => 'День']);

Вывод:

<select name="created[day]">
    <option value="" selected="selected">День</option>
    <option value="01">1</option>
    <option value="02">2</option>
    <option value="03">3</option>
    ...
    <option value="31">31</option>
</select>

Создание элементов управления часами

Cake\View\Helper\FormHelper::hour(string $fieldName, array $attributes)

Создает элемент select, заполненный дневными часами.

Вы можете создать 12 или 24-часовой элемент select, используя опцию 'format':

echo $this->Form->hour('created', [
    'format' => 12
]);
echo $this->Form->hour('created', [
    'format' => 24
]);

Создание минутных элементов управления

Cake\View\Helper\FormHelper::minute(string $fieldName, array $attributes)

Создает элемент select, заполненный значениями минут для часа. Вы можете создать элемент select, который содержит только определенные значения, используя опцию 'interval'.

Например, если вы хотите 10-минутные приращения, вы бы сделали следующее:

// В вашем файле шаблона Вида
echo $this->Form->minute('arrival', [
    'interval' => 10
]);

Это приведет к выводу:

<select name="arrival[minute]">
    <option value="" selected="selected"></option>
    <option value="00">00</option>
    <option value="10">10</option>
    <option value="20">20</option>
    <option value="30">30</option>
    <option value="40">40</option>
    <option value="50">50</option>
</select>

Создание элементов управления Meridian

Cake\View\Helper\FormHelper::meridian(string $fieldName, array $attributes)

Создаёт элемент select, заполненный „am“ и „pm“. Это полезно, когда в часовом формате установлено значение 12 вместо 24, так как это позволяет указать период дня, к которому относится час.

Создание ярлыков

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)
  • $fieldName - Имя поля в форме 'Modelname.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'] - Вы можете установить это для одного из следующих трёх возможных значений:
    1. 'submit' - Подобно методу $this->Form->submit() он создаст кнопку отправки. Однако это не создаст обёртку div, как в submit(). Это тип по умолчанию.
    2. 'reset' - Создаёт кнопку сброса формы.
    3. '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 = [])
  • $secureAttributes - Необязательный. Позволяет предоставлять защищенные атрибуты, которые будут передаваться как атрибуты HTML в скрытые элементы ввода, созданные для SecurityComponent.

Метод 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-ссылок

  • $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

Настройка использования шаблонов FormHelper

Как и многие помощники(хелперы) в CakePHP, FormHelper использует строковые шаблоны для форматирования создаваемого HTML. Хотя шаблоны по умолчанию предназначены для разумного набора значений по умолчанию, вам может потребоваться настроить шаблоны в соответствии с вашим приложением.

Чтобы изменить шаблоны при загрузке хелпера, вы можете установить опцию 'templates', когда включаете помощника в ваш контроллер:

// В классе View
$this->loadHelper('Form', [
    'templates' => 'app_form',
]);

Это загрузило бы теги, найденные в config/app_form.php. Этот файл должен содержать массив шаблонов индексированный по имени:

// в config/app_form.php
return [
    'inputContainer' => '<div class="form-control">{{content}}</div>',
];

Любые шаблоны, которые вы определяете, заменяют стандартные, включенные в помощник. Шаблоны, которые не заменяются, будут продолжать использовать значения по умолчанию.

Вы также можете изменить шаблоны во время выполнения с помощью метода setTemplates():

$myTemplates = [
    'inputContainer' => '<div class="form-control">{{content}}</div>',
];
$this->Form->setTemplates($myTemplates);
// До 3.4
$this->Form->templates($myTemplates);

Предупреждение

Строки шаблонов, содержащие знак процента (%), требуют особого внимания; вы должны приписать этому символу еще один процент, чтобы он выглядел как %%. Причина в том, что внутренние шаблоны скомпилированы для использования с sprintf(). Пример: '<div style="width:{{size}}%%">{{content}}</div>'

Список шаблонов

Список шаблонов по умолчанию, их формат по умолчанию и ожидаемые переменные можно найти в FormHelper API documentation.

Использование специальных контейнеров для пользовательского контроля

В дополнение к этим шаблонам метод control() будет пытаться использовать отдельные шаблоны для каждого контейнера управления. Например, при создании элемента управления datetime используется datetimeContainer, если он присутствует. Если этот контейнер отсутствует, будет использоваться шаблон inputContainer.

Для примера:

// Add custom radio wrapping HTML
$this->Form->setTemplates([
    'radioContainer' => '<div class="form-radio">{{content}}</div>'
]);

// Create a radio set with our custom wrapping div.
echo $this->Form->control('User.email_notifications', [
    'options' => ['y', 'n'],
    'type' => 'radio'
]);

Использование отдельных групп настраиваемых форм

Подобно управлению контейнерами, метод control() также пытается использовать отдельные шаблоны для каждой группы форм. Группа форм представляет собой комбинацию меток и элементов управления. Например, при создании radio control будет использоваться radioFormGroup, если он присутствует. Если этот шаблон отсутствует по умолчанию, каждый набор label и input отображается с использованием шаблона formGroup по умолчанию.

Для примера:

// Add custom radio form group
$this->Form->setTemplates([
    'radioFormGroup' => '<div class="radio">{{label}}{{input}}</div>'
]);

Добавление дополнительных шаблонных переменных в шаблоны

Вы можете добавить дополнительные шаблонные заполнители в пользовательские шаблоны и заполнить эти заполнители при создании элементов управления.

Например:

// Добавьте шаблон с помощью заполнителя.
$this->Form->setTemplates([
    'inputContainer' => '<div class="input {{type}}{{required}}">
        {{content}} <span class="help">{{help}}</span></div>'
]);

// Создайте ввод и заполните переменную справки
echo $this->Form->control('password', [
    'templateVars' => ['help' => 'At least 8 characters long.']
]);

Вывод:

<div class="input password">
    <label for="password">
        Password
    </label>
    <input name="password" id="password" type="password">
    <span class="help">At least 8 characters long.</span>
</div>

Добавлено в версии 3.1: Опция templateVars была добавлена в 3.1.0

Перемещение флажков и радио за пределами метки

По умолчанию CakePHP устанавливает флажки, созданные с помощью control(), и переключатели, созданные как control() и radio() внутри элементов метки. Это помогает упростить интеграцию популярных CSS-фреймворков. Если вам нужно поместить флажки/радиокнопки вне метки, вы можете сделать это, изменив шаблоны:

$this->Form->setTemplates([
    'nestingLabel' => '{{hidden}}{{input}}<label{{attrs}}>{{text}}</label>',
    'formGroup' => '{{input}}{{label}}',
]);

Это заставит переключатели и флажки отображаться вне их меток.

Создание цельных форм

Создание нескольких элементов управления

Cake\View\Helper\FormHelper::controls(array $fields = [], $options = [])
  • $fields - Массив полей для генерации. Позволяет настраивать настраиваемые типы, метки и другие параметры для каждого указанного поля.
  • $options - Необязательный. Множество опций. Допустимые ключи:
    1. 'fieldset' - Установите для этого параметра значение false, чтобы отключить набор полей. Если пуст, набор полей будет включен. Также может быть массив параметров, которые будут применяться как HTML атрибуты к тегу fieldset.
    2. 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 - Необязательный. Множество опций. Допустимые ключи:
    1. 'fieldset' - Установите для этого параметра значение false, чтобы отключить набор полей. Если пуст, набор полей будет включен. Также может быть массив параметров, которые будут применяться в качестве атрибутов HTML для тега fieldset.
    2. legend - Строка используется для настройки текста legend. Установите её в false, чтобы отключить легенду для сгенерированного набора управления.

Этот метод тесно связан с controls(), однако аргумент $fields по умолчанию имеет все поля в текущем объекте верхнего уровня. Чтобы исключить определенные поля из созданных элементов управления, установите их в false в параметре $fields:

echo $this->Form->allControls(['password' => false]);
// Или до 3.4.0:
echo $this->Form->allInputs(['password' => false]);

Создание инпутов для связанных данных

Создание форм для связанных данных является простым и тесно связано с путями в данных вашего объекта. Предполагая следующие табличные соотношения:

  • Authors HasOne Profiles
  • Authors HasMany Articles
  • Articles HasMany Comments
  • Articles BelongsTo Authors
  • Articles BelongsToMany Tags

Если бы мы редактировали статью с загруженными ассоциациями, мы могли бы создать следующие элементы управления:

$this->Form->create($article);

// Article controls.
echo $this->Form->control('title');

// Author controls (belongsTo)
echo $this->Form->control('author.id');
echo $this->Form->control('author.first_name');
echo $this->Form->control('author.last_name');

// Author profile (belongsTo + hasOne)
echo $this->Form->control('author.profile.id');
echo $this->Form->control('author.profile.username');

// Tags controls (belongsToMany)
echo $this->Form->control('tags.0.id');
echo $this->Form->control('tags.0.name');
echo $this->Form->control('tags.1.id');
echo $this->Form->control('tags.1.name');

// Multiple select element for belongsToMany
echo $this->Form->control('tags._ids', [
    'type' => 'select',
    'multiple' => true,
    'options' => $tagList,
]);

// Inputs for the joint table (articles_tags)
echo $this->Form->control('tags.0._joinData.starred');
echo $this->Form->control('tags.1._joinData.starred');

// Comments controls (hasMany)
echo $this->Form->control('comments.0.id');
echo $this->Form->control('comments.0.comment');
echo $this->Form->control('comments.1.id');
echo $this->Form->control('comments.1.comment');

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

$article = $this->Articles->patchEntity($article, $this->request->getData(), [
    'associated' => [
        'Authors',
        'Authors.Profiles',
        'Tags',
        'Comments'
    ]
]);

Добавление пользовательских виджетов

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)
  • $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'.