﻿# Динамическая таблица

> [HTML Version](dynamic-table.html)

Виджет **Динамическая таблица **позволяет отобразить пользовательское содержимое в виде стандартной таблицы с колонками, строками и ячейками.

Используйте виджет, когда сотрудникам нужно выполнять действия с данными прямо из строк таблицы: запускать процессы, изменять значения, просматривать информацию в нестандартном виде.

В настройках виджета **Динамическая таблица **указывается** **таблица-источник, в шаблоне виджета добавляется нужное количество колонок. Внутри каждой колонки — настраивается отображение заголовка, содержимого ячейки строки и ячейки подвала. Для этого используются другие виджеты.

Например, можно задать запуск процесса обработки элемента, разместив в колонке виджет **Кнопка**. В примере ниже применяется пользовательский виджет, с помощью которого пользователь может изменить и сохранить значение суммы заказа.

**(dynamic-table-1.png)**

Виджет **Динамическая таблица **можно добавить на страницу. Для этого откройте её в дизайнере интерфейсов и выполните следующие действия:

1. На вкладке **Контекст **добавьте переменную с типом **Таблица**, которая будет источником данных для виджета **Динамическая таблица**. Задайте значение переменной. Например, укажите приложение в её настройках или сформируйте значение с помощью скрипта.

