Issue in Pagination in Service portal widget
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-19-2020 10:14 PM
Hello
I am working on a menu item - My Approvals which should give me Pending Approvals, Approval history.
In approval history widget, I am trying to show 5 approvals at a time(On clicking "next", next 5 approvals will show up ) - which included all the states except Requested.
I'm trying to fetch records from sysapproval_approver table. and paginate them.
The pagination works fine for gr.addQuery('state','Requested');
Now I'm trying to make a widget for Approval History gr.addQuery('state','!=','Requested');
but the pagination for this changes everytime I click next button, It shows 3, sometimes 2 or sometimes 5 records, it is not consistent pagination.
I tried fetching only for approved state, but same thing. It seems to work well only for requested records for me.
I've tried fetching less records also, till some date, as I thought the issues might be large data, but same issue.
Kindly help ASAP.
Regards
- Labels:
-
Service Portal Development

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-20-2020 01:55 AM
Hello Nikita,
I'm afraid that without sharing the code we won't be able to help.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-20-2020 02:03 AM
Hi
Can try adding condition something like this?
gr.addEncodedQuery("state!=requested^ORstate=NULL");
Hope this helps.
Regards
Omkar Mone
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-20-2020 02:20 AM
Hi Omkar, I'm from Nikita's Team.
I tried this query, but did not helped.
Thanks for the response. I'll share the code soon.
-Laukik
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-20-2020 02:43 AM
Hi, The code is as below :
HTML
<div class="container">
<div>
<div >
<h2 class="title"> Pending Approvals</h2>
</div>
<div class="panel-group" id="accordion">
<div ng-repeat="records in c.data.approvals"class="panel panel-default">
<div class="panel-body">
<table style="width:100%" >
<tc>
<td>
{{records.item}}
<br>
<a href="sp_p66?id=requested_item&table=sc_req_item&sys_id={{records.reqItemSysID}}&view=sp" >
{{records.number}}
</a>
<br>
{{records.date}}
</td>
</tc> <tc>
<td class="more-info-btn">
<button type="button"
class="btn btn-primary"
ng-click="c.moreInfoClicked($index)"
is-open="records.isOpened"
data-parent="#accordion"
data-toggle="collapse"
data-target="#collapse{{$index}}">
<span class="glyphicon glyphicon-info-sign"></span>
<br>
More Info
</button>
</td>
</tc>
</table>
</div>
<div id="collapse{{$index}}" class="panel-collapse collapse" >
<div class="panel-footer">
<div class="table-container">
<table class="detail-shadow-box">
<tr class="detail-row"
ng-repeat="detail in c.data.approvals[$index].approvalDetails"
ng-class-odd="'odd'"
ng-class-even="'even'">
<td id="column-field"><b>{{detail.fieldType}}:</b></td>
<td id="column-data">{{detail.data}}</td>
</tr>
</table>
</div>
<div class="row" id="action-buttons">
<button type="button" class="btn btn-success" ng-click="c.approve($index)">
Approve
</button>
<button type="button" class="btn btn-danger" ng-click="c.reject($index)">
Reject
</button>
</div>
</div>
</div>
</div>
<!--<button class="btn btn-primary" ng-show="c.data.current_page != 0" ng-click="getPreviousIdx()">Previous</button>
<button class="btn btn-primary" ng-show="c.data.count >= c.data.page_size" ng-click="getNextSetIdx()">Next</button>-->
</div>
</div>
<div>
<div ng-if="c.data.advancedApproval" style="text-align:center; margin-bottom:15%">
<div class="panel panel-default">
<a href="/sysapproval_approver_list.do?sysparm_query=approver=javascript:getMyApprovals()^state=requested^EQ&sysparm_clear_stack=true&sysparm_clear_stack=true" target="_blank">
<h3>You have advanced approvals. Please click here to see them.</h3>
</a>
</div>
<div ng-if="c.data.approvals.length == 0 && c.data.advancedApproval == false">
<h4>You have no pending approvals</h4></div>
</div>
</div>
<div >
<h2 class="title">Approval History</h2>
<div class="panel-group" id="accordion">
<div ng-repeat="records in c.data.approvalsHistory" class="panel panel-default">
<div class="panel-body">
<table style="width:100%">
<col width="250">
<col width="100">
<col width ="75">
<tc>
<td>
{{records.item}}
<br>
<a href="sp_p66?id=requested_item&table=sc_req_item&sys_id={{records.reqItemSysID}}&view=sp" >
{{records.number}}
</a>
<br>
{{records.date}}
</td>
<td class="state-text">{{records.state}}</td>
</tc>
<tc>
<td class="more-info-btn">
<button type="button"
class="btn btn-primary"
ng-click="c.moreInfoClicked($index)"
is-open="records.isOpened"
data-parent="#accordion"
data-toggle="collapse"
data-target="#historycollapse{{$index}}">
<span class="glyphicon glyphicon-info-sign"></span>
<br>
More Info
</button>
</td>
</tc>
</table>
</div>
<div id="historycollapse{{$index}}" class="panel-collapse collapse" >
<div class="panel-footer">
<div class="table-container">
<table class="detail-shadow-box">
<tr class="detail-row"
ng-repeat="detail in c.data.approvalsHistory[$index].approvalDetailsHistory"
ng-class-odd="'odd'"
ng-class-even="'even'">
<td id="column-field"><b>{{detail.fieldType}}:</b></td>
<td id="column-data">{{detail.data}}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div>
<button class="btn btn-primary" ng-show="c.data.current_page != 0" ng-click="getPreviousFdx()">Previous</button>
<button class="btn btn-primary" ng-show="c.data.count >= c.data.page_size" ng-click="getNextSetFdx()">Next</button>
</div>
</div>
</div>
</div>
<script type="text/ng-template" id="rejectionModal">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Please enter comment</h4>
</div>
<div class="panel-body wrapper-xl">
<textarea required sp-autosize="true" ng-required="true" id="rejectComment" ng-model="c.comments"
placeholder="Comments required" class="form-control ng-pristine ng-valid ng-scope ng-empty ng-touched" aria-invalid="false"
style="overflow: hidden; word-wrap: break-word; resize: horizontal;"></textarea>
</div>
<div class="panel-footer text-right">
<button class="btn btn-primary" ng-click="c.display(idx)" >${Confirm Rejection}</button>
<button class="btn btn-primary" ng-click="c.closeModal()" >${Close}</button>
</div>
</div>
</script>
CSS
.title {
color: black;
}
.more-info-btn1 {
text-align: right;
}
.more-info-btn {
text-align: right;
}
.state-text {
color:black;
}
#action-buttons{
padding-top:30px;
text-align:center;
}
#column-field{
text-align:right;
width:50%;
padding-right:5px;
}
#column-data{
padding:5px;
}
.btn-success{
margin-right:5px;
}
.btn-danger{
margin-left:5px;
}
.detail-row{
color:black;
border-bottom-style: solid;
border-color: rgba(0, 0, 0, 0.19);
border-size: 1px;
}
/*
* .odd and .even are the colors that each row will be
*/
.odd{
background-color:#FFFFFF;
}
.even{
background-color:#EEEEEE;
}
.detail-shadow-box{
width: 100% !important;
}
/*
* The table container is used for the drop shadow and rounded corners
*/
.table-container{
border-radius: 10px;
overflow:hidden;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
Client Script
function($scope,spUtil,$uibModal) {
/* widget controller */
var c = this;
c.approve = function(idx){
c.data.actionSysID = c.data.approvals[idx].sysID;
c.data.action = 'approve';
c.data.actionIdx = idx;
c.server.update();
}
$scope.idx = "";
c.reject = function(idx){
$scope.idx = idx;
$scope.modalInstance = $uibModal.open({
templateUrl: 'rejectionModal',
scope: $scope
});
}
c.display = function(){
if(c.comments == undefined ){
alert("Comments are mandatory");
}
if(c.comments!= undefined ){
c.data.actionSysID = $scope.data.approvals[$scope.idx].sysID;
c.data.action = 'reject';
c.data.comments = c.comments;
c.data.actionIdx = $scope.idx;
c.server.update();
c.closeModal();
}
};
c.closeModal = function(){
$scope.modalInstance.close();
};
//}
/* Function for Approval History*/
//function($scope,spUtil,$uibModal) {
/* widget controller */
c.approveHistory = function(fdx){
c.data.actionSysID = c.data.approvalsHistory[fdx].sysID;
c.data.action = 'approve';
c.data.actionFdx = fdx;
c.server.update();
}
$scope.fdx = "";
c.rejectHistory = function(fdx){
$scope.fdx = fdx;
$scope.modalInstance = $uibModal.open({
templateUrl: 'rejectionModal',
scope: $scope
});
}
c.displayHistory = function(){
if(c.comments == undefined ){
alert("Comments are mandatory");
}
if(c.comments!= undefined ){
c.data.actionSysID = $scope.data.approvalsHistory[$scope.fdx].sysID;
c.data.action = 'reject';
c.data.comments = c.comments;
c.data.actionFdx = $scope.fdx;
c.server.update();
c.closeModal();
}
};
c.closeModal = function(){
$scope.modalInstance.close();
};
// pagination
/*$scope.getNextSetIdx = function(idx) {
c.data.current_page = parseInt(c.data.current_page) + 1;
c.data.action = "nextRecordIdx"
c.server.update().then(function(r){
c.data.action = undefined;
//c.data.records = r.records;
});
}
$scope.getPreviousIdx = function(idx) {
c.data.current_page = parseInt(c.data.current_page) - 1;
c.data.action = "nextRecordIdx"
c.server.update().then(function(r){
c.data.action = undefined;
//c.data.records = r.records;
});
}*/
$scope.getNextSetFdx = function(fdx) {
c.data.current_page = parseInt(c.data.current_page) + 1;
c.data.action = "nextRecordFdx"
c.server.update().then(function(rn){
c.data.action = undefined;
//c.data.records = r.records;
});
}
$scope.getPreviousFdx = function(fdx) {
c.data.current_page = parseInt(c.data.current_page) - 1;
c.data.action = "nextRecordFdx"
c.server.update().then(function(rn){
c.data.action = undefined;
//c.data.records = r.records;
});
}
}
Server Script
(function() {
/* populate the 'data' object */
/* e.g., data.table = $sp.getValue('table'); */
data.advancedApproval = false;
/*
This will get all the details for an
application approval.
*/
function getApplAccDetails(idx){
//Fetch approval record to get the associated details
var gr = new GlideRecord('sysapproval_approver');
gr.addQuery('sys_id', data.approvals[idx].sysID);
gr.query();
if(gr.next()){
/*
Now that we have the approval record will will dot walk over
to the reference record using document_id. From here we can
get the data on the record
*/
data.approvals[idx].approvalDetails = [
{
fieldType: "Number",
data: gr.document_id.number.toString()
},
{
fieldType: "Application",
data: gr.document_id.u_application.name.toString()
},
{
fieldType: "Application Line Item",
data: gr.document_id.u_application_line_item.u_name.toString()
},
{
fieldType: "ALI Role",
data: gr.document_id.u_ali_role.u_name.toString()
},
{
fieldType: "Role Description",
data: gr.document_id.u_ali_role.u_description.toString()
},
{
fieldType: "For User",
data: gr.document_id.u_user.name.toString()
}
];
}
}
function getRITMDetails(idx){
//Must define array
data.approvals[idx].approvalDetails = [];
//Fetch approval record to get the associated details
var gr = new GlideRecord('sysapproval_approver');
gr.addQuery('sys_id', data.approvals[idx].sysID);
gr.query();
if(gr.next()){
var varObj = gr.document_id.variables;
for(var v in varObj){
if(varObj.hasOwnProperty(v) && varObj[v] != ""&& v.toString() != "Break"){
var varName = v.toString();
var fieldObj = varObj[varName].getQuestion().getLabel();
var dataObj = varObj[varName].getDisplayValue();
var singleDetail = {};
if(fieldObj == null){
continue;
//singleDetail.fieldType = "";
}
else{
singleDetail.fieldType = fieldObj.toString();
}
singleDetail.data = dataObj.toString();
data.approvals[idx].approvalDetails.push(singleDetail);
}
}
} }
/*
Given the logged in user we want to pull up their approval record
*/
/*if (!input) {
//data.records = [];
data.page_size = 5;
data.count = 5;
data.current_page = 0;*/
data.approvals = [];
var approvalGR = new GlideRecord('sysapproval_approver');
approvalGR.addQuery('state', 'Requested');
approvalGR.addQuery('approver', gs.getUserID());
approvalGR.addQuery('source_table',"!=", "");
approvalGR.orderBy('sys_created_on');
//approvalGR.chooseWindow(data.current_page, data.page_size);
approvalGR.query();
while(approvalGR.next()){
var approvalObj = {};
var approvalNumber = approvalGR.document_id.number.toString();
if(approvalNumber.startsWith("RITM")){
approvalObj.type = "Requested Item";
approvalObj.number = approvalNumber;
approvalObj.sysID = approvalGR.sys_id.toString();
approvalObj.reqItemSysID = approvalGR.document_id.sys_id.toString();
approvalObj.date = approvalGR.sys_created_on.toString();
approvalObj.item = approvalGR.document_id.cat_item.name.toString();
data.approvals.push(approvalObj);
}
else if(approvalNumber.startsWith("ApplAcc")){
approvalObj.type = "Application Access";
approvalObj.number = approvalNumber;
approvalObj.sysID = approvalGR.sys_id.toString();
approvalObj.reqItemSysID = approvalGR.document_id.sys_id.toString();
approvalObj.date = approvalGR.sys_created_on.toString();
approvalObj.item = approvalGR.document_id.u_application.name.toString();
data.approvals.push(approvalObj);
}
else{
data.advancedApproval = true;
}
}
var loopIdx = 0;
while(loopIdx < data.approvals.length){
switch(data.approvals[loopIdx].type){
case "Application Access":
getApplAccDetails(loopIdx);
break;
case "Requested Item":
getRITMDetails(loopIdx);
break;
default:
break;
}
loopIdx += 1;
}
/*
Approve
*/
if(input.action == 'approve'){
var gr = new GlideRecord('sysapproval_approver');
gr.addQuery('sys_id', input.actionSysID);
gr.addActiveQuery();
gr.query();
if(gr.next()){
gr.state = 'approved';
gr.update();
}
data.approvals.splice(input.actionIdx,1);
}
/*
Rejection
*/
if(input.action == 'reject'){
var gr = new GlideRecord('sysapproval_approver');
gr.addQuery('sys_id', input.actionSysID);
gr.addQuery('state', 'requested');
gr.addActiveQuery();
gr.query();
if(gr.next()){
gr.state = 'rejected';
gr.comments = input.comments;
gr.update();
}
data.approvals.splice(input.actionIdx,1);
}
//})();
/*
Approval History Function
*/
//(function() {
/* populate the 'data' object */
/* e.g., data.table = $sp.getValue('table'); */
//data.advancedApproval = false;
/*
This will get all the details for an
application approval.
*/
function getApplAccDetailsHistory(fdx){
//Fetch approval record to get the associated details
var gr = new GlideRecord('sysapproval_approver');
gr.addQuery('sys_id', data.approvalsHistory[fdx].sysID);
gr.query();
if(gr.next()){
/*
Now that we have the approval record will will dot walk over
to the reference record using document_id. From here we can
get the data on the record
*/
data.approvalsHistory[fdx].approvalDetailsHistory = [
{
fieldType: "Number",
data: gr.document_id.number.toString()
},
{
fieldType: "Application",
data: gr.document_id.u_application.name.toString()
},
{
fieldType: "Application Line Item",
data: gr.document_id.u_application_line_item.u_name.toString()
},
{
fieldType: "ALI Role",
data: gr.document_id.u_ali_role.u_name.toString()
},
{
fieldType: "Role Description",
data: gr.document_id.u_ali_role.u_description.toString()
},
{
fieldType: "For User",
data: gr.document_id.u_user.name.toString()
}
];
}
}
function getRITMDetailsHistory(fdx){
//Must define array
data.approvalsHistory[fdx].approvalDetailsHistory = [];
//Fetch approval record to get the associated details
var gr = new GlideRecord('sysapproval_approver');
gr.addQuery('sys_id', data.approvalsHistory[fdx].sysID);
gr.query();
if(gr.next()){
var varObjHist = gr.document_id.variables;
for(var v in varObjHist){
if(varObjHist.hasOwnProperty(v) && varObjHist[v] != ""&& v.toString() != "Break"){
var varName = v.toString();
var fieldObj = varObjHist[varName].getQuestion().getLabel();
var dataObj = varObjHist[varName].getDisplayValue();
var singleDetail = {};
if(fieldObj == null){
continue;
//singleDetail.fieldType = "";
}
else{
singleDetail.fieldType = fieldObj.toString();
}
singleDetail.data = dataObj.toString();
data.approvalsHistory[fdx].approvalDetailsHistory.push(singleDetail);
}
}
}
}
/*
Given the logged in user we want to pull up their approval record
*/
if (!input) {
//data.records = [];
data.page_size = 5;
data.count = 5;
data.current_page = 0;
//var queryString = 'state!=requested';
data.approvalsHistory = [];
var approvalGRH = new GlideRecord('sysapproval_approver');
//approvalGRH.addQuery('state','NOT','Requested');
approvalGRH.addQuery("state", "!=","requested");
approvalGRH.addQuery('approver', gs.getUserID());
approvalGRH.addQuery('source_table',"!=", "");
// approvalGRH.orderBy('state');
approvalGRH.orderByDesc('sys_created_on');
//approvalGRH.setLimit(1);
approvalGRH.chooseWindow(data.current_page, data.page_size);
approvalGRH.query();
while(approvalGRH.next()){
var approvalObjHist = {};
var approvalNumberH = approvalGRH.document_id.number.toString();
if(approvalNumberH.startsWith("RITM")){
approvalObjHist.type = "Requested Item";
approvalObjHist.number = approvalNumberH;
approvalObjHist.sysID = approvalGRH.sys_id.toString();
approvalObjHist.reqItemSysID = approvalGRH.document_id.sys_id.toString();
approvalObjHist.date = approvalGRH.sys_created_on.toString();
approvalObjHist.item = approvalGRH.document_id.cat_item.name.toString();
approvalObjHist.state = approvalGRH.state.getDisplayValue().toString();
data.approvalsHistory.push(approvalObjHist);
}
else if(approvalNumberH.startsWith("ApplAcc")){
approvalObjHist.type = "Application Access";
approvalObjHist.number = approvalNumberH;
approvalObjHist.sysID = approvalGRH.sys_id.toString();
approvalObjHist.reqItemSysID = approvalGRH.document_id.sys_id.toString();
approvalObjHist.date = approvalGRH.sys_created_on.toString();
approvalObjHist.item = approvalGRH.document_id.u_application.name.toString();
approvalObjHist.state = approvalGRH.state.getDisplayValue().toString();
data.approvalsHistory.push(approvalObjHist);
}
else{
data.advancedApproval = true;
}
}
var loopFdx = 0;
while(loopFdx < data.approvalsHistory.length){
switch(data.approvalsHistory[loopFdx].type){
case "Application Access":
getApplAccDetailsHistory(loopFdx);
break;
case "Requested Item":
getRITMDetailsHistory(loopFdx);
break;
default:
break;
}
loopFdx += 1;
}
}
if (input && input.action == "nextRecordFdx") {
//data.records = [];
data.count = 0;
//var queryString = 'state!=requested';
//var startPage = 0;
//var endPage= 0;
var startPage = input.current_page * input.page_size;
var endPage= (input.current_page * input.page_size) + input.page_size;
data.approvalsHistory = [];
var approvalGRH = new GlideRecord('sysapproval_approver');
//approvalGRH.addQuery('state','IN','Rejected,Approved,Cancelled');
approvalGRH.addQuery("state", "!=","requested");
approvalGRH.addQuery('approver', gs.getUserID());
approvalGRH.addQuery('source_table',"!=", "");
approvalGRH.orderByDesc('sys_created_on');
// approvalGRH.orderBy('state');
//approvalGRH.setLimit(1);
approvalGRH.chooseWindow(startPage, endPage);
// gs.addInfoMessage("start " + startPage + " endPage " + endPage);
approvalGRH.query();
while(approvalGRH.next()){
data.count++;
var approvalObjHist = {};
var approvalNumberH = approvalGRH.document_id.number.toString();
if(approvalNumberH.startsWith("RITM")){
approvalObjHist.type = "Requested Item";
approvalObjHist.number = approvalNumberH;
approvalObjHist.sysID = approvalGRH.sys_id.toString();
approvalObjHist.reqItemSysID = approvalGRH.document_id.sys_id.toString();
approvalObjHist.date = approvalGRH.sys_created_on.toString();
approvalObjHist.item = approvalGRH.document_id.cat_item.name.toString();
approvalObjHist.state = approvalGRH.state.getDisplayValue().toString();
data.approvalsHistory.push(approvalObjHist);
}
else if(approvalNumberH.startsWith("ApplAcc")){
approvalObjHist.type = "Application Access";
approvalObjHist.number = approvalNumberH;
approvalObjHist.sysID = approvalGRH.sys_id.toString();
approvalObjHist.reqItemSysID = approvalGRH.document_id.sys_id.toString();
approvalObjHist.date = approvalGRH.sys_created_on.toString();
approvalObjHist.item = approvalGRH.document_id.u_application.name.toString();
approvalObjHist.state = approvalGRH.state.getDisplayValue().toString();
data.approvalsHistory.push(approvalObjHist);
}
else{
data.advancedApproval = true;
}
}
var loopFdx = 0;
while(loopFdx < data.approvalsHistory.length){
switch(data.approvalsHistory[loopFdx].type){
case "Application Access":
getApplAccDetailsHistory(loopFdx);
break;
case "Requested Item":
getRITMDetailsHistory(loopFdx);
break;
default:
break;
}
loopFdx += 1;
}
}
else{ return data}
})();