A widget includes four components that define its view, execution, and behavior:

  1. Template specifies widget views and the way they are displayed with HTML and SimpleTags. It also allows end-users to input and to interact with data. 
  2. Server script runs a JS script on the server-side and processes the data received from the client-side and passes it back. 
  3. Client script runs a JS script on the client-side, so that it receives the data from the server-side, processes the data before rendering, then passes it to the widget template. Also, the client script passes the data input received to the server-side.
  4. Demo data specifies widget options available for further customization and processing if it is needed.

Widget creation


Role required: admin.

To create a widget, follow the steps below:

  1. Navigate to Portal Structure → Widgets.
  2. Click New and fill in the fields.
  3. Click Save or Save and Exit to apply changes.

Widget form fields 

Field

MandatoryDescription

Name

YSpecify the name of your widget.

Description

NDescribe the widget in details.

Active

NSelect this checkbox to make the widget functionality available.

Template

N

Determine the widget display view with the <div> container:

<div></div> 
  • Use SimpleTags to define the form, fields, and the behavior you need:
<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

NSpecify CSS classes for the widget structure and style.

Tables

N

A list field type with reference to the Table (sys_db_table) dictionary. Specify tables, which views can be extended by adding the widget to their forms using the Form Layout functionality.

To make the widget available for adding to any table, choose the Global (sys_global) table.

Inheritance

NSelect this checkbox if you want to make the widget available for adding to child tables' records.

Server Script

N

Use this controller to specify how the widget sends, receives and processes system events on the server-side. 

The server script uses the input object to access the data received from the client controller and the data object for processing and sending it back as JSON. 

Use the Server API to create a server script code.

Client Script

N

Use this controller to specify how the widget sends, receives and processes system events on the client-side.

The client script uses the data object to access the server data. After processing the data by the client script, invoke the s_widget.serverUpdate() method to send the data to the server controller. When calling this method, the server script data object automatically overwrites the client controller data object. 

Use the Client API to create a client script code.

The client controller uses the s_widget object to invoke widget API methods.

It is not recommended to use native JS methods and properties manipulating the Document Object Model in widget client scripts. For example, using such properties as Element.innerHTML or Element.outerHTML in client scripts may possibly cause malfunction.

To avoid errors, please use methods provided and supported by vendor instead. See the example below for clarity.

Usage example
// Not Recommended
document.querySelector(".article-body").innerHTML = s_widget.getFieldValue('body');
// Recommended
s_widget.addTemplate('body', s_widget.getFieldValue('body'));

Demo Data

N

Specify the widget options used for the preset configuration. Use the formatting below to define the options:

Example
{ "title": "Timeline"; "column": "state" }

title and and column are options with the 'Timeline' and 'state' default values set.

These options may be overridden in the situations below:

Widget example


An example below illustrates the components of the widget displaying the following fields:

  • Incident: a reference field that allows selecting an item from the Incident table.
  • Description: a text field with a description of the Incident selected. The field is empty by default.
  • The get button: clicking the button fills in the Description field.
  • The send button: clicking the button overwrites the selected incident description in the database with the value specified in the Description field within the widget.
  • The go button: clicking the button opens the selected incident item on the current page.

Server controller


The server controller uses data.incident to access the input.incident data received from the client controller. Depending on the input.operation_code received, the server controller runs the query to the database for:

  1. getting the incident description within the getIncidentDescription(incident_id) function.
  2. updating it within the sendIncidentDescription(sys_id, description) function.
  3. getting a redirect URL within the createUrlFromIncidentNumber(sys_id) function.
Server script
;(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;
        }
    }
})();

Client controller


The client script includes the three s_widget_custom methods declared:

  • window.s_widget_custom.getDescription – to get an incident description from the server controller.
  • window.s_widget_custom.sendDescription – to send it back.
  • window.s_widget_custom.goToIncident – to open the incident item form.

Each method invokes s_widget.serverUpdate() for sending and receiving data back from the server controller. The data object allows accessing the redirect_url received from the server script.

Client script
;(() => {
  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 Template


The widget template defines the fields and buttons displayed using HTML and SimpleTags. Clicking the buttons activates the methods declared in the client controller.

Template
<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>

The CSS field allows specifying a style of the template components displayed.

CSS
.textColorRed textarea {
   color: red;
}

  • No labels