How to create a filterable list popup via a UI Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-27-2022 07:38 AM
I recently was faced with a challenge on how to bulk add multiple users from a dialog box. It is similar to if you click the Edit button but in my use case I needed to show a list of users when sys_user was not the table being referenced. I achieved it by created a Table and Condition field on a custom form and then created a UI Page and Script include. You can find the code below.
Code to call the UI Page from a UI Action
function onClickFunctionName(){
var dialog = new GlideDialogWindow('slush_bucket_users');
dialog.setTitle('Add Users');
dialog.setSize(1000,500);
dialog.render();
return false;
}
UI Page HTML
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<g:evaluate jelly="true"></g:evaluate>
<g:requires name="elements/element_conditions.jsx"></g:requires>
<TABLE BORDER="0">
<TR>
<TD>
<div>Conditions</div>
<!-- you need a table name field and a condition field that is dependent on that table name field here. You can use any table with those two fields but make sure there are no tableChoicesScripts on them or anything or it will mess it up. Get the sys id from the sys_dictionary record of your fields-->
<g:ui_element table="u_affected_users" field="u_table" id="ReplaceWithYourTableFieldSysId"></g:ui_element>
<g:ui_element table="u_affected_users" field="u_user_conditions" id="ReplaceWithYourConditionFieldSysId"></g:ui_element>
</TD>
</TR>
<TR>
<TD>
<button class="btn btn-primary" onclick="addUserQuery()">Filter</button>
</TD>
</TR>
<TR>
<TD> Please select the users you wish to add. </TD>
</TR>
<TR>
<TD>
<!-- Include the 'ui_slushbucket' UI macro -->
<div>
<g:ui_slushbucket name="sb" left_header="Left Side" right_header="Right Side">
</g:ui_slushbucket>
</div>
</TD>
</TR>
<TR>
<TD align="right">
<!-- Include the 'dialog_buttons_ok_cancel' UI macro -->
<g:dialog_buttons_ok_cancel ok="return continueOK()" cancel="return continueCancel()" ok_type="button" cancel_type="button" />
</TD>
</TR>
</TABLE>
</j:jelly>
UI Page Client Script
function continueOK() {
var values = sb.getValues(sb.getRightSelect());
var taskID = g_form.getUniqueValue();
//checks to make sure they did not select nothing
if (values == '') {
alert("At least one user must be selected");
return;
}
//calls our script include that has the code we want to perform against the values in our list
var ajax = new GlideAjax('UI_Page_Utils');
ajax.addParam('sysparm_name', 'addUsers');
ajax.addParam('sysparm_taskID', taskID);
ajax.addParam('sysparm_values', values);
ajax.getXML(addUserResponse);
}
function addUserResponse() {
GlideDialogWindow.get().destroy();
return true;
}
function continueCancel() {
GlideDialogWindow.get().destroy();
return false;
}
//This happens when the page loads
addLoadEvent(function() {
//This clears the -- that starts out on the right
sb.clearSelect(sb.getRightSelect());
//This sets the table value
//The format for the id of the field is TableNameYouChoose.TableNameField then you set the value to whatever table you are wanting to have the filter apply to
document.getElementById("u_affected_user.u_table").value = "sys_user";
//This used to be a getElementById but when inspecting the code the id of this changes every time it is loaded
var selectBoxChosen = document.getElementsByClassName("select2-chosen");
//This sets the table field
selectBoxChosen[0].innerHTML = "User [sys_user]";
//This hides the table select box. The format is s2id_TableNameYouChoose.TableNameField
document.getElementById("s2id_u_affected_user.u_table").hide();
//This loads the filter field the format is (TableNameYouChoose.ConditionFieldName, TableNameField)
loadFilterColumns('u_affected_user.u_user_conditions', 'u_table');
//This may be uneeded I have it because otherwise you have to scroll to see the whole filter
var filterRow = document.getElementsByClassName("col-xs-10 col-md-9 col-lg-8 form-field input_controls filter_controls-with-overflow");
//This just sets the first one. If you were to have multiple filters on the page for different tables then you could iterate them
filterRow[0].style.width = "100%";
});
function addUserQuery() {
//starts the loading dialog
showLoadingDialog();
//this gets the filter of the filter field The format is TableNameYouChoose.TableNameField should be the same as the first element in your loadEvent
var userFilter = getFilter('u_affected_user.u_user_conditions');
//This calls our script include where we pass in the query and it return us a list of users
var userQueryAjax = new GlideAjax('UI_Page_Utils');
userQueryAjax.addParam('sysparm_name', 'getUserList');
userQueryAjax.addParam('sysparm_query', userFilter);
userQueryAjax.getXML(userResults);
}
function userResults(response) {
hideLoadingDialog();
//Clears our list on the left
sb.clearSelect(sb.getLeftSelect());
//assigns our response to a var
var userList = response.responseXML.documentElement.getAttribute("answer");
//parses our JSON string to JSON so we can work with it
userListJson = JSON.parse(userList);
//Loops through our list and adds each of them to our slushbucet
for (var i = 0; i < userListJson.length; i++) {
var rowJson = userListJson[i];
//adds them to our slushbucket with the format of (value,label)
sb.addLeftChoice(rowJson['sys_id'], rowJson['name']);
}
}
Script Include Code
var UI_Page_Utils = Class.create();
UI_Page_Utils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
//This function is to add the users selected to the table I want
addUsers: function() {
//Gets the parameters from the function
var taskId = this.getParameter("sysparm_taskID");
var values = this.getParameter("sysparm_values");
//The slushbucket list comes in a comma seperated string. This turns that into an array
var valueArrary = values.split(",");
//Loops through the array and executes the code I want against each record
for (var i = 0; i < valueArrary.length; i++) {
var userID = valueArrary[i];
var affectedUserGR = new GlideRecord("u_affected_user");
affectedUserGR.u_affected_user = userID;
affectedUserGR.u_outage = taskId;
affectedUserGR.insert();
}
//You could return something of value here if you wanted.
return true;
},
//This is the function to return a list of users based on a query you could add more parameters and be able to put in a table name and such
getUserList: function() {
var query = this.getParameter("sysparm_query");
var userList = new GlideRecord("sys_user");
//This is the query we pass in from our user
userList.addEncodedQuery(query);
userList.query();
var userListArray = [];
//This loops through our results and pushes them to an array. You can add any values you want here to the Array of objects. Just follow Json format because this is an array of objects
while (userList.next()) {
userListArray.push({
"sys_id": userList.sys_id.toString(),
"name": userList.name.toString()
});
}
//this returns the list of users in JSON String format so you can parse it on the other end. If you dont to this it returns as a string that is the name of the object
return JSON.stringify(userListArray);
},
type: 'UI_Page_Utils',
});
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-22-2024 01:43 AM
Sure, here's a summarized version of your solution in bullet points:
1. You created a custom form with a Table and Condition field. This form is used to select the users that need to be added in bulk.
2. You created a UI Page. This page is used to display the list of users that are selected from the custom form.
3. You created a Script Include. This script is used to process the selected users and add them in bulk.
4. The Script Include uses the GlideRecord API to query the sys_user table and add the selected users.
5. The UI Page uses the GlideForm API to display the list of selected users and provide an interface for the user to confirm the bulk add operation.
6. The custom form uses the GlideDialogWindow API to display the UI Page when the user clicks on the 'Add Users' button.
7. The bulk add operation is performed when the user confirms the operation on the UI Page.
8. The Script Include uses the GlideUser API to add the selected users to the sys_user table.
9. The UI Page is refreshed after the bulk add operation is completed to display the updated list of users.
10. The custom form and the UI Page are linked using the 'name' attribute of the UI Page and the 'source' attribute of the GlideDialogWindow API.
Please note that this is a high-level summary of your solution and the actual implementation may vary based on the specific requirements and the ServiceNow instance configuration.
nowKB.com
If you want to know any information about Service Now . Visit to https://nowkb.com/home