Save sc_task record with incomplete mandatory fields | getElementById failing

Evan McElfresh
Giga Guru

I have been struggling with this for a few months now. I set it aside for some time and now I am revisiting and hoping the community can help me get to a resolution.

 

For reference, I am starting with the solution in this thread. However, when I execute this function, I get a NULL response from the variable_map element and the script fails.

Below is my current UI Action settings and script, the HTML div, and the console error output I receive:

EvanMcElfresh_0-1740674049664.png

 

 

//Client-side 'onclick' function
function u_saveRecordClient() {
    //ignore mandatory fields
    var state = g_form.getValue('state');

    console.log("UI Action details | State: " + state);

    //we can save without filling in all mandatory fields and variables if the task is not closed or closing
    if (g_form.getValue('state') != 3) {
        console.log("UI Action details | If statement 1 reached: TRUE");
        g_form.checkMandatory = false; //ignore mandatory fields
        try {
            console.log("Trying to get allVariables");

            //now ignore any mandatory variables
            var allVariables = document.getElementById('variable_map').getElementsByTagName('item');
            console.log("UI Action details | allVariables: " + allVariables);

            for (var i = 0; i < allVariables.length; i++) {
                var item = allVariables[i];
                g_form.setMandatory('variables.' + item.getAttribute('qname').toString(), false);
            }
        } catch (err) {
            console.log("Encountered error: " + err);
        }
    }

    //Call the UI Action and skip the 'onclick' function
    //this will execute the code below
    gsftSubmit(null, g_form.getFormElement(), 'sysverb_update_and_stay'); //MUST call the 'Action name' set in this UI Action
}

//Code that runs on the server, without 'onclick'
//Ensure call to server-side function with no browser errors
if (typeof window == 'undefined')
    u_saveRecordServer();

function u_saveRecordServer() {
    action.setRedirectURL(current); //come back to the same record
    current.update();
}

 

 

EvanMcElfresh_0-1740673762832.png

 

 

 

<div id="variable_map" style="visibility:hidden;display:none">
    <item qname="service_provider" id="57d6447a87120610d851c259dabb351e"></item>
    <item qname="etf" id="b43ed07a87920610d851c259dabb35cd"></item>
    <item qname="lte" id="235ed87a87920610d851c259dabb35eb"></item>
    <item qname="device_details" id="3c9f85228716c210d851c259dabb3548"></item>
    <item qname="cost_center" id="f1de54ba87920610d851c259dabb35bc"></item>
</div>

 

 

 

Encountered error: TypeError: Cannot read properties of null (reading 'getElementById')

 

 @Steven Parker and @Jim Coyne have been very involved in this topic.

@Brad Bowman  for visibility 

Please mark this response as correct and/or helpful if it assisted you with your question.
1 ACCEPTED SOLUTION

Chaitanya ILCR
Kilo Patron

Hi @Evan McElfresh ,

try setting Isolate Script of UI action to false

ChaitanyaILCR_0-1740677960500.png

 

Please mark my answer as helpful/correct if it resolves your query.

Regards,
Chaitanya

View solution in original post

11 REPLIES 11

Chaitanya ILCR
Kilo Patron

Hi @Evan McElfresh ,

try setting Isolate Script of UI action to false

ChaitanyaILCR_0-1740677960500.png

 

Please mark my answer as helpful/correct if it resolves your query.

Regards,
Chaitanya

Thank you. That at least gave me a different error...

 

I now get this output in the Console:

UI Action details | allVariables: [object HTMLCollection]

And I get a ServiceNow error message on the sc_task record:

Error MessageonSubmit script error: TypeError: Cannot read properties of null (reading 'getElementById'):
function () { [native code] }

 

Please mark this response as correct and/or helpful if it assisted you with your question.

Hi @Evan McElfresh ,

if you have any onSubmit client script where you are using DOM 

do that same thing with it 

Find the client script and set Isolate Script to false

 

Please mark my answer as helpful/correct if it resolves your query.

Regards,
Chaitanya

For anyone looking for the solution to allow saving, but not closure of a task in Service Operations Workspace, I set up a Catalog Client Script on the specific catalog item in question, and this was is the script I used:

edit: Added a check to see if any of the variables in the forEach loop were not visible and skipped them.

edit 2: Removed the "isVisible" check as it doesn't work with Classic UI. This new  method simply checks the sc_task short description and decides which variables to include in the mandatory check.

 

 

 

function onSubmit() {
    if (g_form.getValue('state') == 3) { //Closed Complete

		// Initialize mandatory variables array
		var mandVars = [];

		// Set mandatory variables based on task short description
		var sd = g_form.getValue('short_description');
		var computer = false;
		if (g_form.getValue('device_details') == 'computer') {
			computer = true;
		}

		// Choose what variables to add to the array
		switch (sd) {
			case 'Specify device and order details':
				mandVars.push('cost_center');
				if (!computer) {
					mandVars.push('etf', 'lte', 'service_provider');
				}
				break;
			case 'Create Jira purchase order request':
				mandVars.push('cost_center', 'delivery_date', 'jira_itpo');
				break;
			case 'Order device':
				mandVars.push('cost_center');
				if (!computer) {
					mandVars.push('service_provider');
				}
				break;
			case 'Receive device':
				mandVars.push('asset_tag', 'serial_number');
				if (!computer) {
					mandVars.push('asset_tag', 'serial_number', 'imei', 'phone_number');
				}
				break;
		}

		// Set initial script variables
		var stopSubmit = false;

		// Loop through each catalog variable
		mandVars.forEach(function(name){
			try {
				g_form.setMandatory(name, true); // Set as mandatory
				var value = g_form.getValue(name); // Get variable value
				if (value.trim() === '' || !value) { // If the variable is empty, flag the submission
					stopSubmit = true;
				}
			} catch (err) {}
		});

		// If any mandatory variable is empty, stop submit, and notify the user what to do next if submission denied
		if (stopSubmit) {
			g_form.addErrorMessage('Complete required fields before closing. Saving is allowed, but will require a page refresh first.');
			return false;
		}
    }
}

 

 

 

 

Thank you @Brad Bowman  for the direction to use this type of method for SOW.

Please mark this response as correct and/or helpful if it assisted you with your question.