Popup for cancel confirmation not working

Roshini
Tera Guru

I am trying to create a UI Action with name 'Cancel RITM', which will be asking for reason for cancellation, and cancel /Ok button. Once Ok is clicked, it will verify if there is some value or not, if no value it will give an info message and won't allow to proceed further, If value is there it will allow to make the RITM closed incomplete( value =4) and update the work notes with "Cancelled: " + cancel comments.

Below is the UI action and Ui page am trying, but it is not working as expected, am not getting any error.
Just the OK button is not validating anything and updating anything. It is redirecting to "ui_page_process" page with UI action sys id.


Ui action



function cancelRITM()
{
    var dialog = new GlideDialogWindow ('cancel_reason_dialog');
    dialog.setTitle('Cancellation Reason');
    dialog.setSize(750, 300);
    dialog.setPreference('sys_id', g_form.getUniqueValue()); // Pass current record ID
    dialog.render();
   
}


Ui page
HTML
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
    <g:ui_form>
        <!-- Capture current record ID passed from UI Action -->
        <input type="hidden" name="sys_id" value="${RP.getWindowProperties().get('sys_id')}" />
       
        <table width="100%">
            <tr>
                <td>
                <p>Please provide a reason for cancellation:</p>
                    <textarea id="cancel_comments" name="cancel_comments" rows="4" style="width:100%"></textarea>
                </td>
            </tr>
            <tr id="dialog_buttons">
                <td align="right">
                    <!-- UI Macro for standard OK/Cancel buttons -->
 <g:dialog_buttons_ok_cancel ok="validateReason()" ok_type="submit"
                                            cancel="cancelDialog()" cancel_type="button"/>

                </td>
            </tr>
        </table>
    </g:ui_form>
</j:jelly>



Client script
function validateReason() {
    var reason = gel('cancel_comments').value.trim();
    if (reason == "") {
        alert("Cancellation reason is mandatory.");
        return false; // Blocks submission
    }
    return true; // ALLOWS submission to Processing Script
}

function cancelDialog() {
    GlideDialogWindow.get().destroy();
    return false;
}


Processing script


    var gr = new GlideRecord('sc_req_item'); // Or your target table
    if (gr.get(sys_id)) {

        gs.info("@ro inside 1")
        gr.state = 4; // 'Cancelled' state
       // gr.close_notes = "Cancelled: " + cancel_comments;
        gr.update();
       
        // Redirect back to the form or list
        response.sendRedirect("sc_req_item.do?sys_id=" + sys_id);
    }
10 REPLIES 10

Naveen20
ServiceNow Employee

The journal field assignment method and potentially the textarea value not posting cleanly. Here's what to fix:

1. Processing Script — use setValue() for journal fields:

Journal fields like work_notes don't reliably accept direct assignment in all contexts. Replace the direct assignment:

var sysId = RP.getParameterValue('sys_id');
var cancelComments = RP.getParameterValue('cancel_comments');

// Debug: check what's actually coming through
gs.info("Cancel RITM - sys_id: " + sysId);
gs.info("Cancel RITM - comments: " + cancelComments);

var gr = new GlideRecord('sc_req_item');
if (gr.get(sysId)) {
    gr.setValue('state', 4);
    gr.setValue('work_notes', 'Cancelled: ' + cancelComments);
    gr.update();
}

response.sendRedirect("sc_req_item.do?sys_id=" + sysId);

2. Client Script — copy the textarea into a hidden input before submitting:

Textarea values can sometimes get lost during form POST in UI Pages. The safest approach is to relay the value through a hidden input:

Update the HTML to add a hidden field:

<input type="hidden" name="sys_id" value="${RP.getWindowProperties().get('sys_id')}" />
<input type="hidden" id="hidden_comments" name="cancel_comments" value="" />

Then remove the name attribute from the textarea so only the hidden field posts:

<textarea id="cancel_comments" rows="4" style="width:100%"></textarea>

And update the client script to copy the value before submitting:

function validateAndSubmit() {
    var reason = gel('cancel_comments').value.trim();
    if (reason === "") {
        alert("Cancellation reason is mandatory.");
        return false;
    }
    // Copy textarea value into the hidden input before submit
    gel('hidden_comments').value = reason;
    document.forms[0].submit();
    return false;
}

