{{tag>dev Инвентаризация forms}}
====== Инвентаризация: DEV: Forms ======
==== ActiveField ====
Поскольку у нас шаблон ввода в форме не стандартный, а
{Label} с иконкой и {hint} завернутым в tooltip, {input}, {error}
Переделываем (наследуем) Activefield (от \yii\bootstrap5\ActiveField) следующим образом
* методы label и hint не заполняют $this->parts['{label}'] и $this->parts['{hint}'] отрендеренным HTML, а сохраняют текстовую часть в labelText и hintText атрибутах
* в методе render мы уже формируем $this->parts['{label}'] на основании labelText и hintText. $this->parts['{hint}'] остается пустой
* на самом деле в \yii\bootstrap5\ActiveField есть метод renderLabel и делаем всю магию там
* $this->parts['{hint}'] можно заполнить методом classicHint, тогда можно отобразить и классическую подсказку после Input
==== Text ====
Сделал метод для ввода текста ->text($options=[]), который может вызывать
* textAutoresize
* dokuwikiEdit
* mardownEdit
В зависимости от настройки
'textFields'=>[
'default'=>'text',
'Aces.ips'=>'text', //IP адреса хранить иначе чем текст нет смысла
'Aces.notepad'=>'markdown',
'Acls.notepad'=>'markdown',
'Comps.ip'=>'text',
'Comps.mac'=>'text',
'Comps.raw_hw'=>'text',
'Comps.raw_sw'=>'text',
'Comps.external_links'=>'text',
'MaintenanceReqs.description'=>'markdown',
'MaintenanceReqs.links'=>'text',
'LicTypes.links'=>'text',
'Networks.notepad'=>'markdown',
],
==== Modal Popups ====
Была следующая проблема: если у формы явно не задан ID, то он (т.к. форма наследуется от виджета) формируется как префикс (w) + индекс (0), поэтому по умолчанию у формы ID = w0.
И если на страницу, в которой уже есть форма, через Popup + Ajax подгрузить еще одну форму, то она соответственно тоже будет w0, т.к. она была первой на подгруженной странице. И тут возникает проблема с инициализацией JavaScript, т.к. к форме прилагается скрипт инициализации, и если формы называются одинаково, то возникает коллизия.
++++ пример скрипта инициализации |
jQuery('#w0').yiiActiveForm([{
"id": "aces-users_ids",
"name": "users_ids",
"container": ".field-aces-users_ids",
"input": "#aces-users_ids",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}, {
"id": "aces-comps_ids",
"name": "comps_ids",
"container": ".field-aces-comps_ids",
"input": "#aces-comps_ids",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}, {
"id": "aces-services_ids",
"name": "services_ids",
"container": ".field-aces-services_ids",
"input": "#aces-services_ids",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}, {
"id": "aces-ips",
"name": "ips",
"container": ".field-aces-ips",
"input": "#aces-ips",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}, {
"id": "aces-comment",
"name": "comment",
"container": ".field-aces-comment",
"input": "#aces-comment",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}, {
"id": "aces-name",
"name": "name",
"container": ".field-aces-name",
"input": "#aces-name",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}, {
"id": "aces-access_types_ids",
"name": "access_types_ids",
"container": ".field-aces-access_types_ids",
"input": "#aces-access_types_ids",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}, {
"id": "aces-notepad",
"name": "notepad",
"container": ".field-aces-notepad",
"input": "#aces-notepad",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}, {
"id": "aces-acls_id",
"name": "acls_id",
"container": ".field-aces-acls_id",
"input": "#aces-acls_id",
"error": ".invalid-feedback",
"enableAjaxValidation": true
}
], {
"errorSummary": ".alert.alert-danger",
"errorCssClass": "is-invalid",
"successCssClass": "is-valid",
"validationStateOn": "input",
"validationUrl": "\/web\/aces\/validate?id=675"
});
++++
во избежание подобных коллизий мы делаем в init по умолчанию id вида className-id-form
Для этого во всех формах желательно указывать модель через конфиг
==== Placeholders ====
Во-первых у ArmsModel есть метод getAttributePlaceholder($attribute), который возвращает плейсхолдер для поля ввода атрибута.
Если атрибут отмечен как is_inheritable, то возвращает унаследованное значение (либо указанное в inheritablePlaceholder параметре атрибута (может быть и функцией))
Во вторых в [[#ActiveField]] все методы для вывода инпутов переопределены для подгрузки плейсхолдеров
В третьих в форме по умолчанию включена Ajax валидация, которая в ArmsBaseController тоже переопределена и к данным валидации добавляет значения плейсхолдеров для валидируемого набора значений модели. Зачем? Меняем родителя - меняются унаследованные значения, которые видно в плейсхолдерах
В четвертых, чтобы обрабатывать передаваемые плейсхолдеры к форме прикрепляется обработчик события OnAjaxComplete
==== Валидация ====
По умолчанию формы включают ajax валидацию, но чтобы сгенерировать url валидации по умолчанию (который обслуживается через ArmsBaseController) нужно указывать модель в конфигурацию формы