- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-02-2018 07:24 AM
I have a fairly simple before business rule that adds a message if the CI entered on an Incident record has active Change Requests against it. My issue is that I have been tasked with making this functionality work more "real time", as an "onChange" of the Incident cmdb_ci field.
And this is where my lack of knowledge on script includes comes in. I've spent quite a bit of time trying to figure this out but Script Includes just seem to confuse me.
Here is the business rule that I'm wanting to convert, it runs before insert and update on the Incident table. I would appreciate any help on this.
var gr = new GlideRecord('change_request');
gr.addQuery('cmdb_ci', current.cmdb_ci);
gr.addQuery('active', true);
gr.query();
if (gr.next()) {
var rc = gr.getRowCount();
gs.addErrorMessage("This CI has " + rc + " open Changes against it");
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-02-2018 11:33 AM
Things are a little clearer now (still pretty cloudy though!) but the main thing is that I do have a working script include and a working GlideAjax call. Plus the gr.getRowCount() does still work, so I can provide a "live" count in the alert box.
Here is the modified Script Include based off Shane J's example:
var ChangeCheck = Class.create();
ChangeCheck.prototype = Object.extendsObject(AbstractAjaxProcessor, {
getChangeRequests : function(){
var ciVal = this.getParameter('sysparm_ciVal');
var gr = new GlideRecord('change_request');
gr.addQuery('cmdb_ci', ciVal);
gr.addQuery('active', true);
gr.query();
if (gr.hasNext()) {
var rc = gr.getRowCount();
return "This CI has " + rc + " open Changes against it";
}
else {
return "This CI has no open Changes against it.";
}
},
type: 'ChangeCheck'
});
And here is the modified onChange Client Script (also based off Shane J's example):
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var ciVal = g_form.getValue('cmdb_ci');
var ga = new GlideAjax('ChangeCheck');
ga.addParam('sysparm_name', 'getChangeRequests');
ga.addParam('sysparm_ciVal', ciVal);
ga.getXML(chgCallback);
function chgCallback(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
}
Currently this is working and I have only found 1 issue so far. I found that I had to provide an alert message for the "else" part of the Script Include, otherwise I was getting an alert popup with "null" as the value.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-02-2018 12:52 PM
Could you have the answer from the Script Includes provide a less robust response if the answer is 'None' (or null) and then do an IF in your Client Script, to just "return;" instead of forcing an "alert(answer)"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-02-2018 03:24 PM
If you wanted to simplify a bit and squeeze the most out of performance (as we all should), here's an updated Script Include:
var ChangeCheck = Class.create();
ChangeCheck.prototype = Object.extendsObject(AbstractAjaxProcessor, {
getChangeRequestCount : function(){
var count = 0; //default to none
var ci = this.getParameter("sysparm_ci");
var ga = new GlideAggregate("change_request"); //faster than GlideRecord when we just need a count
ga.addAggregate("COUNT");
ga.addEncodedQuery("active=true^cmdb_ci=" + ci);
ga.query();
if (ga.next()) {
count = ga.getAggregate("COUNT");
}
return count;
},
type: 'ChangeCheck'
});
It will just return the number of records found. No message, just the number. That way we could possibly reuse the function elsewhere.
Then, the Client Script can be simplified as well:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var ga = new GlideAjax("ChangeCheck");
ga.addParam("sysparm_name", "getChangeRequestCount");
ga.addParam("sysparm_ci", newValue); //no need to g_form.getValue(), we already have the value in "newValue"
ga.getXMLAnswer(chgCallback);
function chgCallback(answer){ //the response from getXMLAnswer already just contains the value we want, no need to traverse an XML document
alert(answer);
}
}
You can then actually add some logic to the Client Script to do different things based on the number returned:
function chgCallback(answer){
var count = parseInt(answer);
var type = "info";
var msg = "No Change Requests were found for the selected CI."; //default
if (count == 1) {
msg = "1 Change Request was found for the selected CI.";
} else if (count >= 10) {
msg = "Whoa! " + count + " Change Requests were found for the selected CI.";
type = "error";
} else {
msg = count + " Change Requests were found for the selected CI.";
}
g_form.showFieldMsg("cmdb_ci", msg, type);
}
That way the logic to grab the number of records and whatever we may want to do with that info is kept in the appropriate places.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-03-2018 12:41 AM
Utilising GlideAjax is, of course, best practice. However, for extremely simple tasks it would be feasible to simply define a function in the script include that was later executed in a call in an onChange script. Again, I would by no means suggest this, but for simple logging to avoid synchronisation errors.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-05-2018 10:15 PM
Were you able to find a solution?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-06-2018 04:48 AM
Yes I did. The second set of example scripts above worked. And I've since used them as a base for further script includes.