My requests and My Open incidents Widgets should have pagination.

Sandeep Bharate
Tera Contributor

In the service portal home page , My requests and My Open incidents Widgets should have pagination instead row count beside that there should be a selection with choices 5,10,15,20,25,30,35,40,45,50. When the user selects 5 it should display 5 records in the widget. When 10 , should show 10 records. Same for the remaining. By default it should be 5 for the both My requests and My Open incidents Widgets.

How to achieve this?

find_real_file.png

9 REPLIES 9

Fery,

Here is the full code of my working example for the "My Past Requests" widget we created.

HTML

<div class="panel panel-{{c.options.color}} b" ng-if="c.always_show ||c.data.list.length">
  <div class="panel-heading" >
    <h4 class="panel-title">{{c.options.title}}</h4>
    <i class="fa fa-filter" aria-hidden="true" tabindex="0" ng-click="c.showFilter = !myreq.showFilter;" title="Show filters for {{c.options.title}}"></i>
    <div ng-show="c.showFilter">
      <input ng-model="c.filterText" sn-focus="c.showFilter" style="color: grey; width: 100%; margin-top: .5em;" placeholder="{{data.filterMsg}}" 
             ng-change="c.setFilteredItems(c.data.list | filter:c.filterText)"> 
    </div>
  </div>
  <div class="list-group" style="max-height: none; overflow-y: auto;">
    <div class="list-group-item" ng-repeat="item in c.currentPageItems"> 
      <a  ng-click="c.onClick($event, item, item.url, {})" href="javascript:void(0)"> 
        <div ng-class="{'l-h-40': !item.secondary_fields.length}">{{item.display_field}}</div>
        <small class="text-muted" ng-repeat="f in item.secondary_fields">
          <span ng-if="!$first"> • </span>
          <span ng-switch="f.type" title="{{::f.label}}">
            <span ng-switch-when="glide_date"><sn-time-ago timestamp="::f.value" /></span>
            <span ng-switch-when="glide_date_time"><sn-time-ago timestamp="::f.value" /></span>
            <span ng-switch-default="">{{f.display_value}}</span>
          </span>
        </small>
      </a>
    </div>
  </div>
  <div class="panel-footer" ng-if="c.options.maximum_entries && c.data.count > c.options.maximum_entries">
    
    <div class="h4 number-show-label panel-title">
      ${Showing items {{ c.start + 1}} - {{c.end}} of {{c.filteredItems.length}}}
    </div>
  
    <nav id="prev-tab-nav" class="pull-right" aria-label="Previous requests and tasks page navigation">
      <ul class="pagination">
        <li>
          <a class="btn btn-default" href="#" aria-label="Previous" ng-disabled="c.currentPage == 1" ng-click="c.setCurrentPage(c.currentPage -1)">
            <span aria-hidden="true">&laquo;</span>
          </a>
        </li>
        <li>
          <a class="btn btn-default" href="#" aria-label="Next" id="prev-tab-next" ng-disabled="c.currentPage == c.numPages" ng-click="c.setCurrentPage(c.currentPage + 1)">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
    
    
    <div class="clearfix"></div>
  </div>
</div>

 

CSS

.panel-heading {
  position: relative;
  > .fa-filter { 
    position: absolute;
    top: 1rem; 
    right: 1rem; 
  }
}

.list-group-item > a {
	display: inline-block;
}
div.number-show-label{display:inline-block;}

#prev-tab-nav > ul {
  margin:0;
}
a[aria-label="Previous"]{margin-right:3px;}

 

CLIENT SCRIPT

function ($location, $rootScope) {	
	var c = this;
	c.filterText = "";
	c.showFilter = false;
	
	c.setFilteredItems = function(items) {
		c.filteredItems = items;
		c.currentPageItems = c.filteredItems.slice(0, c.options.maximum_entries);
		c.currentPage = 1;
		c.numPages = Math.ceil(c.filteredItems.length / c.options.maximum_entries);
		c.start = 0;
		c.end = c.options.maximum_entries < c.filteredItems.length ? c.options.maximum_entries : c.filteredItems.length;
	};
	
	c.setFilteredItems(c.data.list);
	
	c.setCurrentPage = function(pageNum) {
		if (pageNum < 1 || pageNum > c.numPages) return;
		c.start = (pageNum - 1) * c.options.maximum_entries;
		c.end = c.start + 5 < c.filteredItems.length - 1 ? c.start + c.options.maximum_entries : c.filteredItems.length;
		c.currentPageItems = c.filteredItems.slice(c.start, c.end);
		c.currentPage = pageNum;
	};
	
		
	c.onClick = function($event, item, url, action) {
		$event.stopPropagation();
		$event.preventDefault();
		if (url)
			$location.search(url);
		else {
			var evt = {};
			evt.url = url;
			evt.table = c.data.table;
			evt.sys_id = item.sys_id;
			evt.record = item;
			evt.rectangle_id = c.data.sys_id;
			evt.action = action;
			// put out the selection with simple list "sl_" prefix
			$location.search('sl_sys_id', evt.sys_id);
			$location.search('sl_table', evt.table);
			$location.search('spa', 1); // spa means "I've got this"
			$rootScope.$broadcast('$sp.list.click', evt);
		}
	};	
}

 

SERVER SCRIPT

(function() {
	if (!options.maximum_entries)
		options.maximum_entries = 20;
	var gr = new GlideRecordSecure('sc_request'); // does ACL checking for us
	//gr.addActiveQuery();
	gr.addQuery('active', false);
	options.title = options.title || gr.getPlural();
	data.display_field = 'sys_created_on';
	data.secondary_fields = ['number','sys_updated_on'];
	data.filterMsg = gs.getMessage("Filter...");
  var username = gs.getUserID();
	gr.addQuery('requested_for',username).addOrCondition('opened_by',username);
	gr.orderByDesc('sys_created_on');
	gr.query();
	data.count = gr.getRowCount();
	data.list = [];
	var recordIdx = 0;
	while (gr.next()) {
		//if (recordIdx == options.maximum_entries)
			//break;

		var record = {};
		record.sys_id = gr.getValue('sys_id');
		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.secondary_fields = [];
		data.secondary_fields.forEach(function(f) {
			record.secondary_fields.push(getField(gr, f));
		});

		record.url = {id: 'sc_request', table: 'sc_request', sys_id: record.sys_id};
		data.list.push(record);
		recordIdx++;
	}

	function getField(gr, name) {
		var f = {};
		f.display_value = gr.getDisplayValue(name);
		f.value = gr.getValue(name);
		var ge = gr.getElement(name);
		f.type = ge.getED().getInternalType()
		f.label = ge.getLabel();
		return f;
	}
	
})()

 

I hope this helps.

Seth

Hi,

I am getting a error in the HTML part href = "#" cannot be used it seems.

Are you editing the widget in the Now Platform or the Portal Widget Editor? Also, which version are you running?

I did in Now Platform. I am on Jakarta version

The Now Platform editor gives false errors.  Make your changes using the Portal Widget Editor.  It's a much better interface.  Let me know how it goes.