| Следующая версия | Предыдущая версия |
| инвентаризация:dev:forms [2025/04/27 14:49] – создано admin | инвентаризация:dev:forms [2025/05/01 18:18] (текущий) – [Placeholders] admin |
|---|
| {{tag>dev Инвентаризация forms}} | {{tag>dev Инвентаризация forms}} |
| ====== Инвентаризация: DEV: Forms ====== | ====== Инвентаризация: DEV: Forms ====== |
| | |
| | ==== ActiveField ==== |
| Поскольку у нас шаблон ввода в форме не стандартный, а | Поскольку у нас шаблон ввода в форме не стандартный, а |
| {Label} с иконкой и {hint} в tooltip, {input}, {error} | {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 |
| |
| Переделываем (наследуем) Activefield следующим образом | В зависимости от настройки |
| По умолчанию в $this->parts хранятся отрендеренные части для шаблона | <code php> |
| Мы в $this->parts['{hint}'] все равно храним Hint, но используем его в шаблоне, а используем при рендере label | 'textFields'=>[ |
| Для этого метод render должен | 'default'=>'text', |
| * сначала вызывать $this->hint(), который заполнит $this->parts['{hint}'] | 'Aces.ips'=>'text', //IP адреса хранить иначе чем текст нет смысла |
| * уже после вызывать $this->label(), который заполнит $this->parts['{label}'] в котором в тултипе будет $this->parts['{hint}'] | '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', |
| | ], |
| | </code> |
| | ==== Modal Popups ==== |
| | Была следующая проблема: если у формы явно не задан ID, то он (т.к. форма наследуется от виджета) формируется как префикс (w) + индекс (0), поэтому по умолчанию у формы ID = w0. |
| | И если на страницу, в которой уже есть форма, через Popup + Ajax подгрузить еще одну форму, то она соответственно тоже будет w0, т.к. она была первой на подгруженной странице. И тут возникает проблема с инициализацией JavaScript, т.к. к форме прилагается скрипт инициализации, и если формы называются одинаково, то возникает коллизия. |
| | ++++ пример скрипта инициализации | |
| | <code 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" |
| | }); |
| | </code> |
| | ++++ |
| | во избежание подобных коллизий мы делаем в init по умолчанию id вида className-id-form |
| | Для этого во всех формах желательно указывать модель через конфиг |
| | ==== Placeholders ==== |
| | Во-первых у ArmsModel есть метод getAttributePlaceholder($attribute), который возвращает плейсхолдер для поля ввода атрибута. |
| | Если атрибут отмечен как is_inheritable, то возвращает унаследованное значение (либо указанное в inheritablePlaceholder параметре атрибута (может быть и функцией)) |
| | Во вторых в [[#ActiveField]] все методы для вывода инпутов переопределены для подгрузки плейсхолдеров |
| | В третьих в форме по умолчанию включена Ajax валидация, которая в ArmsBaseController тоже переопределена и к данным валидации добавляет значения плейсхолдеров для валидируемого набора значений модели. Зачем? Меняем родителя - меняются унаследованные значения, которые видно в плейсхолдерах |
| | В четвертых, чтобы обрабатывать передаваемые плейсхолдеры к форме прикрепляется обработчик события OnAjaxComplete |
| |
| | ==== Валидация ==== |
| | По умолчанию формы включают ajax валидацию, но чтобы сгенерировать url валидации по умолчанию (который обслуживается через ArmsBaseController) нужно указывать модель в конфигурацию формы |