Skip to main content

ServiceNow Client Scripting

See if any values on the form changed (client) 


if (g_form.modified){
       //---add code

}


//--example: check carried out in a 'risk assessment' client side UI action
if(g_form.modified){
   alert('As values were changed, saving the form');
   var resSv=g_form.save();
   return;
}

Save form in client script 


g_form.save();

gsftSubmit(gel('sysverb_update_and_stay'));

Check mandatory fields in client


For example if need to check from a client side ui action if the mandatory fields are complete


var arrMand = g_form.getMissingFields();
if(arrMand.length>0){
  alert('Complete mandatory fields');
}else{
   //--carry on
}

Getting label title text


var el = gel("label.change_request.test_plan");
//var el = gel("status.change_request.test_plan");
alert(el.innerHTML);
alert(el.title);
alert(el.label-text);

Modifying field hint

here's a way of editing the change_request.test_plan hint:


var el = gel("label.change_request.test_plan");

//var el = gel("status.change_request.test_plan");
alert (el.innerHTML);
document.getElementById('status.change_request.test_plan').setAttribute('title', 'BLAHBLAH');
document.getElementById('status.change_request.test_plan').setAttribute('aria-label', 'BLAHBLAH');
alert(el.innerHTML);
var elements = el.getElementsByTagName('span');
alert('LEN: ' + elements.length);
for(var i = 0; i < elements.length; i ++) {
       if(elements[i].className === 'label-text')
            alert('found!');
            alert(elements[i]);
            elements[i].setAttribute('title', 'BLAHBLAH');

        }
 }

alert(el.innerHTML);

Check active flag in client script


Display business rule:

(function executeRule(current, previous /*null when async*/) {

    // --RDS Feb2018 chg enhancements
    //-- set scratchpad(s) which can then be used in client scripting/UI Policy scripts
    g_scratchpad.chg_active=current.active;

})(current, previous);


Client script:

alert(g_scratchpad.chg_active); 
//--seems to save scratchpad as a string, hence use:
if(g_scratchpad.chg_active=='true'){

}



AJAX scripting

AJAX call example 1: return multiple values:

Client script code:

//--author: RDS Feb 2018
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        // return;
    }
    //--default the line manager and job title from requested for field
    g_form.setValue('job_title', '');
    g_form.setValue('line_manager', '');
    if (newValue!=''){
        var ga = new GlideAjax('my_ajax_funcs_sc');
        ga.addParam('sysparm_name', 'mab_getuserinfo');
        ga.addParam('sysparm_usersysid', newValue);
            ga.getXML(function(serverResponse){
              var result = serverResponse.responseXML.getElementsByTagName("result");
              var message = result[0].getAttribute("message");
              //alert(message);
              //--get favorite elements
              var favorites = serverResponse.responseXML.getElementsByTagName("favorite");
              for(var i = 0; i < favorites.length; i++) {
                  var name = favorites[i].getAttribute("name");
                  var value = favorites[i].getAttribute("value");
              }

        });
    }
}

Script include script (client callable):


var my_ajax_funcs_sc = Class.create();
my_ajax_funcs_sc.prototype = Object.extendsObject(AbstractAjaxProcessor, {
   
    mab_getuserinfo: function(){
        //--
        var userSYSID=this.getParameter('sysparm_usersysid');
        var sResult1='';
        var sResult2='';
        var result = this.newItem("result");
        result.setAttribute("message", "returning all favorites");
        //...complete the code...
        this._addFavorite('result1', sResult1);
        this._addFavorite('result2', sResult2);
        return sReturn;
    },

    _addFavorite : function(name, value) {
        var favs = this.newItem("favorite");
        favs.setAttribute("name", name);
        favs.setAttribute("value", value);
    },

    type: 'my_ajax_funcs_sc'
});

AJAX call example 2: return single value:

Client script code:


var ga = new GlideAjax('my_date_funcs');

ga.addParam('sysparm_name','my_getDateNow');

ga.getXMLAnswer(function(answer) {

        alert(answer);

 });

Script include script (client callable):


var my_date_funcs= Class.create();

my_date_funcs.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    my_getDateNow: function (){

        return (gs.now());  

    },

    type: "my_date_funcs"

});


AJAX call example 3: wait for result (synchronous):


