Skip to content

Commit 2657bc6

Browse files
authored
GlideAjax: Populate choices from a Decision Table (#1062)
* Create GetChoicesFromDT.js * Create readme.md * Create addChoicesClient.js * Update addChoicesClient.js * Update readme.md * Update readme.md * Update GetChoicesFromDT.js Commenting updates * Update readme.md * Update readme.md * Update GetChoicesFromDT.js * Update addChoicesClient.js * Update readme.md * Update readme.md * Update readme.md * Update readme.md * Update readme.md * Update GetChoicesFromDT.js * Update readme.md * Update GetChoicesFromDT.js * Update readme.md
1 parent 164b2f3 commit 2657bc6

File tree

3 files changed

+151
-0
lines changed

3 files changed

+151
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
var GetChoicesFromDT = Class.create();
2+
GetChoicesFromDT.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
3+
4+
getChoices: function() {
5+
6+
/**
7+
* Gets the defined choices for the passed in catalog item
8+
*
9+
* @author Laszlo Balla
10+
* @param {String} sysparm_cat_item
11+
* The sys_id of the catalog item to get choices for - mandatory
12+
* @param {String} sysparm_cat_variable
13+
* Value from an additional catalog variable to evaluate as part of your decision - optional
14+
* @return {String}
15+
* A stringified array (since it goes to client script) of choices
16+
*/
17+
18+
19+
/**
20+
* In addition to the above, the following variable MUST be set for the script to work:
21+
*
22+
** decisionTableId : Sys ID of the decision table. Store in a system property and set with gs.getProperty()
23+
** dtInput1, 2, etc. : the technical names of the Decision Table inputs
24+
** resultColumn : the technical name of the result column of your Decision Table that has the choices set
25+
*/
26+
27+
var catItem = gs.nil(this.getParameter('sysparm_cat_item')) ? null : this.getParameter('sysparm_cat_item'); // Mandatory parameter
28+
var catVar = gs.nil(this.getParameter('sysparm_cat_variable')) ? null : this.getParameter('sysparm_cat_variable'); // Optional parameter example (variable from record producer). Multiple as needed, or remove if not.
29+
var decisionTableId = ''; //Sys ID of the decision table. Store in a system property and set with gs.getProperty()
30+
var dtInput1 = 'u_catalog_item'; // Make sure you set this to the technical name of the first input of your Decision Table
31+
var dtInput2 = 'u_catalog_variable'; // Make sure you set this to the technical name of the second input of your Decision Table, if you have one. Multiply as needed, or remove if not.
32+
var resultColumn = 'u_choice_result'; // Set this to the technical name of the result column that contains your choices
33+
var answerArray = [];
34+
var choiceArr = [];
35+
var iter1 = 0;
36+
37+
if (!gs.nil(catItem) && !gs.nil(decisionTableId)) {
38+
var choiceQuery = 'var__m_sys_decision_multi_result_element_' + decisionTableId;
39+
var decisonTable = new sn_dt.DecisionTableAPI();
40+
var inputs = new Object();
41+
inputs[dtInput1] = catItem;
42+
43+
// Repeat this block as necessary with additional parameters and inputs
44+
if (!gs.nil(catVar)) {
45+
inputs[dtInput2] = catVar;
46+
}
47+
48+
var dtResponse = decisonTable.getDecisions(decisionTableId, inputs);
49+
while (iter1 < dtResponse.length) {
50+
answerArray.push(dtResponse[iter1]['result_elements'][resultColumn].toString());
51+
iter1++;
52+
}
53+
// Now find the the actual choices with labels
54+
var choiceGr = new GlideRecord('sys_choice');
55+
choiceGr.addQuery('name', choiceQuery);
56+
choiceGr.addQuery('value', 'IN', answerArray.toString());
57+
choiceGr.setLimit(30); // The Choice table is huge, so I recommend setting a reasonable query limit. You should have an idea of the max # of results anyway.
58+
choiceGr.query();
59+
while (choiceGr.next()) {
60+
var choice = {};
61+
choice['value'] = choiceGr.getValue('value');
62+
choice['label'] = choiceGr.getValue('label');
63+
choiceArr.push(choice);
64+
}
65+
66+
return JSON.stringify(choiceArr); // Return a stringified array to the client
67+
68+
} else {
69+
gs.error('GetChoicesFromDT Script include did not run as the catItem mandatory variable is null: ' + catItem + ' or decision table sys_id is empty: ' + decisionTableId);
70+
return;
71+
}
72+
},
73+
74+
type: 'GetChoicesFromDT'
75+
});
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
function onLoad() {
2+
3+
var targetChoiceField = 'choice_field'; // Set this to the name of the Selectbox variable you want to populate
4+
g_form.clearOptions(targetChoiceField);
5+
6+
var catItem = g_form.getUniqueValue();
7+
var dtChoiceAjax = new GlideAjax('global.GetChoicesFromDT'); // Set this to the name of the script include with the relevant scope
8+
dtChoiceAjax.addParam('sysparm_name', 'getChoices');
9+
dtChoiceAjax.addParam('sysparm_cat_item', catItem);
10+
/*
11+
* Add an other option parameter, e.g.:
12+
* dtChoiceAjax.addParam('sysparm_cat_variable', g_form.getValue('some_variable'));
13+
*/
14+
dtChoiceAjax.getXMLAnswer(setChoices);
15+
16+
function setChoices(answer) {
17+
if (answer) {
18+
var choiceArray = JSON.parse(answer);
19+
if (choiceArray.length == 0) {
20+
// Do something if the response is empty
21+
g_form.setReadOnly(targetChoiceField, false);
22+
g_form.setMandatory(targetChoiceField, false);
23+
g_form.setDisplay(targetChoiceField, false);
24+
} else {
25+
g_form.setDisplay(targetChoiceField, true);
26+
27+
// Similarly, you might want to do something if there is only one choice, e.g. set that by default and make the field read-only.
28+
var isSingleChoice = choiceArray.length == 1 ? true : false;
29+
if (isSingleChoice) {
30+
g_form.addOption(targetChoiceField, choiceArray[0].value, choiceArray[0].label);
31+
g_form.setValue(targetChoiceField, choiceArray[0].value);
32+
g_form.setReadOnly(targetChoiceField, true);
33+
} else {
34+
// And finally, if you have multiple options, decide how you want your field to behave
35+
g_form.setReadOnly(targetChoiceField, false);
36+
g_form.addOption(targetChoiceField, '', '-- None --'); // Adding None option - this is also optional
37+
for (i = 0; i < choiceArray.length; i++) {
38+
g_form.addOption(targetChoiceField, choiceArray[i].value, choiceArray[i].label, i + 1);
39+
}
40+
g_form.setMandatory(targetChoiceField, true);
41+
}
42+
}
43+
} else {
44+
// What if there was no answer return from the script include at all?
45+
g_form.setReadOnly(targetChoiceField, false);
46+
g_form.setMandatory(targetChoiceField, false);
47+
g_form.setDisplay(targetChoiceField, false);
48+
}
49+
}
50+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Prerequisites
2+
## Decision table
3+
> [!IMPORTANT]
4+
> Create a Decision table with a result column of type '**Choice**', and at least one, **mandatory input** that is a reference to sc_cat_item.
5+
6+
You will have to define the decisions for each catalog item separately. One catalog item can have multiple results - this is how you will get multiple choices for your selectbox variable at the end.
7+
If you have other inputs, i.e. for different values from different variables, you simple add those conditions for each decision line for the related catalog item.
8+
> [!NOTE]
9+
> If you created the choices inside the Decision Table, make sure the values are not too long. They end up getting truncated in the sys_decision_answer table, and sebsequently the values stored in sys_choice will not match. If necessary, change the default value to something short and unique (or use an existing choice list if you can).
10+
11+
## Variables in the Script Include
12+
> [!IMPORTANT]
13+
> Make sure the following variables have a valid value in your script include:
14+
* `var decisionTableId = '';` The Sys ID of the decision table. Store in a system property and set with gs.getProperty().
15+
* `var dtInput1 = 'u_catalog_item';` Make sure you set this to the technical name of the first input of your Decision Table. It will always start with u_. If unsure, check the **sys_decision_input** table.
16+
* `var dtInput2 = 'u_catalog_variable';` Make sure you set this to the technical name of the second input of your Decision Table, if you have one. Multiply as needed (if you have more inuts), or remove / comment out if not.
17+
* `var resultColumn = 'u_choice_result';` Set this to the technical name of the result column that contains your choices
18+
19+
## Variables in the client script
20+
> [!IMPORTANT]
21+
> Remember to define the target field (the one you want to add the choices to) in row 3: `var targetChoiceField = 'choice_field';`
22+
23+
If you want send values from other variables for your decision table to consider, add them as additional parameters, in line with what you have defined in the Script include, for instance: `dtChoiceAjax.addParam('sysparm_cat_variable', g_form.getValue('some_variable'));`
24+
25+
# Usage
26+
Use the provided Script Include and Client Script, and update them as mentioned in the [Prerequisites](#prerequisites) section. The example client script is **onLoad**, but if you are looking to use variable values as additional inputs, you will want to have it run as an **onChange** script instead, or as a scripted UI Policy - it should work the same way.

0 commit comments

Comments
 (0)