Создание виджета

Виджет содержит четыре компонента, которые задают вид и поведение виджета:

  1. Шаблон задает вид виджетов и способ их отображения с помощью HTML и Simple-тегов. Он также позволяет конечным пользователям вводить данные и взаимодействовать с виджетом.
  2. Серверный скрипт запускает JS-скрипт на стороне сервера, обрабатывает данные, полученные со стороны клиента, и передает их обратно.
  3. Клиентский скрипт запускает JS-скрипт на стороне клиента так, чтобы он получил данные со стороны сервера, передает данные перед отображением, затем передает их в шаблон виджета. Кроме того, клиентский скрипт передает полученные данные на сервер.
  4. Демо-данные указывают параметры виджета, доступные для дальнейшей настройки и обработки, если это необходимо.

Требуемая роль: admin.

Чтобы создать виджет, выполните следующие шаги:

  1. Перейдите в Структура портала → Виджеты.
  2. Нажмите Создать и заполните поля.
  3. Нажмите Сохранить или Сохранить и выйти, чтобы применить изменения.

Поля формы Виджет

ПолеОбязательноОписание
НаименованиеДаУкажите название виджета.
ОписаниеДаДайте подробное описание виджета.
АктивенНетУстановите флажок, чтобы активировать виджет. Неактивные виджеты нельзя добавлять на формы или страницы. 
ТаблицыНет

Укажите таблицы, на формы которых можно добавить виджет с помощью настройки представления формы.

Чтобы виджет был доступен для добавления в любую таблицу, выберите Глобальную таблицу (sys_global).

НаследуетсяНетУстановите этот флажок, чтобы сделать виджет доступным для добавления на формы записей дочерних таблиц.
ШаблонНет

Определите вид отображения виджета с помощью контейнера <div>:

<div></div> 

Используйте Simple-теги, чтобы определить форму, поля и поведение, которые вам нужны:

<div>
	<textarea></textarea>
	<button></button>
</div> 

Примените атрибуты тегов, чтобы указать и описать поведение элементов виджета:

<div>
	<textarea label="Name" model="data.name">
	</textarea>
	<button event-click="window.s_widget_custom.submit();">
		OK
	</button>
</div> 
CSSНетУкажите классы CSS для создания структуры и стиля виджета.
Серверный скриптНет

Укажите скрипт, который определяет, как виджет отправляет, получает и обрабатывает системные события на стороне сервера.

Серверный скрипт использует объект input для доступа к данным, полученным от клиентского контроллера, и объект data для обработки и отправки обратно в формате JSON.

Используйте Серверный API для создания серверного скрипта.

Клиентский скриптНет

Укажите скрипт, который определяет, как виджет отправляет, получает и обрабатывает системные события на стороне клиента.

Клиентский скрипт использует объект data для доступа к данным сервера. После обработки данных клиентским скриптом вызовите метод s_widget.serverUpdate() для отправки данных на серверный контроллер. При вызове этого метода объект data серверного скрипта автоматически перезаписывает объект data контроллера клиента.

Используйте клиентский API для создания клиентского скрипта.

Клиентский контроллер использует объект s_widget для вызова методов API класса SimpleWidget(s).


Не рекомендуется использовать нативные методы и свойства JS, управляющие моделью DOM, в клиентских скриптах виджетов. Например, использование в клиентских скриптах таких свойств, как Element.innerHTML или Element.outerHTML, может привести к сбоям в работе.

Во избежание ошибок используйте вместо этого методы, предоставленные и поддерживаемые поставщиком. См. пример ниже.

Usage example
// Не рекомендуется
document.querySelector(".article-body").innerHTML = s_widget.getFieldValue('body');
// Рекомендуется
s_widget.addTemplate('body', s_widget.getFieldValue('body'));
Демо-данныеНет

Укажите параметры виджета, используемые для предустановленной конфигурации. Используйте форматирование ниже, чтобы задать параметры:

{ value_1: '1'; value_2: 'abc' }

value_1 и value_2 – это параметры с установленными значениями по умолчанию "1" и "abc".

Эти параметры могут быть переопределены в следующих ситуациях:

На следующей схеме показано, как данные передаются между серверным и клиентским скриптами с помощью глобальных объектов:

Пример виджета


В следующем примере показаны компоненты виджета, отображающие поля и кнопки:

  • Инцидент ссылочное поле, которое позволяет выбрать элемент из таблицы Инциденты (itsm_incident).
  • Описание – текстовое поле с описанием выбранного Инцидента (itsm_incident). По умолчанию поле пустое.
  • Кнопка Получить описание заполняет поле Описание значением из связанного инцидента.
  • Кнопка Отправить описание – перезаписывает описание инцидента в базе данных значением, указанным в поле Описание.
  • Кнопка Перейти – открывает выбранный инцидент на текущей странице.

Серверный контроллер


Серверный контроллер использует переменную data.incident для доступа к данным переменной input.incident, полученной от клиентского контроллера. В зависимости от полученного значения переменной input.operation_code контроллер сервера выполняет запрос к базе данных для того, чтобы:

  1. Получить описание инцидента в функции getIncidentDescription(incident_id).
  2. Обновить инцидент в функции sendIncidentDescription(sys_id, description).
  3. Получить URL-адрес перенаправления в функции createUrlFromIncidentNumber(sys_id).