this kind of defeats the purpose of AJAX. but in certain cases might be justified, for example if you wish to prevent a submit via an onsubmit client script if a certain value is returned

Client script code:


var ga = new GlideAjax('AjaxProjectTaskUtil');
ga.addParam('sysparm_name','getProjectStartToTaskEndDuration');

ga.addParam('sysparm_task_start_date',g_form.getValue('start_date'));
ga.addParam('sysparm_end_date',g_form.getValue('end_date'));
ga.getXMLWait();
var setEndDate = ga.getAnswer();


note: getXMLWait() does not work in Service Portal, use getXMLAnswer()


Script include script (client callable):


similar to example 2

AJAX call example 4: xmlwait returning multiple values (synchronous)


ga.getXMLWait();

           

 var result = ga.requestObject.responseXML.getElementsByTagName("result");
               
 var message = result[0].getAttribute("message");           
 var favorites = ga.requestObject.responseXML.getElementsByTagName("favorite");

note: getXMLWait() does not work in Service Portal, use getXMLAnswer()

Hide/show related lists

locate the related list ID under 'system UI > related lists'
then use script as below:

show:
function onCondition() {
   
    g_form.showRelatedList('u_task_vendors.u_task');
}
hide:
function onCondition() {
   
    g_form.hideRelatedList('u_task_vendors.u_task');
}



Order Guide Scripting

Get order guide sys id in the catalog item client script, and

how to tell in catalog item scripts if part of an order guide or standalone

non-portal

note: below does not work in service portal


alert(gel('sysparm_guide').value);


[top.location will be nav_to.do?uri=%2Fcom.glideapp.servicecatalog_cat_item_guide_view.do%3Fsysparm_guide%3D7d292af7371c57008ca1138943990e7d%26sysparm_active%3D5ec78e0237a0db008ca1138943990e63 ]

for service portal

[ top.location will be https://<instance url>/sp?id=sc_cat_item_guide&sys_id=7d292af7371c57008ca1138943990e7d ]

var res_orderguide=getP();
if (res_orderguide ){
        //--form is part of order guide
        g_form.setReadOnly('line_manager', true);
        g_form.setReadOnly('requested_for', true);
        g_form.setReadOnly('job_title', true);
       
    }

function getP(){
    var isPartOfGuide=false;
    try{
        var urlString=top.location.toString();
        //return urlString;
        if(urlString.indexOf('sc_cat_item_guide')>-1){
            //--service portal view
            isPartOfGuide=true;
        }
        if(urlString.indexOf('sysparm_guide')>-1){
            //--standard servicenow view
            isPartOfGuide=true;
        }
       
        alert(getPVal('sc_cat_item_guide'));//--to get order guide ID--portal friendly
        alert(getPVal('sysparm_guide'));//--to get order guide ID--non portal friendly
    }catch (ex){
        //alert('err');
    }
    return (isPartOfGuide);
}

function getPVal (name){
    var parms = decodeURI(location.search).split("&").map(makeParmObjList);
    if(parms){
        parms.forEach(function(item){
            //alert(item.field);
            //alert(item.value);
        });
    }
   
    function makeParmObjList(item){
        var keyPair = item.split('=');
        return {field: keyPair[0], value: keyPair[1]};
        }
        //--courtesy of
        //--https://community.servicenow.com/community?id=community_blog&sys_id=ec3eea6ddbd0dbc01dcaf3231f9619d6&view_source=searchResult
        //--https://www.servicenowguru.com/scripting/client-scripts-scripting/parse-url-parameters-client-script/

    }
}
courtesy of:
//https://community.servicenow.com/community/develop/blog/2016/11/04/adventures-in-service-portaling-populate-catalog-variable-values-through-the-url

//https://www.servicenowguru.com/scripting/client-scripts-scripting/parse-url-parameters-client-script/


Date Validation example 1 - simple date vetting: date2>date1

client scripting:
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
   
    //--delivery date should not be > engineer date
    if (g_form.getValue('retail_delivery_date')!=''){
       validate_retail_dates(g_form.getValue('retail_delivery_date'),newValue);
    }
}