The gs.info lines in the processing script will log to the system log, so you can check System Logs > System Log > All to confirm whether the values are actually arriving. If cancel_comments shows as null or empty there, it confirms the textarea POST issue. The hidden input relay approach is the standard workaround for this in ServiceNow UI Pages.

pr8172510
Giga Guru

 

Hi Roshini,

I tried your approach and was able to fix the OK button issue  (it was due to missing return in the dialog button / submission handling).

However, I’m still facing an issue with the record update part:


 Current Behavior

  • Popup opens correctly 
  • Validation works (empty reason is blocked) 
  • On clicking OK → dialog closes 

 But:

 

 
State → NOT changing 
Stage → NOT updating 
Work notes → NOT getting updated 
 

 

 What I Observed

Even though the processing script runs, the RITM remains:

 

 
State = Open
Stage = Waiting for Approval
 

Looks like something is overriding or blocking the update.


function cancelRITM() {

 

    var dialog = new GlideDialogWindow('cancel_reason_dialog');

    dialog.setTitle('Cancellation Reason');

    dialog.setSize(600, 300);

 

    dialog.setPreference('sys_id', g_form.getUniqueValue());

 

    dialog.render();

}



<?xml version="1.0" encoding="utf-8" ?>

<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide">

 

<g:ui_form method="post" action="cancel_reason_dialog.do">

 

    <input type="hidden" name="sysparm_name" value="cancel_ritm" />

    <input type="hidden" name="sys_id" value="${RP.getWindowProperties().get('sys_id')}" />

 

    <table width="100%">

        <tr>

            <td>

                <p>Please provide a reason for cancellation:</p>

                <textarea id="cancel_comments" name="cancel_comments" rows="4" style="width:100%"></textarea>

            </td>

        </tr>

 

        <tr>

            <td align="right">

                <button type="button" onclick="submitForm()">OK</button>

                <button type="button" onclick="cancelDialog()">Cancel</button>

            </td>

        </tr>

    </table>

 

</g:ui_form>

 

</j:jelly>





function submitForm() {

 

    var reason = gel('cancel_comments').value;

 

    if (!reason || reason.trim() == "") {

        alert("Cancellation reason is mandatory.");

        return false;

    }

 

    document.forms[0].submit();

}

 

function cancelDialog() {

    GlideDialogWindow.get().destroy();

    return false;

}




if (request.getParameter('sysparm_name') == 'cancel_ritm') {

 

    var sys_id = request.getParameter('sys_id');

    var cancel_comments = request.getParameter('cancel_comments');

 

    var gr = new GlideRecord('sc_req_item');

 

    if (gr.get(sys_id)) {

 

        if (!cancel_comments || cancel_comments.trim() == "") {

 

            gs.addErrorMessage("Cancellation reason is mandatory.");

            response.sendRedirect("cancel_reason_dialog.do?sys_id=" + sys_id);

 

        } else {

 

            gr.state = 4; // Closed Incomplete

            gr.work_notes = "Cancelled: " + cancel_comments;

            gr.update();

 

            gs.addInfoMessage("RITM cancelled successfully");

 

            response.sendRedirect("sc_req_item.do?sys_id=" + sys_id);

        }

    }

}

Screenshot 2026-04-13 183722.pngScreenshot 2026-04-13 183820.png


am not seeing the processing script running, am not getting any logs

Ankur Bawiskar
Tera Patron

@Roshini 

why not use javascript prompt box where user can enter the reason?

Grab it and update the record

no need of UI page

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  10x ServiceNow MVP  ||  ServiceNow Community Leader

Can you please help me the code
I thought of below
UI action script

function promptForReason() {
var reason = prompt("Please enter the reason for this update:");
if (reason) {
var ga = new GlideAjax('RecordUpdateHandler');
ga.addParam('sysparm_name', 'updateReason');
ga.addParam('sysparm_id', g_form.getUniqueValue());
ga.addParam('sysparm_reason', reason);
ga.getXMLAnswer(function(response) {
if (response === 'success') {
g_form.addInfoMessage('Updated successfully.');
g_form.refresh();
}
});
}
}

Script include

var RecordUpdateHandler = Class.create();
RecordUpdateHandler.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    updateReason: function() {
        var gr = new GlideRecord('incident');
        if (gr.get(this.getParameter('sysparm_id'))) {
            gr.work_notes = "Reason: " + this.getParameter('sysparm_reason');
            gr.update();
            return 'success';
        }
        return 'error';
    }
});
But am not able to save the Ui action script.