---
original_url: "https://jace.pro/blog/meetup-lab-service-portal-advanced-widget-development/"
format: markdown
ai_optimized: true
---

Meetup Lab: Service Portal Advanced Widget Development- # Meetup Lab: Service Portal Advanced Widget Development

July 11, 2019 [servicenow ](/tags/servicenow/)[service-portal](/tags/service-portal/)

  Enable AI AnimationThis lab covers advanced Service Portal widget development across 5 labs. Originally from CreatorCon (CCW1088).
*This lab originally from the [sndevs meetups repo](https://github.com/sndevs/meetups) and [hosted on GitHub Pages](https://sndevs.github.io/meetups/).*

Scoped app import: `https://github.com/sndevs/CCW3956.git`

## [Lab 1: Getting Started](#lab-1-getting-started)

Import the scoped app into Studio, then open the Service Portal designer at `/$spd.do`.

## [Lab 2: Using the Option Schema](#lab-2-using-the-option-schema)

Create a Card List Widget:

Name: `Card List Simple`
- ID: `card_list_simple`

Open the widget editor, click the hamburger menu, then “Edit option schema”. Add:

LabelNameTypeHintTitletitlestringThe title for the card listTabletablestringThe table for the queryFilterfilterstringThe filter query stringFieldsfieldsstringComma separated list of fields### [Server Script](#server-script)

Type out [server.js](./simple.list.server.js.txt) yourself:

### [CSS](#css)

Add [style.css](./simple.list.scss.txt):

### [Client Script](#client-script)

Add [client.js](./simple.list.client.js.txt):

### [HTML Template](#html-template)

Add [template.html](./simple.list.html.txt):

### [Add to Playground](#add-to-playground)

- Open `/$spd.do` and find the Playground page
- Add a container with a 3,9 split grid
- Place the Simple List Widget in the left side

### [Configure Instance Options](#configure-instance-options)

FieldValueTitleActive IncidentsTableincidentFilteractive=trueFieldsassigned_to, impact, incident_state, priority

## [Lab 3: Using SP Instance](#lab-3-using-sp-instance)

Create an `sp_instance` extension table for more configurability.

### [Create a Table](#create-a-table)

FieldValueLabelCard List InstanceExtends tableInstance with TableAdd a column (advanced view):

- Type: Reference
- Label: View
- Name: view
- Reference: UI View
- Reference qualifier: `javascript:"sys_idIN" + new x_snc_reusable_wid.ListViewHelper().getViewsForList(current.table)`

### [Create Script Include](#create-script-include)

Type out [ListViewHelper.js](./ListViewHelper.js.txt):

### [Clone Widget](#clone-widget)

Clone “Card List Simple” → name it “Card List”, then open in platform view. Set:

- Data Table: `Card List Instance`
- Fields: `Title, Table, View, Filter, Display Field`

### [New Widget Templates](#new-widget-templates)

Type out the [HTML template](./list.html.txt), [server script](./list.server.js.txt), and [client script](./list.client.js.txt):

### [Create a Service Portal Page](#create-a-service-portal-page)

- In Studio, create Application File → Service Portal Page
- Page title: `Incident Workspace`, Page ID: `iw`
- Add a [3 | 9] layout
- Drag Card List to the left column
- Configure: Table=`Incident`, Filter=`active=true`, Display field=`Short Description`, Title=`Active Incidents`, View=`Mobile`

## [Lab 4: Handling the Empty State](#lab-4-handling-the-empty-state)

Widgets should provide an empty state that tips users off about configuration.

### [Show a Default Title](#show-a-default-title)

Add this to the client script:

Then use it to set an example:

### [Richer UX](#richer-ux)

Replace your client script with [rich.client.js.txt](./rich.client.js.txt). Then in the designer, delete the Card List widget and drag a fresh instance — you’ll see a much better preview:

## [Lab 5: Embedded Widgets and Directives](#lab-5-embedded-widgets-and-directives)

As widgets grow complex, break them into smaller components.

Create an Angular Provider:

- Open Card List in the platform at `/sp_widget_list.do`
- Find Angular Providers related list
- Click New
- Type: Directive, Name: `workspaceCard`, Script: [directive.js](directive.js.txt)

**Pros:** Keeps template close to directive code, reusable, passable scope parameters
**Cons:** Template isn’t cached, directive can get large

---
[View this page on GitHub](https://github.com/jacebenson/jace.pro/tree/main/./src/posts/2019/2019-07-11-meetup-sp-widgets-lab.md).

[Meetup Lab: Service Portal Advanced Widget Development](https://jace.pro/blog/meetup-lab-service-portal-advanced-widget-development/) [Jace Benson](https://jace.pro) ![Jace Benson](https://jace.pro/icon-512x512.png)

---

*This content is from Jace Benson's ServiceNow and tech blog at jace.pro*
*Original post: https://jace.pro/blog/meetup-lab-service-portal-advanced-widget-development/*
