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.

How can we add action button for RITM(Requests) on ESC

ayushmaan_b
Tera Contributor

Hi Team,

We have a requirement to add ' Action ' drop down on ESC page for the " My requests" records when opened by the caller . The expected actions drop down options are " Reopen, Cancel '.

 

We have earlier done this sort of customization for incidents (as attached) and now the requirement is to implement the same for RITM.

 

While doing it for incidents it was easy as we found existing widgets like ' Incident Standard Ticket Actions' and its related existing SNC script includes. However, for RITM these are not present to use so what do you suggest here?

 

Thanks

2 ACCEPTED SOLUTIONS

@ayushmaan_b 

did you check the link I shared above?

try to use that as reference point and using an AI tool like Co-pilot etc you should be ready with the code but you will have to make some changes on your own as well.

If my response helped please mark it correct and close the thread so that it benefits future readers.

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

View solution in original post

Hi @ayushmaan_b ,

I'll use the Incident Standard Ticket Action widget and modify some of the basics. However, you will need to make the necessary modifications if the basics don't meet your process needs. I put in comments to help guide you to understand what is going on in the code.

 

HTML Markup

<div>
    <!-- The following div element nests the components that this drop down is made of. ng-if is an attribute that decides whether or not to
     render the actions or not. It looks for a true or false value. data.showActions is determined in the server script-->
    <div class="dropdown" id="child-case-tabs" ng-if="data.showActions">
        <button type="button" id="actions-button" class="btn btn-default dropdown-toggle action-btn" data-toggle="dropdown" style="width : 100%" aria-haspopup="true" ng-init="setFocusOnActionButtons()">
            ${Actions}
            <span class="fa fa-caret-down"></span>
        </button>

        <!--Remove "li" elements not needed. Change the text where needed-->
        <ul class="dropdown-menu pull-right" id="actionList">
            <li>                            <!-- you can see the name modifications here to reflect the requirement-->
                <a href="javascript&colon;void(0)" ng-click="$event.stopPropagation();reopenRITM()">${Reopen}</a>
            </li>
            <li>                            <!-- you can see the name modifications here to reflect the requirement-->
                <a href="javascript&colon;void(0)" ng-click="$event.stopPropagation();cancelRITM()">${Cancel}</a>
            </li>
        </ul>
    </div>
  
</div>

 

Server Script

(function() {
	//Setting up the GlideRecord Query
    var scReqItemGr = new GlideRecord('sc_req_item');

	//In this widget the sys_id can be set by the options
	var scReqItemSysId = options.sys_id;
	
	if (!scReqItemSysId && $sp.getParameter('table') == 'sc_req_item'){
		//Or the sys_id can be set from a URL parameter called sys_id
		scReqItemSysId = $sp.getParameter('sys_id');
	}
	
	
	/* Actions - Start */
	//If there is an input object, the client side sent something , in this case it's checking if it's to reopen the item
	if (input && input.action == 'reopenRITM' && scReqItemGr.get(scReqItemSysId) && hasPermissions(scReqItemGr, "write")) {
        scReqItemGr.state = 2;
		data.isRITMReopened = scReqItemGr.update();
		gs.addInfoMessage(gs.getMessage("RITM reopened"));
    }
	
	//If there is an input object, the client side sent something , in this case it's checking if it's to cancel the item
	if (input && input.action == 'cancelRITM' && scReqItemGr.get(scReqItemSysId) && hasPermissions(scReqItemGr, "write")) {
		scReqItemGr.state = 7; //OOB there is no cancel. so here is Closed Skipped
		data.isRITMClosed = scReqItemGr.update();
		gs.addInfoMessage(gs.getMessage("RITM Cancelled"));

    }

   /* Actions - End */
	
	/* Load RITM data */
	//decide to show the Actions dropdown
	//If there is an Item and the user has permissions 
    if (scReqItemGr.get(scReqItemSysId) && hasPermissions(scReqItemGr)) {

		//If the item is in either the Closed, Closed Incomplete, or Closed Skipped state they can Reopen
        data.canReopen = "3,4,7".includes(scReqItemGr.state);

		//If the item is in either Pending, Open or Work In Progress, the user can Cancel
        data.canCancel = "1,2,-5".includes(scReqItemGr.state);
		

		//If either are true display the actions dropdown
        data.showActions = data.canReopen || data.canClose;
    }

	//The naming conventiion here is very self explanatory
    function hasPermissions(gr, operation) {
        if (operation == "read" && gr.canRead())
            return true;

        if (operation == "write" && gr.canWrite())
            return true;

		//checks if the logged in user is the requested_for or opened_by
        return (gr.getValue("requested_for") == gs.getUserID()) || (gr.getValue("opened_by") == gs.getUserID());
    }
    data.i18n = {};

})();

 

