Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

On Change Script having problems setting a Date Time field for a Catalog Item variable

WarrenB
Tera Expert

I have a requirement to set a Date/Time field in a catalog item based on the Create Date of an associated record.

1.  User chooses an Incident in a reference field.

2.  On change script runs that populates the Date/Time field "Incident Created" with the Created date/time from the incident.

Problem.  Unless the user has chosen the YYYY-MM-DD format in their user profile, the date brought over will not be accepted by the system.  So, the created date time field on the Incident is in the following format:  2022-09-12 20:41:24.  When you choose the incident number, it comes over looking like this:  2022-09-12 20:41:24 (looks the same doesn't it!), but when you try  to submit, you get:  "Error Message The following fields contain invalid value: Incident Number Date/Time"!

Now, here's the strange part.  If I use the date picker for the date field, it looks like this:  09-12-2022 20:41:24...  It's very aggravating because it seems to be so tied to the user's date preference.  It should be agnostic!

This is the script I am using:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

    //Type appropriate comment here, and begin script below
    var gr = g_form.getReference('incident_number');
    g_form.setValue('incident_created', gr.sys_created_on);
}

Any help would be greatly appreciated.  Javascripting gives me a great big headache!

Thanks in advance!

1 ACCEPTED SOLUTION

Brad Bowman
Kilo Patron
Kilo Patron

Hi Warren,

This struggle is one of the reasons you almost always need a server script to manipulate or even fetch a date/time value.  The key is that you can return the displayValue to the client script, which is what it needs to populate a field or variable correctly.  So your Client Script should look more like this:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

	var ajax = new GlideAjax('DateTimeUtils'); //name of a Script Include
	ajax.addParam('sysparm_name', 'incDateTime'); //name of a function in this Script Include
	ajax.addParam('sysparm_inc', newValue); 	
	ajax.getXML(getDate);

	function getDate(response){
		var answer = response.responseXML.documentElement.getAttribute("answer");
		g_form.setValue('incident_created', answer);
	}
}

Next create a Script Include using the same name as in the GA call.  Ensure the Client callable box is checked.  Your SI will look similar to this:

var DateTimeUtils = Class.create();
DateTimeUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	incDateTime: function () {
		var inc = this.getParameter('sysparm_inc');
		var incDT = new GlideDateTime(gs.nowDateTime());
		var incGR = new GlideRecord('incident');
		if(incGR.get(inc)) {
			incDT = incGR.sys_created_on;
		}
		return incDT.getDisplayValue();
	},
	  
    type: 'DateTimeUtils'
});

Incidentally, getReference is still supported, but usually not considered best practice due to the fact that it returns the entire record from the server, when you usually only need one or a few fields.  If you are going to use it, you must always include a callback function to lessen the impact and prevent possible problems.  So your Client Script would look more like this:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

    var gr = g_form.getReference('incident_number', incInfo);
    function incInfo(gr) {
        g_form.setValue('incident_created', gr.sys_created_on);
    }
}

 

View solution in original post

3 REPLIES 3

Brad Bowman
Kilo Patron
Kilo Patron

Hi Warren,

This struggle is one of the reasons you almost always need a server script to manipulate or even fetch a date/time value.  The key is that you can return the displayValue to the client script, which is what it needs to populate a field or variable correctly.  So your Client Script should look more like this:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

	var ajax = new GlideAjax('DateTimeUtils'); //name of a Script Include
	ajax.addParam('sysparm_name', 'incDateTime'); //name of a function in this Script Include
	ajax.addParam('sysparm_inc', newValue); 	
	ajax.getXML(getDate);

	function getDate(response){
		var answer = response.responseXML.documentElement.getAttribute("answer");
		g_form.setValue('incident_created', answer);
	}
}

Next create a Script Include using the same name as in the GA call.  Ensure the Client callable box is checked.  Your SI will look similar to this:

var DateTimeUtils = Class.create();
DateTimeUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	incDateTime: function () {
		var inc = this.getParameter('sysparm_inc');
		var incDT = new GlideDateTime(gs.nowDateTime());
		var incGR = new GlideRecord('incident');
		if(incGR.get(inc)) {
			incDT = incGR.sys_created_on;
		}
		return incDT.getDisplayValue();
	},
	  
    type: 'DateTimeUtils'
});

Incidentally, getReference is still supported, but usually not considered best practice due to the fact that it returns the entire record from the server, when you usually only need one or a few fields.  If you are going to use it, you must always include a callback function to lessen the impact and prevent possible problems.  So your Client Script would look more like this:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

    var gr = g_form.getReference('incident_number', incInfo);
    function incInfo(gr) {
        g_form.setValue('incident_created', gr.sys_created_on);
    }
}

 

Brad,

Thank you so much!  Worked like a charm regardless of what the user's date preference is.  I really appreciate it.

Warren

You are welcome!