function validate_retail_dates(date1, date2){
    var ga=new GlideAjax('ajax_funcs_sc');//--the AJAX script include name
    ga.addParam('sysparm_name', 'validate_dates');
    ga.addParam('sysparm_date1', date1);
    ga.addParam('sysparm_date2', date2);
    ga.getXMLAnswer(function(answer) {
        if (answer=='false'){
            alert('Delivery date is after the engineer date');
            g_form.setValue('retail_engineer_date', '');
        }
    });
}

AJAX scripting:
validate_dates: function(){
        //--validate that end date 2 >= date 1
        //--called from catalog client scripts
        //--returns 'true' if the dates are valid
        var date1=new GlideDateTime();
        var date2=new GlideDateTime();
    date1.setDisplayValue(this.getParameter('sysparm_date1'));
    date2.setDisplayValue(this.getParameter('sysparm_date2'));
        var sReturn=(date2>=date1).toString();
        return sReturn;
},

Date Validation example 2 - check that date entered within certain amount of hours

client scripting:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '') {
        return;
    }
    if (newValue<g_form.getValue('end_date')){
        alert('Date entered is before the end date');
        g_form.setValue('start_date', '');
        return false;
    }else{
        var chgType=g_form.getValue('type');
        //--RDS feb2018 chg enhancements: now validate normal change > 36 hours
        if (chgType=='Normal' || chgType=='Emergency'){
           
            var ga = new GlideAjax('misc_funcs');
            if (chgType=='Emergency'){
                ga.addParam('sysparm_name', 'validateDateTime_chgStartDate_E');
            }else{
                ga.addParam('sysparm_name', 'validateDateTime_chgStartDate');
            }
            ga.addParam('sysparm_date_entered', newValue);
            ga.getXMLAnswer(function(answer) {
                //alert('TEST:' + answer);
                if (answer=="true" && chgType=='Normal'){
                    alert('Date entered is <36 hours from now');
                    g_form.setValue('start_date', '');
                    g_form.setValue('end_date', '');
                    return false;
                }
                if (answer!="true" && chgType=='Emergency'){
                    alert('Date entered is >36 hours from now');
                    g_form.setValue('start_date', '');
                    g_form.setValue('end_date', '');
                    return false;
                }
            });
           
            //--check if day entered in the past, if so is it acceptable?
            var ga2 = new GlideAjax('misc_funcs');
            ga2.addParam('sysparm_name', 'validateDateTimes');
            ga2.addParam('sysparm_date_entered', newValue);
            ga2.getXMLAnswer(function(answer) {
                if (answer=="true" ){
                    var resp=confirm('Note: you have entered a day in the past');
                    if (!resp){
                        g_form.setValue('start_date', '');
                        return false;
                    }
                }
            });
        }
    }
}

AJAX scripting:
validateDates: function(){
        //--verify that a date entered is not a day in the past.
        //--function will return "true" if a date is NOT VALID / in the past
        var dateNow=new GlideDate();
        var dateEntered=new GlideDate();
    dateEntered.setDisplayValue(this.getParameter('sysparm_date_entered'));
        var sReturn=(dateEntered<dateNow).toString();
        return sReturn;
    },
   
    validateDateTimes: function(){
        //--verify that a date entered is not a day in the past.
        //--function will return "true" if a date is NOT VALID / in the past
        var dateNow=new GlideDateTime();
        var dateEntered=new GlideDateTime();
    dateEntered.setDisplayValue(this.getParameter('sysparm_date_entered'));
        var gtime_05 = new GlideTime();
gtime_05.setValue("00:05:05"); //--allow for a few minutes
dateEntered.add(gtime_05); 
        var sReturn=(dateEntered<dateNow).toString();
        return sReturn;
    },
   
    validateDateTime_chgStartDate: function(){
        //--verify that a date entered is not <36 hours (normal change).
        //--function will return "true" if a date is NOT VALID
        var dateNow=new GlideDateTime();
        var gtime_36 = new GlideTime();
        gtime_36.setValue("36:00:00");
        dateNow.add(gtime_36);
       
        var dateEntered=new GlideDateTime();
    dateEntered.setDisplayValue(this.getParameter('sysparm_date_entered'));
        var sReturn=(dateEntered<dateNow).toString();
        return sReturn;
    },
   
    validateDateTime_chgStartDate_E: function(){
        //--verify that a date entered is <=36 hours (Emergency change).
        //--function will return "true" if a date is NOT VALID
        var dateNow=new GlideDateTime();
        var gtime_36 = new GlideTime();
        gtime_36.setValue("36:00:00");
        dateNow.add(gtime_36);
       
        var dateEntered=new GlideDateTime();
    dateEntered.setDisplayValue(this.getParameter('sysparm_date_entered'));
        var sReturn=(dateEntered<=dateNow).toString();
        return sReturn;
    },

