# JS/CSS-вставки в карточке задачи

В мобильном приложении JS-вставка отображается в карточке задачи как отдельная вкладка с веб-виджетом: блок HTML-содержимого, которое приходит с заданного в настройке эндпоинта и показывается во встроенном веб-вью.

Настройка выполняется в **настройках категории, раздел «Настройки JS и CSS вставок»**.

> Это **не** событийная кастомизация формы задачи средствами JS/CSS веб-клиента. Тот механизм относится к веб-клиенту и в мобильном приложении не применяется — см. [Форма задачи → JS-вставки (первоисточник)](https://help.1forma.ru/domains/task-forms/admin.md).

## Отличия от похожих механизмов

| Похожий механизм | Чем отличается |
|---|---|
| `dashboardCustomURL` | webView-**плитка на дашборде**, отображающая внешний URL во фрейме (`previewURL`). Это не вкладка в карточке задачи. |
| Виджеты домашнего экрана ОС | Нативные home-screen виджеты операционной системы, к карточке задачи отношения не имеют. |
| Событийные веб JS/CSS-вставки | Событийная кастомизация формы задачи средствами JS/CSS — механизм **веб-клиента**. В мобильном приложении не применяется. [Первоисточник](https://help.1forma.ru/domains/task-forms/admin.md). |

## Как настроить виджет

### Шаг 1. Создать вставку в настройках категории

В настройках категории откройте раздел **«Настройки JS и CSS вставок»** и создайте вставку:

- **тип контента** — `js`;
- включите флаг **«использовать в MTF»**;
- задайте **название вставки** — оно станет заголовком вкладки в карточке задачи.

Вкладка появляется в карточке задачи, когда вставка имеет тип `js` и включён флаг использования в MTF. Если название вставки не задано, заголовком вкладки служит ключ `title` из блока конфигурации (см. ниже); если не задано ни то ни другое — вкладка не создаётся.

### Шаг 2. Описать блок конфигурации `__WIDGET_CONFIG__`

В тело вставки поместите блок конфигурации между парными маркерами:

```text
/* __WIDGET_CONFIG__
{
  "title": "Заголовок секции",
  "url": "https://example.com/widget или /relative/path",
  "method": "POST",
  "body": {
    "param1": "@ep1234",
    "param2": "@taskId",
    "param3": 123,
    "param4": true
  }
}
__WIDGET_CONFIG__ */
```

Ключи JSON:

| Ключ | Тип | Обязательный | По умолчанию | Описание |
|---|---|---|---|---|
| `url` | строка | да | — | Абсолютный URL или относительный путь эндпоинта виджета. Не должен быть пустым. |
| `method` | строка | нет | `POST` | HTTP-метод запроса: `GET` или `POST`. |
| `body` | объект | нет | `{}` | Параметры запроса. Допускаются **только плоские значения**: строка, число, булево. |
| `title` | строка | нет | — | Заголовок вкладки. Используется, если название вставки (шаг 1) не задано. |

> Вложенные объекты и массивы в `body` не поддерживаются — при их наличии виджет не загрузится. Передавайте только плоские пары «ключ — значение».

### Шаг 3. Подстановки в `url` и `body`

Перед отправкой запроса в `url` и в **строковых** значениях `body` подставляются динамические значения текущей задачи:

| Плейсхолдер | Значение |
|---|---|
| `@taskId` | Идентификатор текущей задачи. |
| `@ep123` или `@ep{123}` | Значение дополнительного параметра задачи с указанным идентификатором. |

Нестроковые значения `body` (числа, булевы) подставлению не подлежат и передаются как есть.

### Шаг 4. Требования к эндпоинту (контракт ответа)

Приложение обращается к `url` указанным методом (для `POST` — передаёт `body` как параметры запроса) и ожидает в ответ JSON:

```json
{
  "ok": true,
  "html": "<div>...содержимое виджета...</div>",
  "error": null
}
```

Поведение приложения в зависимости от ответа:

- **`ok` + непустой `html`** — виджет показывается или обновляется, содержимое сохраняется для быстрого показа при следующем открытии;
- **`ok` + пустой `html`** — содержимое виджета очищается;
- **сбой запроса при наличии ранее показанного содержимого** — на экране остаётся прежнее содержимое и выводится предупреждение, что данные могут быть неактуальны;
- **сбой запроса без ранее сохранённого содержимого** — отображается состояние ошибки.

### Шаг 5 (опционально). Оформляющий контейнер — `emptyPortal`

Серверная настройка `emptyPortal` задаёт идентификатор «пустого портала», который служит оформляющим контейнером виджета и наследует его тему и стили. Содержимое виджета встраивается внутрь этого контейнера, не затирая его оформление.

Если `emptyPortal` не задан, используется стандартный пустой контейнер без дополнительного оформления.

## Поведение и быстрый показ

- При открытии вкладки ранее показанное содержимое выводится сразу, а в фоне выполняется обновление с сервера.
- Содержимое виджета сохраняется в привязке к конкретной задаче и конкретной вставке.
- Оформляющий контейнер (портал) кешируется до 1 часа.

## Рекомендация

Виджет в карточке задачи — поддерживаемый способ встроить веб-содержимое в карточку. Для кастомизации самой формы задачи (поля, режимы отображения, настройки) используйте мобильные шаблоны — см. [Шаблоны — обзор](https://help.1forma.ru/domains/mobile/mobile-templates.md).

## Связанные документы

- [Форма задачи → JS-вставки (первоисточник веб-механизма)](https://help.1forma.ru/domains/task-forms/admin.md)
- [Шаблоны — обзор](https://help.1forma.ru/domains/mobile/mobile-templates.md) — контексты NTF/MTF/Cell
- [Автогенерация и привязка шаблонов](https://help.1forma.ru/domains/mobile/reference/template-generation.md)
