Multi-response output controls
Summarize
Summary of Multi-response output controls
Multi-response output controls enable the implementation of multi-step user input processes within ServiceNow applications. This functionality is particularly useful for scenarios like paginating picker options or collecting sequential input such as selecting a year, then a month, and finally a date. These controls leverage context data stored per user to maintain state across multiple interaction steps.
Show less
Key Features
- Context Data Management APIs: Four key APIs are available exclusively in inbound and outbound transformers to manage user context data:
setProviderUserContext(key, contextData, providerAppId, providerUserId)– stores context data keyed by user and application.getProviderUserContext(key, providerAppId, providerUserId)– retrieves stored context data.removeProviderUserContext(key, providerAppId, providerUserId)– deletes specific user context data.removeAllProviderUserContext(providerAppId, providerUserId)– deletes all stored context data for a user and application.
- User-Specific Pagination State: Outbound transformers can save current pagination details (e.g., page index and length) in the user context. Inbound transformers retrieve and update this information based on user navigation actions.
- Picker Control Example: Demonstrates how to paginate picker options, presenting "prev" and "next" controls to navigate pages and updating the displayed options accordingly. The outbound transformer constructs the paginated display, while the inbound transformer processes user input, updates pagination state, and resolves selected values.
How This Enables ServiceNow Customers
By using multi-response output controls with user context APIs, customers can design conversational or interactive controls that maintain state across multiple user inputs. This is essential for handling large option sets with pagination or sequential input steps without losing context. The provided example code serves as a practical template to implement paginated pickers that respond dynamically to user navigation, improving user experience and input accuracy.
Practical Application
- Implement paginated pickers to display manageable subsets of large option lists, enhancing performance and usability.
- Use multi-step input flows, such as date pickers that prompt for year, month, and day in sequence.
- Maintain user-specific interaction state securely and efficiently via the provided context APIs within transformers.
- Customize inbound and outbound transformers to handle user actions like "next" and "prev," updating context and generating appropriate responses.
Implement controls that involve multiple steps to get user input.
Use the following API to configure context data for multi-output controls.
Common use cases
- To achieve pagination of pickers: page_no, pagination_length updated in inbound based on next/previous button is read in outbound.
- Step by step response of date picker like first year, then month, and then date selection.
sn_cs.VASystemObject.setProviderUserContext( key, contextData, providerAppId, providerUserId);
sn_cs.VASystemObject.getProviderUserContext(key, providerAppId, providerUserId);
sn_cs.VASystemObject.removeProviderUserContext(key, providerAppId, providerUserId);
sn_cs.VASystemObject.removeAllProviderUserContext(providerAppId, providerUserId) var paginationData = {
"page_index": 1,
"pagination_length": 2
}
};
sn_cs.VASystemObject.setProviderUserContext("picker_pagination", paginationData, providerAppId, providerUserId, );var paginationData = sn_cs.VASystemObject.getProviderUserContext("picker_pagination", providerAppId, providerUserId);Example code for picker control outbound transformer
(function execute(inputs, outputs) {
var control = inputs.rich_control;
var payload = inputs.payload;
var appId = payload.appId;
var userId = payload.userId;
var paginationData = sn_cs.VASystemObject.getProviderUserContext('picker_control', appId, userId);
paginationData = JSON.parse(paginationData);
//First time when the outbound picker is called when selecting the topic.
if (paginationData == null) {
paginationData = {
'page_index': 1,
'pagination_length': 5
};
sn_cs.VASystemObject.setProviderUserContext('picker_control', paginationData, appId, userId);
}
var page_index = paginationData['page_index'];
var pagination_length = paginationData['pagination_length'];
var start = (page_index - 1) * pagination_length;
var end = page_index * pagination_length;
if (control['options']) {
var options = control['options'];
var optionsLength = options.length;
if (end > optionsLength)
end = optionsLength;
var picker = control["label"] + ":";
if (start > 0)
picker += "\n" + "*" + ": " + "prev";
for (var x = start; x < end; x++) {
gs.log("here " + x + " : " + options[x]);
picker += "\n" + (x + 1) + ": " + options[x].label;
}
if (end < optionsLength)
picker += "\n" + "#" + ": " + "next";
}
outputs.text_message = picker;
})(inputs, outputs);
Example Picker Control Inbound Tranformer
(function execute(inputs, outputs) {
var request_context = inputs.request_context;
var rich_control = inputs.rich_control;
var appId = request_context.appId;
var userId = request_context.userId;
var selectedValue = request_context["typed_value"];
var result = {};
result["value"] = "";
result["search_text"] = selectedValue;
var options = rich_control['options'];
var paginationData = sn_cs.VASystemObject.getProviderUserContext('picker_control', appId, userId);
paginationData = JSON.parse(paginationData);
switch (selectedValue) {
case 'prev': {
--paginationData["page_index"];
result["send_prev_control"] = true;
}
break;
case 'next': {
++paginationData["page_index"];
result["send_prev_control"] = true;
}
break;
default: {
var selectedIndex = Number(selectedValue) - 1;
if (paginationData["page_index"] != undefined && paginationData["pagination_length"] != undefined) {
var highestOptionInPage = paginationData["page_index"] * paginationData["pagination_length"];
if (selectedIndex >= 0 && selectedIndex < highestOptionInPage) {
var selectedOption = options[selectedIndex];
result["value"] = selectedOption.value;
result["search_text"] = "";
}
} else {
var selectedOption = options[selectedIndex];
result["value"] = selectedOption.value;
result["search_text"] = "";
}
}
}
sn_cs.VASystemObject.setProviderUserContext('picker_control', paginationData, appId, userId);
outputs.result = result;
})(inputs, outputs);