Service Catalog 

form  sys_ids

//--Cat item id:
gel('sysparm_id').value;

//--Actual form id:
gel('sysparm_item_guid').value);

and for Service Portal friendly versions:

//--Cat item id:
itemID= g_form.getSysId();

Service Catalog: variable advanced reference qualifiers

Call a script include to apply a reference qualifier on a catalog item variable:
- variable reference qualifier dependent on another variable selection, in this case a variable referencing sys_user (requested_for)
On the catalog item form.

variable name to apply ref qual filter:
retail_equipment

variable reference qualifier (on cmdb table):
javascript: new refqual_functions().lostStolen_getAssignedCIs();

client-callable script include (refqual_functions) function:

lostStolen_getAssignedCIs: function(){
        //--called from variable set client script, for lost/stolen request (service catalog)
    gs.log(current.variables.requested_for,'retail_lostStolen_getAssignedCIs');
        return ('install_statusNOT IN8,7^owned_by='+current.variables.requested_for);
       
    //owned_by=1269b79937f1060041c5616043990e41^install_statusNOT IN8,7
       
  },



Service Catalog: change a catalog item variable labels

function onLoad() {
    //shared functions for form load
    var label='Select site';
    var labelElement = $('label_' + g_form.getControl('requested_for').id);
    labelElement.select('.sn-tooltip-basic').each(function(elmt) {
        elmt.innerHTML = label;
    });
}




Comments

  1. Hi Ruen any tips on how to convert Single Line Texts with Numeric Validation to Numeric type in client script?

    ReplyDelete
    Replies
    1. Ah ok sorry ignore me I was using Number() when I needed parseint(string, radix)

      Delete
    2. Cool Gareth, glad you cracked it!

      Delete
  2. Yeah thanks for having such an inspirational blog too 👍

    ReplyDelete

Post a Comment

Popular posts from this blog

ServiceNow check for null or nil or empty (or not)

Haven't tested these all recently within global/local scopes, so feel free to have a play! option 1 use an encoded query embedded in the GlideRecord , e.g.  var grProf = new GlideRecord ( 'x_cls_clear_skye_i_profile' ); grProf . addQuery ( 'status=1^ owner=NULL ' ); grProf . query (); even better use the glideRecord  addNotNullQuery or addNullQuery option 2 JSUtil.nil / notNil (this might be the most powerful. See this link ) example: if ( current . operation () == 'insert' && JSUtil . notNil ( current . parent ) && ! current . work_effort . nil ())  option 3 there might be times when you need to get inside the GlideRecord and perform the check there, for example if the code goes down 2 optional routes depending on null / not null can use gs.nil : var grAppr = new GlideRecord ( 'sysapproval_approver' ); var grUser = new GlideRecord ( 'sys_user' ); if ( grUser . get ( 'sys_id' , current . approver )){...

Get URL Parameter - server side script (portal or classic UI)

Classic UI : var sURL_editparam = gs . action . getGlideURI (). getMap (). get ( ' sysparm_aparameter ' ); if ( sURL_editparam == 'true' ) { gs . addInfoMessage ( 'parameter passed ); } Portal : var sURL_editparam = $sp . getParameter ( " sysparm_aparameter " ); if ( sURL_editparam == 'true' ) { gs . addInfoMessage ( 'parameter passed ); }

Code a pause/wait - gs.sleep or gs.wait alternative, pause script for specified seconds (timer)

Code a pause/wait - gs.sleep / gs.wait alternative, pause script for specified seconds (timer)  e.g. 10 seconds: do_sleep ( 10000 ); function do_sleep ( milliseconds ) { var start = new Date (). getTime (); for ( var i = 0 ; i < 1e7 ; i ++) { if (( new Date (). getTime () - start ) > milliseconds ){ gs . print ( 'waking up!' ); break ; } } }