Display Short Description on Widget 'My Requests'

rishabh31
Mega Sage

Hello Team,

I want to display a 'Short Description' of the Requests/Incidents instead of currently displaying the 'item name' on the 'Requests' list view of the Service Portal. (highlighted section in below screenshot is the place where the Short description needs to be displayed by replacing the currently displaying item name)

rishabh31_0-1680624289726.png

This is under the OOB widget- 'My Requests', I cloned this and tried ways to Display Short Descriptions on the 'Requests' view through various related community posts but failed to achieve this.

 

To complete this, something needs to be modified on Server Script OR Body HTML Template.

 

Below is the HTML Body Template & Server Script for the widget 'My Requests'. Requesting to please help me to modify the same so that the above requirement can be achieved.

 

HTML Body Template:

<div class="panel panel-default b" ng-init="c.trackPage()">
 <div class="panel-heading" ng-show="::!data.is_associated_ticket_tab">
    <h2 class="panel-title">{{::data.messages.myRequestsTitle}}</h2>
  </div> 	
  <div class="panels-container list-group">
			<div ng-show="::!data.is_associated_ticket_tab" class="list-group-item row requests-header-container">
          <div class="col-md-3 col-xs-12 m-b-sm fit-content">
            <div class="form-inline control-view" ng-if="c.options.show_view == 'true'">
            	<label class="control-label hidden-xs wrapper-xs " id="label_view" for="view">${View}</label>
              <select ng-model="c.viewFilter" id="view" class="sc-basic-select adjust-width" ng-change="c.changeView()" style="width:80%">
                <option value="open" selected="true">{{::data.messages.openRequests}}</option>
                <option value="close">{{::data.messages.closedRequests}}</option>
              </select>
            </div>
          </div>
          <div class="col-md-4 col-xs-12 padding-left-large fit-content">
            <div class="input-group" style="width:100%">
              <input ng-model="c.filterText" ng-keypress="c.checkEnter($event)"class="form-control" style="width:100%" placeholder="{{data.filterMsg}}" aria-label="{{data.filterMsg}}">
              <span class="input-group-btn">
                <button class="btn btn-default align-icon" type="button" ng-click="c.search()" data-original-title="{{data.filterMsg}}" aria-label="{{data.filterMsg}}" data-toggle="tooltip" data-placement="bottom">
                	<i class="fa fa-search"></i>
                </button>
              </span>
            </div><!-- /input-group -->
              
          </div>
    	</div>
    	<div ng-if="c.data.request.req_list.length == 0 && !c.filterText" class="panel-body panels-container">
        ${You do not have any requests} 
      </div>
    	<div ng-if="c.data.request.req_list.length == 0 && c.filterText" class="panel-body panels-container">
        ${Search didn't match any requests} 
      </div>
    <div role="table" ng-if="c.data.request.req_list.length > 0" class="table" aria-label="{{::data.messages.myRequestsTitle}}">
      <div ng-show="::!data.is_associated_ticket_tab" role="rowgroup" class="column-headers">
        <div role="row" class="list-group-item table-responsive">
          <span role="columnheader" class="col-xs-6 padder-r-none padder-l-none">${Request}</span>
          <span role="columnheader" class="col-xs-3 padder-r-none padder-l-none">${State}</span>
          <span role="columnheader" class="col-xs-3 padder-r-none padder-l-none">${updated_capital}</span>
        </div>
   	  </div>
      <ul role="rowgroup" class="padder-l-none padder-r-none">
        <li role="row" class="list-group-item table-responsive" ng-repeat="item in c.data.request.req_list | limitTo: c.data.lastLimit track by item.sys_id" style="margin:0px" >
          <div role="cell" class="col-xs-6 padder-l-none padder-r-none main-column">
            <div class="primary-display">
              <a href="?id={{::item.url.id}}&table={{::item.url.table}}&sys_id={{::item.url.sys_id}}" sn-focus="{{::item.highlight}}" aria-label="{{::item.display_field}} , {{::item.display_number}}"> {{::item.display_field}} </a>
            </div>
            <small class="text-muted">
              <div ng-repeat="f in item.secondary_displays" class="secondary-display">
                <span >{{::f.display_value}}</span>
              </div>
            </small>
          </div>
          <div role="cell" class="col-xs-3 padder-l-none padder-r-none state-column">
            <div class="state">
              <span> {{::item.state}}</span>
            </div>
          </div>
          <div role="cell" class="col-xs-3 padder-l-none padder-r-none updated-column">
            <div class="updated">
              <i class="fa fa-clock-o" aria-hidden="true" title="${Updated}"></i>
              <sn-time-ago timestamp="::item.updated_on"/>
            </div>
          </div>
        </li>
      </ul>
    </div>
  </div>
</div>
<div class="col-sm-12 pull-none" ng-if="c.data.hasMore" style="padding-bottom:15px">
					<div class="text-a-c" ng-if="c.fetching">
          	<i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i>
						<span class="sr-only">${Loading more requests}</span>  
  	      </div>
          <button class="btn btn-default btn-show-more" ng-click="c.loadMore()"> {{::data.messages.showMoreRequests}} </button>  
      </div>

Server Script:

(function() {
	
	var localInput = input; //to safeguard pullution of "input" via BR or other scripts
	
	var alsoRequest = false;
	
	var msg = data.messages = {};
	msg.myRequestsTitle = options.title? gs.getMessage(options.title) : gs.getMessage('My Requests');
	msg.openRequests = gs.getMessage('Open requests');
	msg.closedRequests = gs.getMessage('Closed requests');
	msg.showMoreRequests = gs.getMessage('Show More Requests');
	data.filterMsg = gs.getMessage("Search open requests");

	var recordTable = options.record_table || $sp.getParameter("table");
	var recordId = options.record_id || $sp.getParameter("sys_id");
	
	data.is_associated_ticket_tab = options.is_associated_ticket_tab;
	
	if (localInput && localInput.view === 'open')
		data.filterMsg = gs.getMessage("Search open requests");
	else if (localInput && localInput.view === 'close')
		data.filterMsg = gs.getMessage("Search closed requests");
	
	data.is_new_order = (($sp.getParameter("is_new_order") + '') === "true");
	data.requestSubmitMsg = gs.getMessage('Thank You. Your request has been submitted');
	
	function getField(gr, name) {
			var f = {};
			var id = gr.getUniqueValue();
			gr = new GlideRecord(gr.getRecordClassName());
			gr.get(id);
			f.display_value = gr.getDisplayValue(name);
			f.value = gr.getValue(name);
			var ge = gr.getElement(name);
		  if (ge) {
				var ed = ge.getED();
				if (ed)
					f.type = ed.getInternalType();
				f.label = ge.getLabel();
			}
			return f;
	}

	function getMyRequestSysIds() {
		var ids = {};
		var rq_filter = new GlideRecord('request_filter');
		rq_filter.addActiveQuery();
		if (rq_filter.isValidField('applies_to'))
			rq_filter.addQuery('applies_to', 1).addOrCondition('applies_to', 10);
		rq_filter.query();
		while(rq_filter.next()) {
			var tableName = rq_filter.table_name;
			if (rq_filter.isValidField('table'))
				tableName = rq_filter.table;
			var gr = new GlideRecord(tableName);
			gr.addQuery(rq_filter.filter);
			gr.query();
			if (tableName == 'sc_request')
				alsoRequest = true;
			while(gr.next()) {
				var portalSettings = {};
				portalSettings.page = rq_filter.portal_page.nil()? '' : rq_filter.portal_page.getDisplayValue() + '';
				portalSettings.primary_display = rq_filter.primary_display.nil()? '': rq_filter.primary_display + '';
				portalSettings.secondary_displays = rq_filter.secondary_display.nil()? '': rq_filter.secondary_display + '';
				ids[gr.sys_id + ''] = portalSettings;
			}
		}
		return ids;
	}
	
	// retrieve the request's
	var myRequestMap = getMyRequestSysIds();
	var taskIDs = Object.keys(myRequestMap);

	var gr = new GlideRecordSecure('task');
	
	if (!data.is_associated_ticket_tab) {
	if (localInput && localInput.view === 'open') 
		gr.addActiveQuery();
	else if (localInput && localInput.view === 'close')
		gr.addQuery('active', 0);
	else
		gr.addActiveQuery();
	} else {
			if (recordTable != 'universal_request') {
				//Check if universal_request field is present and it is a universal request
				var taskRecord = new GlideRecordSecure('task');
				taskRecord.get(recordId);
				if (taskRecord.isValid() && !taskRecord.universal_request.nil()) {
						var qc = gr.addQuery('parent',taskRecord.universal_request);
						qc.addOrCondition('parent','IN',new sn_uni_req.UniversalRequestUtilsSNC().getChildRequests(taskRecord.universal_request));						
				} 
				else
						gr.addQuery('parent',recordId);
			} 
			else {
				var qc = gr.addQuery('parent',recordId);
				qc.addOrCondition('parent','IN',new sn_uni_req.UniversalRequestUtilsSNC().getChildRequests(recordId));						
			}
	}

	gr.orderByDesc('sys_updated_on');
	if (localInput && localInput.search_text) {
			var req = [];
			var task = new GlideRecordSecure('task');
			task.addQuery('123TEXTQUERY321', localInput.search_text);
			if (localInput && localInput.view === 'open') 
				task.addQuery('active', 1);
			else if (localInput && localInput.view === 'close')
				task.addQuery('active', 0);
			else
				task.addQuery('active', 1);
			task.addQuery('sys_id', taskIDs);
			task.query();

			while(task.next())
				req.push(task.getUniqueValue());
		
			
			if (alsoRequest) {
				var ritmGR = new GlideRecord('sc_req_item');
				if (localInput && localInput.view === 'open') 
					ritmGR.addQuery('request.active', 1);
				else if (localInput && localInput.view === 'close')
					ritmGR.addQuery('request.active', 0);
				else
					ritmGR.addQuery('request.active', 1);
				ritmGR.addQuery('123TEXTQUERY321', localInput.search_text);
				ritmGR.addQuery('request.sys_id', taskIDs);
				ritmGR.query();
				while(ritmGR.next())
					req.push(ritmGR.getValue('request'));
			}
			gr.addQuery('sys_id', req);
		}
		else 
			gr.addQuery('sys_id', taskIDs);
	gr.query();

	data.request = {};

	data.request.req_list = [];
	var recordIdx = 0;	
	var limit = options.items_per_page? options.items_per_page : 15;
	if (localInput && localInput.action == 'fetch_more')
		data.lastLimit = localInput.lastLimit + limit;
	else
		data.lastLimit = limit;

	data.hasMore = false;
	while (recordIdx != data.lastLimit && gr.next()) {
		var portalSettings = myRequestMap[gr.getUniqueValue()];
		if (typeof portalSettings == 'undefined')
			portalSettings = {};

		var record = {};
		record.sys_id = gr.getValue('sys_id');

		if (gr.getRecordClassName() == 'sc_request') {
				var ritm = new GlideRecord("sc_req_item");			
				ritm.addQuery("request", gr.getUniqueValue());
				ritm.query();
				if (ritm.getRowCount() == 0)
					continue;
				if (ritm.getRowCount() > 1)
					record.display_field = gs.getMessage("{0} requested items", ritm.getRowCount());
				else {
					ritm.next();
					record.display_field = ritm.cat_item.getDisplayValue() || ritm.getDisplayValue("short_description");
				}
				record.url = { id: portalSettings.page? portalSettings.page: 'sc_request', table: 'sc_request', sys_id: record.sys_id};
		} else {
				record.display_field = portalSettings.primary_display ? getField(gr, portalSettings.primary_display).display_value : getField(gr, 'number').display_value;
				record.url = { id: portalSettings.page? portalSettings.page :'ticket', table: gr.getRecordClassName(), sys_id: record.sys_id};
		}
		record.display_number = getField(gr, 'number').display_value || '';
		if (portalSettings.secondary_displays) {
			record.secondary_displays = [];
			portalSettings.secondary_displays.split(",").forEach(function (sDisplay){
				record.secondary_displays.push(getField(gr, sDisplay));
			});
		}
		else 
			record.secondary_displays = getField(gr, 'short_description');
		
		record.updated_on = gr.getValue('sys_updated_on');
		record.state = gr.getDisplayValue('state');
		if((recordIdx !== 0) && (data.lastLimit - limit === recordIdx))
			record.highlight = true;

		data.request.req_list.push(record);
		recordIdx++;
	}

	if (gr.next())
			data.hasMore = true;
})();

Requesting to please help to get this acheived.

Will mark response Helpful & accepted as solution.

Thank You

1 ACCEPTED SOLUTION

Nia McCash
Mega Sage
Mega Sage

Try changing the following line in the server script

record.display_field = ritm.cat_item.getDisplayValue() || ritm.getDisplayValue("short_description");

if you only ever have one RITM and want the RITM short description:

record.display_field = ritm.getDisplayValue("short_description");

alternatively, to get the REQ short description:

record.display_field = gr.getDisplayValue("short_description");

View solution in original post

11 REPLIES 11

@Nia McCash 

I agree but I've received a request to show more detail for the RITM. When there are multiple RITMs on a REQ, it displays the quantity, ie. 3 requested items. They don't want to click on the short description of "3 requested items" and route to the ticket page to be able to know what they are about. Alternatively, we would like to display the RITM # and short description instead of the REQ# and sd. Do you have any suggestions? 

OlaN
Giga Sage
Giga Sage

Hi,

I believe this section should be changed, if you want the short description of the REQ showing instead of the RITM text.

// server script 
// current section
if (gr.getRecordClassName() == 'sc_request') {
				var ritm = new GlideRecord("sc_req_item");			
				ritm.addQuery("request", gr.getUniqueValue());
				ritm.query();
				if (ritm.getRowCount() == 0)
					continue;
				if (ritm.getRowCount() > 1)
					record.display_field = gs.getMessage("{0} requested items", ritm.getRowCount());
				else {
					ritm.next();
					record.display_field = ritm.cat_item.getDisplayValue() || ritm.getDisplayValue("short_description");
				}

// try replace with this updated section
if (gr.getRecordClassName() == 'sc_request') {
	record.display_field = gr.getValue('short_description');
	// You might need to set some default value, in case the short description on the REQ is empty
}

 

Thanks, @OlaN Sir,

Your response was also helpful, Per your response Server Script that particular section looks like as:

		if (gr.getRecordClassName() == 'sc_request') {
			record.display_field = gr.getValue('short_description');//To display Request Short Description
				var ritm = new GlideRecord("sc_req_item");			
				ritm.addQuery("request", gr.getUniqueValue());
				ritm.query();
				if (ritm.getRowCount() == 0)
					continue;
				if (ritm.getRowCount() > 1)
					record.display_field = gs.getMessage("{0} requested items", ritm.getRowCount());
				else {
					ritm.next();
					//record.display_field = ritm.cat_item.getDisplayValue() || ritm.getDisplayValue("short_description");//Default Line needs to be comment out
					//record.display_field = gr.getDisplayValue("short_description"); //To display Request Short Description
				}

KoenHaemels
Tera Contributor

Great post about this topic!
We are looking to add a extra column in the "My Requests" widget but are stuck currently.
I've added the extra column in the HTML body but can't seem to link the short description data to it.

<ul role="rowgroup" class="padder-l-none padder-r-none">
        <li role="row" class="list-group-item table-responsive" ng-repeat="item in c.data.request.req_list | limitTo: c.data.lastLimit track by item.sys_id" style="margin:0px" >
          <div role="cell" class="col-xs-6 padder-l-none padder-r-none main-column">
            <div class="primary-display">
              <a href="?id={{::item.url.id}}&table={{::item.url.table}}&sys_id={{::item.url.sys_id}}" sn-focus="{{::item.highlight}}" aria-label="{{::item.display_field}} , {{::item.display_number}}"> {{::item.display_field}} </a>
            </div>
            <small class="text-muted">
              <div ng-repeat="f in item.secondary_displays" class="secondary-display">
                <span >{{::f.display_value}}</span>
              </div>
            </small>
          </div>
          <div role="cell" class="col-xs-3 padder-l-none padder-r-none state-column">
            <div class="state">
              <span> {{::item.state}}</span>
            </div>
          </div>
          <div role="cell" class="col-xs-2 padder-l-none padder-r-none state-column">
            <div class="short_description">
              <span> {{::item.short_description}}</span>
            </div>
          </div>
          <div role="cell" class="col-xs-3 padder-l-none padder-r-none updated-column">
            <div class="updated">
              <i class="fa fa-clock-o" aria-hidden="true" title="${Updated}"></i>
              <sn-time-ago timestamp="::item.updated_on"/>
            </div>
          </div>
        </li>
      </ul>



Brijmohan
Tera Contributor

Hi @Nia McCash , 

 

I am also working in the same widget. When we open my request, short description is showing limited but I want when someone hover on the short description it should be visible whole text like list view in classic view. Please give your suggestion how can I achieve this. 

Brijmohan_0-1690274479685.png

 

 

In below snap we can see short description is long but showing only limited.

Brijmohan_3-1690274619548.png

 

Thanks & regards,

Brij