﻿# Передать событие между дочерними виджетами

> [HTML Version](child-widget-event.html)

С помощью поля типа **Событие** в одном виджете можно создать пользовательское событие и передать его в другой виджет. Подробнее о том, как это работает и как настроить передачу данных от дочернего виджета в родительский, читайте в статье [«Передать событие в родительский виджет»](event-in-widgets.md). 

В данной статье рассмотрим комплексный пример с использованием различных опций и дополнительных переменных, когда событие передаётся между двумя дочерними виджетами, размещёнными в одном родительском.

Предположим, что в системе создана страница **Отчёт по транзакциям**. На ней размещены два дочерних виджета: **Настройки фильтрации** и **Таблица с поступлениями**. Когда пользователь вводит значения в поля фильтров, в виджете с таблицей выполняется поиск по введённым параметрам и отображаются его результаты. Это позволяет просматривать искомые элементы сразу после ввода значения в поле фильтра.

**(child-widget-event-1.png)**

Рассмотрим подробнее, как выполнить настройку такой передачи данных. 

## Шаг 1. Создать и настроить пользовательский виджет «Настройки фильтрации»

Начните настройку с создания виджета, который содержит поля с параметрами фильтрации. В нём нужно:

- добавить свойства для поиска;

- создать переменную типа **Событие**, к которой в родительском виджете (странице **Отчёт по транзакциям**) привязывается скрипт для выполнения поиска;

- в настройках созданных свойств для поиска указать скрипт в опции **Событие при изменении значения**. Таким образом каждый раз, когда вводится значение в поле, в родительский виджет будет передаваться событие вместе с указанными данными фильтрации.

Выполните эти действия:

1. [Создайте виджет](interface_settings.md#create-widget) **Настройки фильтрации** со следующими переменными:

- **Контрагент** — переменная типа [Приложение](app-data-type.md). В этом поле пользователь укажет название нужного контрагента для поиска данных по его названию;

- **Начало периода** и **Конец периода** — переменные типа [Дата/время](360009707032.md#date-time). Здесь можно указать период поступлений;

- **Изменение фильтров** — служебное поле типа [Событие](360009707032.md#event). Оно применяется в скрипте, который зафиксирует событие использования фильтра, произошедшее в виджете.  
**(child-widget-event-2.jpg)**

2. На вкладке **Шаблон** вынесите виджет [Панель с заголовком](panel_with_heading.md) и назовите его **Настройки фильтрации**. В эту панель добавьте виджет [Колонки](columns.md), а в них — свойства **Контрагент**, **Начало периода** и **Конец** **периода**.  
**(child-widget-event-3.png)**

3. На поле для моделирования выберите свойство **Контрагент** и нажмите значок шестерёнки. В открывшемся окне перейдите на вкладку **События**. Справа от опции **Событие при изменении значения** нажмите кнопку **Создать**, введите название функции **setFilters**, выберите **Сохранить**, а затем — **Открыть**.  
**(child-widget-event-4.png)**

Чтобы отправить событие вместе с данными фильтрации, когда пользователь введёт значение в это поле, на открывшейся вкладке **Скрипты** укажите следующую функцию:

````
async function setFilters(): Promise<void> \{  
    const filterData = \{  
        agent: Context.data.agent,  
        from\_date: Context.data.from\_date,  
        to\_date: Context.data.to\_date,  
    \};  
  
    Context.data.filter\_changed?.emit(filterData);  
\}

4. ````
Укажите эту же функцию для свойств **Начало периода** и **Конец периода**. Для этого в их настройках на вкладке **События** справа от опции **Событие при изменении значения** нажмите пустое поле и выберите **setFilters**.

5. Сохраните и опубликуйте виджет **Настройки фильтрации**.

Теперь его можно использовать в других виджетах как дочерний для фильтрации элементов приложений по заданным параметрам.

## Шаг 2. Создать и настроить пользовательский виджет «Таблица с поступлениями»

Создайте второй виджет для отображения результатов фильтрации в виде таблицы. В настройках виджета задайте настройки, чтобы:

- запускать поиск соответствующих элементов, когда в фильтрах изменяется значение;

- отображать результат поиска в таблице.

1. [Создайте виджет](interface_settings.md#create-widget) **Таблица с поступлениями** со следующими переменными:  
**(child-widget-event-5.png)**

- **Таблица** — переменная типа [Таблица](360010201779.md). Настройте её колонки, указав необходимые свойства приложения. Здесь пользователь увидит результаты фильтрации по введённым значениям. Подробнее о том, как настроить колонки таблицы читайте в статье [«Настройка поля типа „Таблица“»](table-visibility.md);

- **Поступление** — переменная типа [Приложение](app-data-type.md) с опцией **Один**. Выберите приложение **Реестр поступлений**. Это служебная переменная, которая нужна для выполнения ниже указанного скрипта. С её помощью происходит поиск элементов приложения по заданным фильтрам;

- **Данные фильтрации** — служебная переменная типа [Произвольный тип](360009707032.md#any). Она используется, чтобы передать данные из первого виджета **Настройки фильтрации** во второй виджет **Таблица с поступлениями**.  
**(child-widget-event-6.png)**

При создании переменной **Данные фильтрации** в опции **Событие при изменении значения** укажите скрипт, который покажет отфильтрованные данные в таблице.

Скрипт для заполнения таблицы отфильтрованными данными

````
  
interface FilterData \{  
    agent: TApplication<Application\$\_clients\$\_companies\$Data, any, Application\$\_clients\$\_companies\$Processes> | undefined;  
    from\_date: TDate | undefined;  
    to\_date: TDate | undefined;  
\}  
  
async function setFilter(): Promise<void> \{  
    const filterData: FilterData = Context.data.filterData;  
  
    // Получение транзакций поступлений по заданным фильтрам  
    const transactions = await Context.fields.transactions.app.search()  
    .where((f, g) => \{  
        const conditions: Filter\[\] = \[\];  
        if (filterData.agent) \{  
            conditions.push(f.\_contractor.link(filterData.agent))  
        \}  
        if (filterData.from\_date) \{  
            conditions.push(f.\_plannedPaymentDate.gte(filterData.from\_date))  
        \}  
        if (filterData.to\_date) \{  
            conditions.push(f.\_plannedPaymentDate.lte(filterData.to\_date))  
        \}  
        return g.and(...conditions)  
    \})  
    .all()  
  
    const table = Context.data.table\!;  
  
    // Очистка таблицы  
    for (let i = table.length - 1; i >= 0; i--) \{  
        table.delete(i);  
    \}  
  
    // Заполнение таблицы  
    for (const item of transactions) \{  
        const row = table.insert();  
        row.contractor = item.data.\_contractor\!;  
        row.plan\_data = item.data.\_plannedPaymentDate\!;  
        row.name = item.data.\_\_name;  
    \}  
  
    // Обновляем отображение таблицы  
    Context.data.table = Context.data.table;  
\}


````

````


2. На вкладке **Шаблон** вынесите виджет [Панель с заголовком](panel_with_heading.md) и назовите его **Поступления**. В этот виджет добавьте созданное свойство **Таблица**.  
**(child-widget-event-7.png)**

3. Сохраните и опубликуйте виджет **Таблица с поступлениями**.

Теперь его можно использовать в других виджетах как дочерний, чтобы показать результаты фильтрации транзакций в виде таблицы.

## Шаг 3. Добавить виджеты на страницу и настроить передачу данных между ними

На [созданную страницу](360009924451.md) **Отчёт по транзакциям** добавьте виджеты **Настройки фильтрации** и **Таблица с поступлениями**. Страница станет для них родительским виджетом. На странице записываются данные фильтрации от первого виджета и передаются во второй.

1. Откройте настройки страницы **Отчёт по транзакциям** и перейдите в [дизайнер интерфейсов](360027211631.md#setting-in-designer), нажав опцию **Конструктор**.

2. На вкладке **Контекст** создайте переменную **Данные фильтрации** типа **Произвольный тип**. Она нужна, чтобы:

- записать в эту переменную данные фильтрации, полученные вместе с событием от виджета **Настройки фильтрации**;

- связать контекст страницы с контекстом виджета **Таблица с поступлениями** для показа найденных элементов в таблице.

3. Перейдите на вкладку **Шаблон** и вынесите созданные ранее:

- виджет **Настройки фильтрации**;

- виджет **Таблица с поступлениями**.  
**(child-widget-event-8.png)**

4. Откройте настройки виджета **Настройки фильтрации** и перейдите на вкладку **События**.  
**(child-widget-event-9.png)**

На этой вкладке отобразится переменная типа **Событие**, созданная в конструкторе виджета. Привяжите к ней скрипт. С его помощью данные фильтрации запишутся в контекст страницы, когда виджет передаст событие **Изменение фильтров**.  
**(child-widget-event-10.png)**

Для этого справа от события нажмите **Создать**, введите название функции **onFilterChanged** и выберите **Сохранить**, а затем — **Открыть**. В результате на вкладке **Скрипты** создастся асинхронная функция. Внесите в неё следующий скрипт:

````
// Устанавливаем запуск скрипта, если значение фильтра изменилось  
async function onFilterChanged(filterData: FilterData): Promise<void> \{  
    Context.data.filterData = filterData;  
\}  
// Указываем, какие значения может принять функция  
interface FilterData \{  
    agent: TApplication<Application\$\_clients\$\_companies\$Data, any, Application\$\_clients\$\_companies\$Processes> | undefined;  
    from\_date: TDate | undefined;  
    to\_date: TDate | undefined;  
\}

5. ````
Вернитесь на вкладку **Шаблон** и откройте настройки виджета **Таблица с поступлениями**. На вкладке **Основные** вы увидите его переменные. Чтобы таблица отобразила элементы по данным фильтрации, нужно передать эти данные в контекст виджета таблицы. Для этого установите связь с переменной произвольного типа **Данные фильтрации**, которую создали ранее в контексте страницы.  
**(child-widget-event-11.png)**

Сохраните настройки виджета **Таблица с поступлениями**.

6. Сохраните и опубликуйте страницу **Отчёт по транзакциям**.

Теперь при вводе значения в одно из полей фильтров в таблице отобразятся данные элементов приложения **Реестр поступлений**.