1. Defining a Widget Option Schema
A widget's Option schema (a field on the widget record) declares
named, typed configuration values an instance of that widget can set — the exact
same idea as declaring @Input() properties on an Angular component,
expressed as JSON instead of decorators.
[
{
"name": "table",
"label": "Table",
"type": "string",
"default_value": "incident"
},
{
"name": "max_rows",
"label": "Max Rows",
"type": "integer",
"default_value": "10"
},
{
"name": "title",
"label": "Panel Title",
"type": "string",
"default_value": "Records"
}
]
Once a schema exists, every time this widget is dropped into a container (via the Designer, from Week 9), an editable options form for that specific instance appears — so the same widget record can be configured completely differently on two different pages.
2. Reading Options in the Server Script
Configured option values arrive in the server script through the
options object, using the same names declared in the schema:
(function() {
data.title = options.title || 'Records';
data.rows = [];
var gr = new GlideRecord(options.table || 'incident');
gr.orderByDesc('sys_created_on');
gr.setLimit(parseInt(options.max_rows, 10) || 10);
gr.query();
while (gr.next()) {
data.rows.push({
display: gr.getDisplayValue(),
sysId: gr.getUniqueValue()
});
}
})();
options (Week 13) are configured once, when the widget is placed on a page, and stay fixed for that instance. input (Week 12) is sent fresh on every c.server.update() call from client-side interaction. Options answer "how is this instance configured"; input answers "what is the client asking for right now."
3. Spawning Widgets Dynamically with sp-widget
Beyond placing widgets via the Designer, a widget's own HTML template can spawn another widget instance directly, passing options inline — useful when a parent widget needs to render a variable number of child widgets it doesn't know about until its own server script runs.
function(spUtil) {
var c = this;
c.getWidget = function(tableConfig) {
return spUtil.get('data-table-widget-id', {
table: tableConfig.table,
title: tableConfig.title,
max_rows: 5
});
};
}
This pattern — a parent widget deciding at runtime how many child widget
instances to render, and with what configuration — is the widget-framework
analogue of dynamically creating Angular components with
ViewContainerRef, just resolved through spUtil
instead.
4. Hands-on Exercise
Build a reusable, configurable data-table widget
Requirements:
- Create the data-table widget with the option schema and server script shown above, plus an HTML template rendering
data.titleas a heading anddata.rowsas a list. - Place two instances of it on the same page: one configured for
incident, one forproblem, with differentmax_rowsvalues. - Confirm both instances render independently with their own configured table and title, from the same widget record.
- Add a third option,
order_by_field, and use it in the server script'sorderByDesc()call instead of the hardcodedsys_created_on.
5. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
What is a widget option schema the closest analogue to, in component-based frontend frameworks?
What is a widget option schema the closest analogue to, in component-based frontend frameworks?
It's the widget-framework equivalent of declaring @Input() properties on a component — named, typed configuration values that a widget instance can be configured with when it's placed, expressed as JSON in the widget's Option schema field rather than as decorated class properties.
Q2
How do you read a configured option value inside a widget's server script?
How do you read a configured option value inside a widget's server script?
Through the options object, using the same name declared in the option schema — e.g. options.table or options.max_rows — available automatically in the server script whenever that widget instance runs.
Q3
What's the key difference between options and input inside a widget's server script?
What's the key difference between options and input inside a widget's server script?
options are set once, when the widget instance is configured (via the Designer or when spawned dynamically), and stay fixed for that instance's lifetime. input is sent fresh on every c.server.update() call, reflecting whatever the client is asking for at that specific moment — options answer "how is this configured," input answers "what does the client want right now."
Q4
Why would a widget need to spawn other widgets dynamically via sp-widget instead of only placing them through the Designer?
Why would a widget need to spawn other widgets dynamically via sp-widget instead of only placing them through the Designer?
When a parent widget doesn't know in advance how many child widget instances it needs, or with what configuration, until its own server script has run — for example rendering one data-table widget per table name returned from a dynamic list. The Designer only handles a fixed, known set of widget placements decided at page-build time.