Skip to content
Yago Ferrer edited this page May 8, 2017 · 13 revisions

Using option schema

This lab starts out with a quick introduction to Widget Options. The Widget’s Options Schema is a way to define configuration options (or parameters) that your widget can accept. For example, the cool clock widget has two options defined, a timezone and second hand color. Whenever you use an instance of the cool clock widget, you can specify values for both of those options.

The options schema supports the following field types:

  • String
  • Boolean
  • Integer
  • Reference
  • Choice
  • Field_list (depends on table)
  • Field_name (depends on table)
  • Glide_list

For more field types, or if your widget options require ui-policy or client scripts, you can create a table that extends sp_instance and use any field type in the ServiceNow platform.You will see an example of this towards the end of this lab.

Create a card list widget

  1. From Studio, Click Create Application File and type Widget in the filter. Select Widget and click Create. Create new

  2. Create a new widget with the following values:

    Name: Card List Simple

    ID: card_list_simple

Add a widget

  1. Click Submit

Optional: Open the properties menu and check Enable Preview With preview enabled, click on the preview button any time you want to see a real time preview of your widget in action.

Define widget options

  1. Select Edit option schema from the widget properties menu.

Edit Option Schema

  1. Click the [ + ] button and add the following values:

    Label : Title

    Name: title

    Type: String

    Hint: The title for the card list

  2. Click [ + ] again add another option:

    Label: Table

    Name: table

    Type: string

    Hint: The table to query

  3. Click [ + ] again add another option:

    Label: Filter

    Name: filter

    Type: string

    Hint: The filter query string

  4. Click [ + ] again add a final option:

    Label: Card Fields

    Name: fields

    Type: string

    Hint: Comma separated list of field names to include on the cards

  5. Click Save

  6. Click Save on the widget editor again. This is very important!

Use the options to render a list of records

You can refer to any option value in your widget client script or server script as options.optionName. Use the options to render a list of records.

Add this to the widget Server Script code block:

(function() {
   if (options.table) {
       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 + "," + options.fields;
       data.fields = $sp.getFieldsObject(gr, fields);
       while(gr.next()) {
             var row = {};
             $sp.getRecordDisplayValues(row, gr, fields);
             data.rows.push(row);
       }
   }
})();

Add this to the Client Script code block:

function() {
      var c = this;
      c.cardFields = (c.options.fields) ? c.options.fields.split(",") : "";
      c.getPrimaryField = function getPrimaryField(row){
            return row[c.data.primaryField];
      };
}

Add this to the CCS - SCSS code block:

.fields {
    $dl-horizontal-offset: 120px;
    dt {
        font-weight: normal;
        color: $text-muted;
        float: left;
        width: ($dl-horizontal-offset - 20);
        clear: left;
        text-align: right;
        @include text-overflow;
       }
    dd {
        @include clearfix;
        margin-left: $dl-horizontal-offset;
       }
 }

Add this to the HTML Template code block:

<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">
          <div class="h4 list-group-item-heading">{{c.getPrimaryField(row)}}</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>

Save the widget

Add the card list to a page using the Service Portal Designer.

  1. Open the designer by opening a new tab and going to [instance]/$spd.do
  2. Type in the filter to find the page called: Playground. Open the page Playground home

Selectexistig page

  1. Click on the [ + ] button to add a predefined layout of [ 3 | 9 ]

select layout

  1. Under the widgets toolbox, find the widget Card List Simple and drag it to the left column. Drag and drop the widget

Configure the widget using instance options

  1. Hover over the widget and click the edit pencil

  2. Enter the following values and click Save

    Title: Active Incidents

    Table: incident(all lower case, this is the table name not the label)

    Filter: active=true

    Card Fields: assigned_to,impact,incident_state,priority (all lower case, no spaces)

  3. You should see the following in the widget designer: Widget designer

This is a breakdown of everything that happened behind the scenes:

breadcrum

When you added the 2 column layout using the designer it created 3 records:

 sp_row (1 record) 
     A reference to the sp_container

 sp_column (2 records) 
     Left column with Size - md: 3 and a reference to sp_row 
     Right column with Size - md: 9 and a reference to sp_row

When you dropped the card list widget into the left column it created 1 record:

 **sp_instance** 
      A reference between the left column and the Card List Simple Widget

Side note: You can visualize this data tree map using the page editor:

[instance]/sp_config?id=page_edit&p=playground_home

When you edited the instance options for the card list it wrote the following JSON object into the sp_instance.widget_parameters field:

{
	"title": {
		"value": "Active Incidents",
		"displayValue": "Active Incidents"
	},
	"table": {
		"value": "incident",
		"displayValue": "incident"
	},
	"filter": {
		"value": "active=true",
		"displayValue": "active=true"
	},
	"fields": {
		"value": "assigned_to,impact,incident_state,priority",
		"displayValue": "assigned_to,impact,incident_state,priority"
	}
}

Optional

At this point, if you are behind or want to get your instance up to parity with the lab guide you can check out the branch lab_1_complete using STUDIO.

This is optional and you will lose all of your local changes.

  1. To check out that branch, open STUDIO and click on the Source Control menu. Switch branch

  2. Select lab_1_complete from the list and click Switch Branch. Switch branch lab 1