Skip to content

Lab 1.5

Yago Ferrer edited this page May 10, 2017 · 17 revisions

Getting started with custom sp_instance extension tables

Widgets like the card list are rarely useful with such basic configuration. A list (whether cards or tables) usually has many requirements depending on the kind of data you want to show. For instance, it can be tedious and arcane to type in a list of fields to show on each card. What if your widget has options that only apply under certain circumstances? In this section, you will learn how to create an sp_instance extension table that allows for more types of options and configurability of your widgets. To give a fair comparison, we will create a similar widget. But when you configure this widget you will be able to pick a pre-built view for the list of fields on your cards. If you already have a VTB card layout, you could just re-use it like this:

VTB view

Create a table that extends sp_instance_table

  1. Using STUDIO click Create Application File.

create application file

  1. Select: Data Model- > Table. Click Create.

  2. Create the table with the following values:

    Label: Card List Instance Name: [automatically created] Extends table: Instance with Table Create Module: false

  3. Click Submit

Create a script include to help build a reference qualifier

  1. Using STUDIO click Create Application File.

create application file

  1. Select: Server Development -> Script Include. Click Create.

  2. Use the following values for the script include:

    Name: ListViewHelper

    Script:

    var ListViewHelper = Class.create();
    ListViewHelper.prototype = {
        initialize: function() {
        },
        getViewsForList: function(table) {
		var views = [];
		var gr = new GlideRecord("sys_ui_list");
		gr.addEncodedQuery("viewNOT LIKErpt^sys_userISEMPTY");
		gr.addQuery("name", table);
		gr.query();
		while(gr.next()) {
			var view = gr.getValue("view");
			if (views.indexOf(view) == -1) {
				views.push(view);
			}
		}
		return views.join(",");
	},

    type: 'ListViewHelper'
    };
  1. Click Submit.

Create a reference field to select a view

  1. Using STUDIO click on the table Card List Instance (If you don’t see a place to add a new column, close the tab and open the Card List Instance table again)

  2. Add a new column
    Type: Reference
    Column Label: View
    Column Name: view
    Reference: UI View (sys_ui_view)
    Display: checked

  3. Click on the hamburger menu and hit Save.

  4. Near the bottom of the form, under Related Links, click Advanced view

  5. In the section Reference Specification. Set the following values:

Use reference qualifier: Advanced

Reference qual:

javascript:"sys_idIN" + new x_snc_reusable_wid.ListViewHelper().getViewsForList(current.table)
  1. Click the Update button.

Clone: Card List Simple widget

  1. Using STUDIO click on the widget Card List Simple
  2. In the widget editor, click on the widget properties menu (next to the save button) and select Clone “Card List Simple”.
  3. Name the new widget: Card List
  4. Click Submit.

Edit Card List widget in the platform

Open the new Card List widget using the platform by using the widget properties menu (next to the save button) and selecting Open in platform and you can close the widget editor window.

  1. Ensure the widget name is “Card List”
    If not you must go to [instance]/sp_widget_list.do and select the Card List widget

  2. Change the field Data Table: Card List Instance

Card list instance

  1. Set Fields: Title, Table, View, Filter, Display Field
  2. Set the Option Schema to:
[{"hint":"A field that contains a value 1 -4 to indicate priority.",
"name":"priority_field",
"default_value":"priority",
"label":"Priority Field",
"type":"string"}]

5.Set the HTML Template code block to:

<div>
  <div class="panel panel-default">
    <div class="panel-heading">
      <span class="h3 panel-title">{{::c.options.title}}</span>
    </div>
    <div class="panel-body">
      <div class="list-group" ng-repeat="row in c.data.rows track by row.sys_id">
        <a href="javascript:void(0)" class="list-group-item" ng-style="::c.getPriority(row)">
          <div class="small">{{::c.getPrimaryField(row)}}</div>
          <div class="h4 list-group-item-heading">{{::row[c.options.display_field]}}</div>
          <dl class="fields">
            <span ng-repeat="f in c.cardFields"><dt>{{c.data.fields[f].label}}</dt><dd>{{row[f]}}</dd></span>
          </dl>
        </a>
      </div>
    </div>
  </div>
</div> 
  1. Set the Server script code block to:
(function() {
	if (options.table) {
		data.cardFields = $sp.getListColumns(options.table, options.view_dv);
		data.rows = [];
		var gr = new GlideRecord(options.table);
                gr.addEncodedQuery(options.filter);
		gr.setLimit(25);
		gr.query();
		if (!data.primaryField) {
				data.primaryField = gr.getDisplayName();
			}
		var fields = "sys_id," + data.primaryField + "," + data.cardFields;
		data.fields = $sp.getFieldsObject(gr, fields);
		while(gr.next()) {
			var row = {};
			$sp.getRecordDisplayValues(row, gr, fields);
			data.rows.push(row);
		}
	}
})();
  1. Set the Client Script code block to:
function() {
	var c = this;
	if (c.data && c.data.cardFields) {
		c.cardFields = getCardFields(c.data.cardFields, c.data.primaryField);
	}
	
	c.getPrimaryField = function getPrimaryField(row) {
		return row[c.data.primaryField];
	};
	
	function getCardFields(allFields, primaryField) {
		var cardFields = [];
		allFields = allFields.split(",");
		var exclude = [primaryField, c.options.display_field, c.options.priority_field];
		for (var i = allFields.length-1; i>= 0; i--){
			if (exclude.indexOf(allFields[i]) == -1) {
				cardFields.push(allFields[i]);
			}
		}
		return cardFields;
	}
	
	c.getPriority = function(row) {
		if (typeof row[c.options.priority_field] == "undefined") {
			return;
		}
		var p = row[c.options.priority_field];
		var color;
		if (p.indexOf('4') > -1) {
			color = 'green';
		} else if (p.indexOf('3') > -1) {
			color = 'yellow';
		} else if (p.indexOf('2') > -1) {
			color = 'orange';
		} else if (p.indexOf('1') > -1) {
			color = 'red';
                }
		if (color) {
			return {'border-left': '3px solid ' + color};
		}
	}
}
  1. Click Update

The primary difference with this widget is that when you drag it onto your page from the designer it will create the instance record in the table *card_list_instance. Editing records in that table will apply the reference qualifier on the view field and make it super simple to define a view that can be shared across different card lists on the platform.

Configure the card_list_instance form

  1. In a new tab go to [instance]/x_snc_reusable_wid_card_list_instance.do

  2. Right click on the form header. Choose Configure -> Form Layout.

  3. Choose the Section “Table, Filter & Fields”.

  4. Move the field View between Table and Filter. Add view to form

  5. Click Save.

Add the new card list to a page

  1. Using STUDIO click Create Application File.

  2. Select Service Portal -> Service Portal Page. Click Create.

  3. For page name and ID use the following values:

    Page title: Incident Workspace Page

    ID: iw

  4. Add the same [ 3 | 9 ] column layout to the default container.

  5. From the widget list, Drag and drop the Card List widget to the left column.

  6. Click on the pencil edit icon and set the following instance options:
    Title: Active Incidents
    Table: Incident
    View: Mobile
    Filter: active=true
    Display field: Short Description
    Priority Field: [use default]

  7. Click Save.