Portal Widget for Process Flow States, need help to automatically reload it, when state changes

German Rodrigue
Kilo Contributor

Hi All, I'm having an issue with a process flow custom widget, I'm trying to found a way how I can automatically reload it on the client script side to redraw the correct state, I have a variable that is automatically change when the state changes, but I'm not able to found a way to check in the client script when it changes, to rerun the function I have to put as active and done and show the correct state, here my code and widget how it looks:

Here a quick gif to see it:
find_real_file.png

//HTML
<div>
  {{data.status}}
</div>

<div ng-hide="!data.procurement" class="md-stepper-horizontal green" id="processflow">
    <div class="md-step" id="pending assignment">
      <div class="md-step-circle"><span>1</span></div>
      <div class="md-step-title">Pending Assignment</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
    
    <div class="md-step" id="assigned">
      <div class="md-step-circle"><span>2</span></div>
      <div class="md-step-title">Assigned</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
    <div class="md-step" id="in progress">
      <div class="md-step-circle"><span>3</span></div>
      <div class="md-step-title">In Progress</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
  <div class="md-step" id="close">
      <div class="md-step-circle"><span>4</span></div>
      <div class="md-step-title">Closed</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
</div>


<div ng-hide="data.procurement" class="md-stepper-horizontal green" id="processflow1">
    <div class="md-step" id="submitted">
      <div class="md-step-circle"><span>1</span></div>
      <div class="md-step-title">Submitted</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
    
    <div class="md-step" id="purchasing">
      <div class="md-step-circle"><span>2</span></div>
      <div class="md-step-title">Purchasing</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
    <div class="md-step" id="deployment">
      <div class="md-step-circle"><span>3</span></div>
      <div class="md-step-title">Deployment</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
      </div>
  <div class="md-step" id="close">
      <div class="md-step-circle"><span>4</span></div>
      <div class="md-step-title">Closed</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
</div>
//END HTML

//CLIENT SIDE
function($rootScope, $scope, $timeout, $location, $log, $window, spUtil, nowAttachmentHandler, spAriaUtil, spNavStateManager) {
	spUtil.recordWatch($scope, $scope.data.table, "sys_id=" + $scope.data.sys_id);
	$scope.updateProcessFlow = function(state) {
	var found_selected = false;
	if($scope.data.procurement==true){
		items = document.getElementById("processflow").getElementsByClassName("md-step");
	}
	else{
		items = document.getElementById("processflow1").getElementsByClassName("md-step");
	}
	selected = state.toLowerCase();
	
	for(i=0;i<items.length;i++){
		if(items[i].id==selected){
			items[i].classList.add("active");
			found_selected = true;
		}
		else if(!found_selected){
			items[i].classList.add("active");
			items[i].classList.add("done");
		}
		else{
			break;
		}
	}
	}	
	
	$scope.updateProcessFlow($scope.data.status);
}
//END Client Side

//SERVER Side
(function(){
		data.pickupMsg = gs.getMessage(options.pickup_msg);
	var gr = $sp.getRecord();
	if (gr == null)
		return;
	
	data.canRead = gr.canRead();
	if (!data.canRead) 
		return;
	
	// Get table & sys_id
  data.table = $sp.getParameter("table");
  data.sys_id = $sp.getParameter("sys_id");
	
  if(gr.u_category!=3){
		 data.procurement = true;
		 var state = $sp.getField(gr, 'state');
	   data.status = state.display_value;
		 }
	else{
		data.procurement = false;
		var stage = $sp.getField(gr, 'u_stage');
		data.status = stage.display_value;
	}
})()
//END Server Side




4 REPLIES 4

Cuong Phan
Kilo Sage

Hi German,

 

You can simply use below script in your client script to watch state changes

spUtil.recordWatch($scope, $scope.data.table, "sys_id=" + $scope.data.sys_id,function(name){
			
		console.log(name.data.changes); 
if (name.data.changes.state) {
   $scope.updateProcessFlow($scope.data.status);
}

		
	});

find_real_file.png

Mark ✅ Correct if this solves your issue and also mark ???? Helpful if you find my response worthy based on the impact.

 

Cuong Phan

DXC Consultant.

 

Regards,
Cuong Phan
ServiceNow Technical Lead

Ivano B
ServiceNow Employee
ServiceNow Employee

Hi German 

I would suggest a slightly different approach suggested by @Cuong Phan that will allow to write less code

spUtil.recordWatch($scope, $scope.data.table, "sys_id=" + $scope.data.sys_id, function(obj){
		console.log(obj);
		spUtil.update($scope);
});

 

You can also try the following approach..

if you need to inject some css class remember that you have a directive named  ng-class available to inject css if specific conditions are meet.

Documentation here.

If you check the actual value of the status you don't even to write the function you created.

This is a rough example using your base code.

Just in case i created a css class to force the circle to go green at the right moment. 

 

Part of your HTML

<div ng-hide="!data.procurement" class="md-stepper-horizontal" id="processflow">
    <div class="md-step" id="pending assignment">
      <div class="md-step-circle" ng-class="{'green' : c.data.state > 0}"><span>1</span>
    </div>
      <div class="md-step-title">Pending Assignment</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
    
    <div class="md-step" id="assigned">
      <div class="md-step-circle" ng-class="{'green' : c.data.state > 1}"><span>2</span></div>
      <div class="md-step-title">Assigned</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
    <div class="md-step" id="in progress">
      <div class="md-step-circle" ng-class="{'green' : c.data.state > 2}"><span>3</span></div>
      <div class="md-step-title">In Progress</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
  <div class="md-step" id="close">
      <div class="md-step-circle" ng-class="{'green' : c.data.state > 3}"><span>4</span></div>
      <div class="md-step-title">Closed</div>
      <div class="md-step-bar-left"></div>
      <div class="md-step-bar-right"></div>
    </div>
</div>

SERVER

(function() {
    data.pickupMsg = gs.getMessage(options.pickup_msg);
    var gr = $sp.getRecord();
    if (gr == null)
        return;

    data.canRead = gr.canRead();
    if (!data.canRead)
        return;

    // Get table & sys_id
    data.table = $sp.getParameter("table");
    data.sys_id = $sp.getParameter("sys_id");

    if (gr.u_category != 3) {
        data.procurement = true;
        var state = $sp.getField(gr, 'state');
		data.state = state.value;
        data.status = state.display_value;
    } else {
        data.procurement = false;
        var stage = $sp.getField(gr, 'u_stage');
        data.status = stage.display_value;
		data.state = state.value;
    }

})();

CLIENT

api.controller = function($rootScope, $scope, $timeout, $location, $log, $window, spUtil, nowAttachmentHandler, spAriaUtil, spNavStateManager) {
    /* widget controller */
    var c = this;

    spUtil.recordWatch($scope, $scope.data.table, "sys_id=" + $scope.data.sys_id, function(obj){
		console.log(obj);
		spUtil.update($scope);
	});

};

Cheers

R0b0

Edson2
Kilo Contributor

Hello German , do you have de css stylei would appreciate it if you can share it

Evren Yamin
Tera Contributor

Hello @German Rodrigue, are you able to make this working? appreciate if you can share, thank you