Виджет Код позволяет работать напрямую с разметкой страницы. С его помощью можно как писать код для формы с нуля, используя HTML, CSS, JavaScript или TypeScript, так и встраивать готовые решения.
Вы можете переопределить системные стили, добавить дополнительные обработчики на кнопки, задать собственное отображение таблиц и многое другое.
Инструмент по большей части предназначен для разработчиков, так как на его основе можно создавать виджеты любой сложности. Затем их можно переиспользовать на различных формах и страницах.
Доработаем виджет для расчёта дат, который мы начали создавать для приложения Отпуск.
Вынесем на поле для моделирования виджет Код. Откроется окно настроек. По умолчанию в него добавляется следующий код с примерами операндов:
Код:
<% if (false) { %>
You can use the following instructions:
- Conditions: <% if (true /* Condition */) { %> ... <% } %>
- Iterators: <% for (const item of [] /* Array */) { %> ... <% } %>
- Values with HTML-escaping: <%- 'SomeValue' %>
- Values without HTML-escaping: <%= 'SomeValue' %>
You can delete this block after reading.
<% } %>
Попробуем с помощью виджета Код задать для дат следующее отображение:
Начало_периода - Конец_периода ( Х дней, Y раб.часов )
Для этого удалим всё содержимое виджета и напишем следующий код:
Код:
<div class="days_count"> <!-- добавляем класс для использования в будущем -->
<div>
<%= Context.data.first_date%> - <%= Context.data.second_date%>
(<%= Context.data.days_count%> дней, <%= Context.data.hours_count%> раб.часов)
</div>
</div>
Запускаем отладку и вводим любые даты:
Результат на форме сейчас выглядит следующим образом:
Переменные first_date и second_date имеют тип Дата/время, и система не смогла привести их к строковому представлению.
Переменные days_count и hours_count не отобразились, так как мы не рассчитали их значения.
Обратите внимание, что сценарий не выдал ошибку, и остальной код отработал без проблем. Этот нюанс необходимо учитывать при разработке, чтобы не пропускать опечатки.
Доработаем отображение дат, используя функцию format(), которая поддерживает формат moment:
Код:
<div class="days_count">
<div>
<%= Context.data.first_date.format("DD.MM.YYYY") %> - <%= Context.data.second_date.format("DD.MM.YYYY")%>
(<%= Context.data.days_count%> дней, <%= Context.data.hours_count%> раб.часов)
</div>
</div>
Добавим переменную для количества рабочих часов hours_count в контекст виджета. Затем на вкладке Сценарии дизайнера интерфейсов напишем сценарий для расчёта дней и часов:
Код:
async function onInit(): Promise<void> {
const firstDate = Context.data.first_date!.asDatetime(new TTime());
const secondDate = Context.data.second_date!.asDatetime(new TTime());
const duration =firstDate.sub(secondDate);
Context.data.days_count = Math.round(Math.abs(duration.days));
Context.data.hours_count = Math.abs(duration.hours);
}
При отладке получаем следующий результат:
На данный момент количество рабочих часов вычислено неверно, так как не учитываются настройки рабочего календаря. Мы доработаем это в следующей главе.
Настройки виджета на данном этапе выглядят так:
Спойлер: Шаблон
Виджет Код со следующим содержимым:
Код:
<div class="days_count">
<div>
<%= Context.data.first_date.format("DD.MM.YYYY") %> - <%= Context.data.second_date.format("DD.MM.YYYY")%>
(<%= Context.data.days_count%> дней, <%= Context.data.hours_count%> раб.часов)
</div>
</div>
Спойлер: Сценарий
Код:
/** Инициализация виджета */
async function onInit(): Promise<void> {
const duration = Context.data.first_date!.sub(Context.data.second_date!);
Context.data.days_count = Math.round(Math.abs(duration.days));
Context.data.hours_count = Math.abs(duration.hours);
}
Пользовательские виджеты внутри виджета «Код»
В предыдущих главах мы рассмотрели, как создать и настроить собственный виджет. Сейчас рассмотрим, как с ним можно работать.
После публикации виджет добавляется в общий список виджетов, и его можно использовать точно так же, как стандартные. Откроем любую форму или страницу в дизайнере интерфейсов и попробуем найти созданный виджет в общем списке на правой панели.
Виджет можно добавить, к примеру, на форму приложения. При переносе виджета на поле для моделирования откроется окно настроек. Поля контекста, которые мы отметили как входные или выходные будут доступны для заполнения:
Далее применение пользовательских виджетов никак не отличается от использования стандартных.
Второй способ добавления пользовательского виджета на форму — это вызов специального метода в виджете Код с помощью контекстного меню:
Система предложит выбрать виджет из списка. Обратите внимание, что ваш виджет может не отображаться в общем списке из-за настроек доступа. В этом случае перейдите в дизайнер интерфейсов и откройте вкладку Настройки. В зависимости от того, на каком уровне настроен ваш виджет, в блоке Доступные элементы разрешите доступ ко всем элементам или к элементам раздела. Подробнее читайте в статье «Дизайнер интерфейсов».
После выбора виджета откроется окно его настроек. Свяжем виджет с контекстом приложения и контекстом формы:
В итоге получим следующий код с разметкой:
Код:
<%= UI.widget.render('leave@days_count', {first_date: Context.data.date_start, second_date: Context.data.date_end, days_count: Context.data.days, hours_count: ViewContext.data.workminutes}) %>
Отформатируем код и добавим признак, указывающий, что виджет используется только для чтения:
Код:
<%= UI.widget.render('leave@days_count',
{
readonly: true,
first_date: Context.data.date_start,
second_date: Context.data.date_end,
days_count: Context.data.days,
hours_count: ViewContext.data.workminutes
}
) %>
Для удобства не будем показывать содержимое виджета Код в разметке формы и зададим для него в нижней части окна настроек читаемое наименование, например, Количество дней [days_count].
Виджет готов к использованию. В дизайнере форма с виджетом Код будет выглядеть следующим образом:
Стандартные виджеты внутри виджета «Код»
В виджете Код можно использовать не только пользовательские виджеты, но и стандартные виджеты системы, однако их набор ограничен. Доступны следующие варианты: Вкладки, Панель с заголовком, Выпадающее окно и Выпадающее меню. Подробнее об этом читайте в TS SDK в статье про API для отображения стандартных виджетов.
Внутри виджета Код добавим на форму виджет Панель с заголовком и вложим в него созданный нами виджет Количество дней [days_count]:
Код:
<%= UI.widget.groupbox(
{
title: 'Количество рабочих дней',
collapsible: true, // Сворачиваемая панель
},
panelDaysCount)
%>
<% $template panelDaysCount %>
<%= UI.widget.render('leave@days_count',
{
readonly: true, // только для чтения
first_date: Context.data.date_start,
second_date: Context.data.date_end,
days_count: Context.data.days,
hours_count: ViewContext.data.workminutes
}
) %>
<% $endtemplate %>
Посмотрим, как виджеты будут выглядеть на форме:
Чтобы виджет с расчётом количества рабочих дней отрисовывался только тогда, когда обе даты введены, добавим условие:
Код:
<% if (Context.data.date_start && Context.data.date_end) { %>
<%= UI.widget.groupbox(
{
title: 'Количество рабочих дней',
collapsible: true, // Сворачиваемая панель
},
panelDaysCount)
%>
<% } %>
Функцию отрисовки содержимого панели panelDaysCount() можно оставить за скобками, так как здесь мы только определяем её, а вызов будет происходить при выполнении условия.