2. Перетащите виджет с боковой панели на поле для моделирования и [задайте его настройки](#settings).

3. Настройте внешний вид таблицы в [шаблоне виджета](#sample).

## Настройки виджета

1. На вкладке **Основное** заполните поля:

**(dynamic-table-2.png)**

- **Списочные данные\*** — выберите контекстную переменную типа **Таблица**, данные которой будут использоваться в вижете;

- **Показывать заголовок\* **— опция включена по умолчанию. Позволяет отобразить заголовки для колонок таблицы;

- **Показывать подвал\*** — опция включена по умолчанию. Используйте её, чтобы показать в виджете итоговую нижнюю строку таблицы, например, общую сумму по всем заказам.

2. На вкладках **События** и **Системные **можно задать [системные настройки](common_widget_settings.md), одинаковые для всех виджетов. Они позволяют управлять видимостью виджетов и доступом к ним, настраивать их поведение при наведении курсора и т. д.

3. Сохраните настройки виджета.

## Настроить шаблон виджета

Если настройки виджета **Динамическая таблица** заданы, отобразится его пустой шаблон в поле для моделирования. Настройте внешний вид таблицы, заполнив шаблон виджета колонками и другими виджетами. Для этого:

1. Добавьте количество колонок, которое хотите показать в таблице. Для этого используйте значок плюса. Обратите внимание, колонки и данные таблицы-источника автоматически не добавляются в виджет.

**(dynamic-table-3.png)**

2. При добавлении колонки в открывшемся окне можно задать её [системные настройки](common_widget_settings.md).

3. В каждой колонке отобразятся три блока, в которых можно настроить содержимое заголовка колонки, ячейки строки и ячейки подвала. Для этого используйте другие виджеты. В их настройках укажите данные таблицы-источника, которые хотите показать. Примеры настройки шаблона приведены ниже.

**(dynamic-table-4.png)**

4. Завершив настройки шаблона, на верхней панели нажмите **Сохранить** и затем — **Опубликовать**.



## Пример с использованием виджета «Кнопка»

Настроим на отдельной странице таблицу со списком заказов и возможностью запустить обработку любого заказа по кнопке.

**(dynamic-table-5.png)**

Для этого:

1. На уровне раздела, в котором пользователи работают с приложением **Заказы**, создайте страницу **Таблица заказов** и откройте её в дизайнере интерфейсов.

2. На вкладке **Контекст** добавьте переменную **Заказы** `(table)` с типом **Таблица** — в неё запишутся данные заказов, когда пользователь откроет страницу. Затем из этой переменной данные будут переданы в виджет **Динамическая таблица**. Включите опции **Входное** и **Выходное**.

3. Предоставьте виджету доступ к списку заказов. Для этого перейдите на вкладку **Настройки > Доступные элементы** и включите опцию **Разрешить использование элементов раздела**.

4. На вкладке **Настройки > Системные функции** задайте [функцию инициализации](widget_functions.md#onlnit)** **`onInit()`, в результате которой данные приложения **Заказы **запишутся в переменную **Заказы**.

Пример скрипта для инициализации страницы



````
async function onInit () \{  
    // Получение всех элементов приложения Заказы  
    const orders = await Namespace.app.zakazy.search().all();  
      
    // Присваивание значения переменной типа Таблица  
    Context.data.table = Context.fields.table.create();  
     
    // Создание в таблице строки для каждого элемента приложения Заказы  
    let total = 0;  
    for (const order of orders) \{  
        const row = Context.data.table.insert();  
        row.order = order;  
        row.statusName = order.data.\_\_status?.name ?? 'Неизвестно';          
    \}  
         
    // Присваивание значения таблице повторно, чтобы виджет обновился  
    Context.data.table = Context.data.table;  
\}
````

5. ````
В конструкторе страницы **Таблица заказов** на вкладке **Шаблон** разместите виджет **Динамическая таблица** и на вкладке **Основное**:

- укажит**е **контекстную переменную **Заказы**, чтобы отобразить в таблице элементы приложения **Заказы**;

- выключите опцию **Показывать подвал\***, т. к. в нашем примере не нужно отображать итоговую строку в нижней части таблицы.

6. На вкладке **Шаблон** добавьте две колонки, используя значок плюса.

7. В первой колонке разместите:

- для заголовка — виджет **Надпись**. В его настройках введите текст **Название**;

- для ячейки строки — виджет **Надпись**. В его настройках выберите **Строка источника – Заказы > Заказы > Название**;

8. Во второй колонке добавьте:

- для заголовка — виджет **Надпись**. В его настройках введите текст **Запуск процесса**;

- для ячейки строки — виджет  **Кнопка**. В поле **Тип действия** выберите запуск процесса и укажите бизнес-процесс **Обработка заказа**.  
Чтобы экземпляр процесса запускался по определённому элементу в таблице, свяжите переменную процесса с виджетом. Для этого в настройках кнопки нажмите **Настроить входные** **параметры**. В открывшемся окне в левой колонке укажите переменную процесса, которое хранит приложение, а в правой — **Строка источника – Заказы. Заказ**.

(dynamic-table-6.png)

9. Сохраните настройки виджета **Кнопка**. Шаблон виджета **Динамическая таблица** примет вид:

**(dynamic-table-7.png)**

10. Завершив настройки шаблона виджета, на верхней панели нажмите **Сохранить** и затем — **Опубликовать**.

После этого пользователи увидят таблицу заказов с колонками **Название** и **Запуск процессов**. В строке с нужным заказом можно нажать кнопку и запустить процесс его обработки. Список заказов обновится каждый раз при переходе пользователя на страницу.

## Пример с использованием пользовательского виджета

Рассмотрим более сложный пример с использованием виджета **Динамическая таблица**. Настроим таблицу со списком заказов, в которой можно редактировать их сумму. Если пользователь изменит сумму заказа и нажмёт **Сохранить**, новое значение запишется в элемент приложения** Заказы**. Также настроим отображение общей суммы всех заказов в итоговой нижней строке таблицы.

**(dynamic-table-1.png)**

Для этого выполните следующие шаги настроек:

1. [Предварительная настройка страницы](#page-setup), на которой будет размещена таблица.

2. Создание виджета [Редактируемая сумма заказа](#create-widget), который используется в колонке **Сумма**.

3. Размещение на странице и [настройка виджета](#setup-dynamic-table) **Динамическая таблица**.

### Шаг 1. Предварительная настройка страницы

1. На уровне раздела, в котором пользователи работают с приложением **Заказы**, создайте страницу **Таблица заказов**.

2. Перейдите в конструктор страницы и на вкладке **Контекст** добавьте переменные:

- **Заказы** `(table)` с типом **Таблица** — в неё запишутся данные заказов, когда пользователь откроет страницу. Затем из этой переменной данные будут переданы в виджет **Динамическая таблица**;

- **Общая сумма **`(total)` с типом **Деньги** — её значение отобразится в итоговой нижней ячейке колонки **Сумма**.

Для созданных переменных задайте опции **Входное** и **Выходное**.

3. В настройках переменной **Заказы** в поле **Событие при изменении значения** задайте функцию `onChanged()` для перерасчёта общей суммы при внесении изменений в таблицу.

**(dynamic-table-8.png)**

Пример скрипта для перерасчёта итоговой суммы в таблице





````
async function onChanged(): Promise<void> \{  
    if (\!Context.data.table) \{  
        return;  
    \}  
    // Пересчитываем итоговую сумму при изменении значения таблицы  
    let total = 0;  
    for (const row of Context.data.table) \{  
        if (row.summa) \{  
            total += row.summa.asFloat();  
        \}  
    \}  
    Context.data.total = new Money(total, 'RUB');      
\}
````

4. ````
Предоставьте виджету доступ к списку заказов. Для этого перейдите на вкладку **Настройки > Доступные элементы** и включите опцию **Разрешить использование элементов раздела**.

5. На вкладке **Настройки > Системные функции** задайте функцию инициализации** **`onInit()`, в результате которой данные приложения **Заказы **запишутся в переменную **Заказы**.

Пример скрипта для инициализации страницы





````
async function onInit () \{  
    // Получение всех элементов приложения Заказы  
    const orders = await Namespace.app.zakazy.search().all();  
      
    // Присваивание значения переменной типа Таблица  
    Context.data.table = Context.fields.table.create();  
     
    // Создание в таблице строки для каждого элемента приложения Заказы и подсчет итоговой суммы  
    let total = 0;  
    for (const order of orders) \{  
        const row = Context.data.table.insert();  
        row.order = order;  
        row.statusName = order.data.\_\_status?.name ?? 'Неизвестно';  
        if (order.data.summa) \{  
            row.summa = order.data.summa\!;  
            total += order.data.summa.asFloat();  
        \}  
    \}  
    Context.data.total = new Money(total, 'RUB');  
     
    // Присваивание значения таблице повторно, чтобы виджет обновился  
    Context.data.table = Context.data.table;  
\}
````

````


### Шаг 2. Создание виджета «Редактируемая сумма заказа»

1. На уровне раздела, в котором создана страница **Таблица заказов** добавьте пользовательский виджет **Редактируемая сумма заказа**. Он будет использоваться в таблице в колонке **Сумма** и позволит пользователю изменить сумму заказа прямо в таблице.

2. Перейдите в конструктор виджета и на вкладке **Контекст **добавьте переменные, которые будут использованы в скриптах и окне настроек виджета, а также в других виджетах, добавленных в шаблон текущего:

- **Заказ** `(order)` с типом **Приложение (один)** — свяжите его с приложением **Заказы**, отметьте опцию **Входное**;

- **Сумма** (summa) c типом **Деньги **— включите опции **Входное **и **Выходное **для этой переменной;

- **Сумма только для чтения** `(isReadonly)` с типом **Выбор «да/нет»** и значением **Да** по умолчанию;

- **Сохранение?** `(isSaving)` с типом **Выбор «да/нет»** и значением **Нет** по умолчанию;

- **Редактируемая сумма** `(editableSumma)` c типом **Деньги**.

3. На вкладку **Шаблон** добавьте виджет **Контейнер** и в нём поместите созданное свойство **Редактируемая сумма** и два виджета **Кнопка**.

**(dynamic-table-9.png)**

4. Один виджет **Кнопка** настройте для редактирования суммы заказа. Для этого в настройках виджета выберите тип действия **Скрипт** с функцией `edit` для переключения на режим редактирования.

**(dynamic-table-10.png)**

Пример функции для редактирования суммы:

````
async function edit(): Promise<void> \{  
    Context.data.isReadonly = false; // переключаем режим на редактирование  
\}

5. ````
Другой виджет **Кнопка** задайте для сохранения нового значения суммы заказа. В настройках виджета:

- в поле **Не активна** выберите переменную **Сохранение?** — она используется в скрипте виджета, чтобы исключить повторное нажатие кнопки;

- задайте тип действия **Скрипт** с функцией `save`.

**(dynamic-table-11.png)**

Пример скрипта для перерасчёта итоговой суммы в таблице

````
async function save(): Promise<void> \{  
    Context.data.isSaving = true; // поле для деактивации кнопки сохранения, чтобы избежать повторного нажатия  
    try \{  
        const order = await Context.data.order\!.fetch(); // выбираем элемент приложения с сервера  
        order.data.summa = Context.data.editableSumma; // устанавливаем новое значение элемента  
        await order.save(); // сохраняем элемент  
        UI.notify('Сумма изменена', NotificationType.Success); // уведомляем об успешном сохранении  
        Context.data.summa = Context.data.editableSumma; // новое значение копируемв в отображаемое только для чтения  
        Context.data.isReadonly = true; // переключаем на режим просмотра  
    \} finally \{  
        Context.data.isSaving = false; // активируем кнопку сохранения  
    \}

6. ````
На вкладке **Настройки > Основные **включите опцию **Вызывать функцию инициализации в конструкторе**.

7. Перейдите на вкладку **Настройки > Системные функции** и задайте функцию инициализации** **`onInit()`, чтобы в поле для редактирования по умолчанию отображалось заданное значение суммы заказа:

````
async function onInit(): Promise<void> \{  
    // Из входных данных копируем в поле для редактирования значение для отображения в режиме просмотра  
    Context.data.editableSumma = Context.data.summa;  
\}

8. ````
Сохраните и опубликуйте виджет** Редактируемая сумма заказа**.

### Шаг 3. Настройки виджета «Динамическая таблица»

1. В конструкторе страницы **Таблица заказов** на вкладке **Шаблон** разместите виджет **Динамическая таблица **и на вкладке **Основное** укажите** **контекстную переменную **Заказы**, чтобы отобразить в таблице элементы приложения **Заказы**.

2. На вкладке **Шаблон** добавьте две колонки, используя значок плюса.

3. В первой колонке разместите:

- для заголовка — виджет **Надпись**. В его настройках введите текст **Название**;

- для ячейки строки — виджет **Надпись**. В его настройках выберите **Строка источника – Заказы > Заказы > Название**;

4. Во вторую колонку добавьте:

- для заголовка — виджет **Надпись**. В его настройках введите текст **Сумма**;

- для ячейки строки — виджет **Редактируемая сумма заказа**, созданный на предыдущем шаге. Нажмите значок шестерёнки, перейдите в настройки виджета и заполните входные параметры:

**(dynamic-table-12.png)**

	- **Заказы** — выберите **Строка источника – Заказы > Заказ**;

	- **Сумма** — выберите **Строка источника – Заказы > Сумма**;

- в итоговой ячейке — свойство **Общая сумма**. 

5. Завершив настройки шаблона виджета, на верхней панели нажмите **Сохранить**  и затем — **Опубликовать**.

После этого пользователи могут работать со списком заказов на странице **Таблица заказов**. Выбрав запись в колонке **Название**, можно изменить и сохранить сумму заказа в колонке **Сумма**. Итоговая стоимость всех заказов отобразится в нижней строке в колонке **Сумма**.