Client Controller

 

function RitmTicketActions($scope, $http, spUtil, $timeout, spModal, i18n, $window, $uibModal, spAriaUtil) {
    /* widget controller */
    var c = this;
    c.doneLoading = false;
    c.closedRITMMsg = "${Closed RITM}";
    c.reopenedRITMMsg = "${Reopened RITM}";

    var MOBILE_DEVICE_SCREEN_WIDTH = 767;
    $scope.mobileDevice = c.data.isMobile || ($window.innerWidth < MOBILE_DEVICE_SCREEN_WIDTH);
	
	//executes when the Cancel option is clicked and sends to the server side
	$scope.cancelRITM = function() {
		$scope.data.action = 'cancelRITM';
        $scope.server.update(init).then(function(response){
					if (response.isRITMClosed)
						spAriaUtil.sendLiveMessage(c.closedRITMMsg);
				});
		var elm = document.getElementById('short-desc')
		elm.focus();
	};

	//executes when the Reopen option is clicked and sends to the server side
    $scope.reopenRITM = function() {
        $scope.data.action = 'reopenRITM';
        $scope.server.update(init).then(function(response){
					if (response.isRITMReopened)
						spAriaUtil.sendLiveMessage(c.reopenedRITMMsg);
				});
			$scope.$emit('focusOnActions', {"isFocusRequired": true});
    };

    function init() {}
	
    $(document).on('click', 'div.modal-footer button.btn, ul#child-case-tabs .dropdown-menu', function(e) {
        e.stopPropagation();
    });

    $(document).bind('dragover drop', function(event) {
        event.preventDefault();
        return false;
    });

    $scope.$on('sp_loading_indicator', function(e, value) {
        if (!value && !c.doneLoading) {
            c.doneLoading = true;
        }
    });
}

 

The CSS and Link fields in the "Incident Standard Ticket Actions" widget aren't modified so you can just copy those and paste into your new widget. 

 

NOTE:

You need to realize that the Req item is different than an Incident in that there are actually two records (possibly more) to think about 1) The Request and 2) The Request Item(s).  So to reiterate, you'll need to be familiar with your process and make the modifications that suit your process. 

I hope this helps.

 

View solution in original post

9 REPLIES 9

Ankur Bawiskar
Tera Patron
Tera Patron

@ayushmaan_b 

for ESC and RITM table the widget is "Standard Ticket Header".

AnkurBawiskar_0-1758949236861.png

 

you can clone that and show those options for RITM table only

Then add this new widget to the ticket page

Also check this link

Create Reopen Incident Widget which requires comments for Service Portal 

If my response helped please mark it correct and close the thread so that it benefits future readers.

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

@ayushmaan_b 

Hope you are doing good.

Did my reply answer your question?

If my response helped please mark it correct and close the thread so that it benefits future readers.

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

Hi Ankur,

Thank you for the inputs. Let me try on PDI and il update the results.

 

Regards,

Ayushmaan

Hi Ankur,

 

I tried the steps shared by Chris above followed by yours where ive copied the 'Standard Ticket Header, widget and tried however the page gets this error ( Attached) probably due to my poor coding/ corrections.

 

Could you help me with 

Body HTML template
CSS
Server script
Client controller

 

that can best work for "RITM".

Thanks

@ayushmaan_b 

did you check the link I shared above?

try to use that as reference point and using an AI tool like Co-pilot etc you should be ready with the code but you will have to make some changes on your own as well.

If my response helped please mark it correct and close the thread so that it benefits future readers.

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