Серверный скрипт
;(function() {
    const OPERATION_GET_DESCRIPTION = 1;
    const OPERATION_SAVE_DESCRIPTION = 2;
    const OPERATION_GO_TO_INCIDENT = 3;    
	data.incident = input.incident;    
	if (!input.operation_code) {
        getTableId(options.table);
        return;
    }    
	if (!input.incident || !input.incident.database_value) {
        ss.addInfoMessage('Select record.');
        return;
    }    
	if (input.operation_code == OPERATION_GET_DESCRIPTION) {
        data.description = getIncidentDescription(input.incident.database_value);
    }    
	if (input.operation_code == OPERATION_SAVE_DESCRIPTION) {
        sendIncidentDescription(input.incident.database_value, input.description);
        ss.addInfoMessage('The incident description is updated.');
    }    
	if (input.operation_code == OPERATION_GO_TO_INCIDENT) {
        data.redirect_url = createUrlFromIncidentNumber(input.incident.database_value);
    }    
	function getIncidentDescription(incident_id) {
      	if (!incident_id) {
        	return;
        }
        let record = new SimpleRecord('itsm_incident');
        record.addQuery('sys_id', incident_id);
        record.query();
       	if (record.next()) {
        	return record.description;
        }
        ss.addInfoMessage('Incident is not found');
    }    
	function sendIncidentDescription(sys_id, description) {
        let record = new SimpleRecord('itsm_incident');
        record.addQuery('sys_id', sys_id);
        record.query();
        if (record.next()) {
            record.description = description;
            record.update();
        }
    }    
	function createUrlFromIncidentNumber(sys_id) {
        return `/record/itsm_incident/${sys_id}`;
    }    
	function getTableId(tableName) {
        let record = new SimpleRecord('sys_db_table');
        record.addQuery('name', tableName);
        record.query();
        if (record.next()) {
            data.table_id = record.sys_id;
        }
    }
})();

Клиентский контроллер


Внутри клиентского скрипта можно задавать пользовательские методы для виджетов при помощи переменной  window.s_widget_custom.

Также клиентский скрипт включает три объявленных метода s_widget_custom:

  • window.s_widget_custom.getDescription – для получения описания инцидента от контроллера сервера.
  • window.s_widget_custom.sendDescription – для отправки описания обратно.
  • window.s_widget_custom.goToIncident – для открытия формы инцидента.

Каждый метод вызывает функцию s_widget.serverUpdate() для отправки и получения данных от контроллера сервера. Объект data позволяет получить доступ к значению переменной redirect_url, полученному от серверного скрипта.

Клиентский скрипт
;(() => {
  window.s_widget_custom = window.s_widget_custom || {}; 
  s_widget.serverUpdate();
  window.s_widget_custom.getDescription = function () {
    s_widget.setFieldValue('operation_code', 1);
    s_widget.serverUpdate();
  };  
  window.s_widget_custom.sendDescription = function () {
   	s_widget.setFieldValue('operation_code', 2);
    s_widget.serverUpdate();
  };  
  window.s_widget_custom.goToIncident = async function () {
    s_widget.setFieldValue('operation_code', 3);
    const response = await s_widget.serverUpdate();
    const data = response.getData();
    s_go.open(data.data.redirect_url);};
})();

Шаблон HTML


Шаблон виджета определяет поля и кнопки, отображаемые с помощью HTML и Simple-тегов. Нажатие на кнопки активирует методы, объявленные в клиентском контроллере.

Шаблон
<div style="width: '600px', marginBottom: '20px'">
    <h2>Incident Description Widget</h2>
    <reference data-table="itsm_incident" 
		data-table_id="options.table" label="Incident" 
		model="data.incident"></reference>
    <textarea label="Description" model="data.description" 
		class="textColorRed"></textarea>
    <button event-click="window.s_widget_custom.getDescription();">get</button>
    <button event-click="window.s_widget_custom.sendDescription();">send</button>
    <button event-click="window.s_widget_custom.goToIncident();">go</button>
</div>

Используйте поле CSS, чтобы указать стиль отображаемых компонентов шаблона.

CSS
.textColorRed textarea {
   color: red;
}

Взаимодействие виджетов


В случаях, когда вам нужно, чтобы виджеты взаимодействовали друг с другом, используйте методы s_widgets в своих клиентских скриптах:

  • Получайте и меняйте данные виджета с помощью методов s_widgets.getFieldValue(widgetID, key) и s_widgets.setFieldValue(widgetID, key, value):

    window.s_widgets.getFieldValue('157555401214600424', 'name');
    window.s_widgets.getFieldValue('157555401214600424', 'name', 'Alex');
  • Получайте все ID виджетов на текущей странице с помощью метода s_widgets.getWidgets():

    window.s_widgets.getWidgets();
  • Посмотрите, какие элементы содержит виджет, используя метод s_widget.getElements():

    window.s_widget.getElements();

  • No labels