Issue in Pagination in Service portal widget

Nikita35
Kilo Guru

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

 

11 REPLIES 11

Ji__ Vopolka
Tera Expert

Hello Nikita,

I'm afraid that without sharing the code we won't be able to help.

Omkar Mone
Mega Sage

Hi 

Can try adding condition something like this?

gr.addEncodedQuery("state!=requested^ORstate=NULL");

 

Hope this helps.

 

Regards

Omkar Mone

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

Laukik Udpikar
Tera Expert

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}
		})();