- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-05-2024 08:18 AM
In our location table we have Buildings and Floors. Buildings are parents to Floors. Some of our buildings have no child floors.
I'd like to make a catalog UI Policy to show the field "Floor" and make it mandatory only when the field "Building" gets a referenced values that actually has floors.
"When to apply" is easy, when Building=anything. I created the script to fire when this condition is met, but I get Java errors on the form when testing.
function onCondition() {
var floors = new GlideRecord("cmn_location"); //Get locations
var buildingSID = g_form.getValue('scvar_building'); //Get selected bulding's sysID
floors.addEncodedQuery('parent.sys_id='+buildingSID); //Filter for items with a parent of the selected building
floors.query();
if (floors.hasNext()) { //Check to see if query resulted in any items
g_form.setDisplay('scvar_floor', true); //Show Floor
g_form.setMandatory('scvar_floor', true); //Make Floor Mandatory
}
else { //Else if nothing has a parent of the selected building
g_form.setDisplay('scvar_floor', false); //Hide Floor
g_form.setMandatory('scvar_floor', false); //Make Floor Optional
}
}
I haven't done a ton of scripting on UI Policies, feels like im missing something simple.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-05-2024 08:36 AM
Since a UI Policy script runs on the client-side, it can't execute something like a GlideRecord query (since that's server-side code). If you want to run this check, you'll need to use GlideAjax and contact a script include, passing through the sys_id of the building. Your response from the script include will dictate what you do in the client script (e.g. you would change the floors.hasNext() to something like response == 'success' in your if statement).
If you need help getting started with GlideAjax, check out this comment I left yesterday. You'll have to shift the code a little bit, but the principle is the same.
I believe you'll also want to shift this all to a onChange and/or onLoad client script rather than using a UI Policy. This way, the system can adjust if the selected Building changes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-05-2024 11:42 AM
Not a good idea especially since it doesn't work in this case lol. Reading up on Glide Ajax now, seems pretty straight forward.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-05-2024 08:36 AM
Since a UI Policy script runs on the client-side, it can't execute something like a GlideRecord query (since that's server-side code). If you want to run this check, you'll need to use GlideAjax and contact a script include, passing through the sys_id of the building. Your response from the script include will dictate what you do in the client script (e.g. you would change the floors.hasNext() to something like response == 'success' in your if statement).
If you need help getting started with GlideAjax, check out this comment I left yesterday. You'll have to shift the code a little bit, but the principle is the same.
I believe you'll also want to shift this all to a onChange and/or onLoad client script rather than using a UI Policy. This way, the system can adjust if the selected Building changes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-05-2024 02:50 PM
This is what I worked out, seems to work alright.
Script Include:
var DoesParentLocationHaveChildScriptInclude = Class.create();
DoesParentLocationHaveChildScriptInclude.prototype = Object.extendsObject(AbstractAjaxProcessor, {
DoesParentLocationHaveChildFunction: function() {
var ParentID = this.getParameter('sysparm_parent');
var gr = new GlideRecord('cmn_location');
gr.addEncodedQuery('parent.sys_id=' + ParentID);
gr.query();
if (gr.next()) {
return 'true';
} else {
return 'false';
}
}
});
Catalog Client Script:
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}
var buildingSID = g_form.getValue('scvar_building');
var ga = new GlideAjax("DoesParentLocationHaveChildScriptInclude");
ga.addParam("sysparm_name", 'DoesParentLocationHaveChildFunction');
ga.addParam("sysparm_parent", buildingSID);
ga.getXML(result);
}
function result(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer == "true") {
g_form.setDisplay('scvar_floor', true);
g_form.setMandatory('scvar_floor', true);
} if(answer == "false"){
g_form.setMandatory('scvar_floor', false);
g_form.setDisplay('scvar_floor', false);
}
}
If you see anything that can be improved upon, let me know!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-05-2024 04:05 PM
Nice! Glad it works and thanks for sharing your code. The only thing I can think to change--and it's very minor--is to use newValue instead of doing the g_form.getValue (I am assuming that your onChange field is scvar_building).
So you'd pass in newValue as the param instead of buildingSID (and then won't need the variable declaration at all).
ga.addParam("sysparm_parent", newValue);