UI Action validation before process the action
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-23-2017 06:22 PM
Hello All,
I would like to get some advise on validating UI policies in generic way. Let me put a scenario to make it more simpler.
In our change module, we have two UI actions in implement state. Let's call them as "Implementation Complete" and "Revert to Assess".
1. When "implementation complete" button is being hit, it asks for two mandatory fields (i.e. closure details). Upon filling the mandatory field, If user hit the SAME button, system sets a flag (implementation complete) to true which triggers the workflow to next state.
2. When "Revert to assess" is being hit, it asks for another mandatory field (reversion detail). Upon filing field,If user hit the SAME button, system sets a flag (reversion flag) to true which in turn regress the workflow.
Here, I am pressing the word "SAME" . Because at times, user hit the "Implementation complete" button, fill out the mandatory fields and hit the another button "Revert to assess". Based on our functionality, flag set up, it triggers the 1st button (Implementation complete) and processed.
My concern is the mandatory fields that are filled in remain and non empty and get stored in the DB which creates issue if the same button is being again, as it has to make field mandatory which is already filled in.
Having said that, I would get advise/suggestion to have a generic way of validating UI actions being pressed.
Regards,
GB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-24-2017 08:05 AM
Hi,
Can you post the snippet of your UI actions? Just to make sure, I'm understanding you, why would the user hit the 'Rever to Assess' when he/she wants to put the change in 'Implementation complete' in first place?
Regards,
Darshak
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-24-2017 09:38 AM
I agree.. This should be doable with the UI Actions and it seems to be something wrong in the code. Sharing it would make it easier to answer.
Generally, my own personal feeling is to put the checks in the UI Action as well, just to keep the same standard as OOB UI Actions has (Like resolve on incident). Having it on a onSubmit client Script would make that script run all the times, even if not the button aren't used when the record is saved. Having it in the UI Action would make the code only run when needed. But I'm kind of a performance nerd 😎 and looking for every little thing to trim it up.
//Göran
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-27-2017 07:15 AM
This is more of preventing users from hitting wrong UI action, filling unintended fields and gets them saved in the data base.
Here is the script on both UI actions
Revert To Assess:
function showRevertChange(){
//make visible reversion fields
g_form.setDisplay('u_reversion_owner',true);
g_form.setMandatory('u_reversion_owner',true);
g_form.setDisplay('u_reversion_reason',true);
g_form.setMandatory('u_reversion_reason',true);
var answer = confirm("Are you sure you want to Revert the change?");
if(answer)
{
if (g_form.getValue('u_reversion_reason') == '' || g_form.getValue('u_reversion_owner') == '' ) {
alert('Please fill in the Reversion Reason and Reversion Owner under Assessment tab');
return false; // Abort submission
}
// Call the UI Action and skip the 'onclick' function
gsftSubmit(null, g_form.getFormElement(), 'revert_change_emergency'); // MUST call the 'Action name' set in this UI Action
}
//Clear & Hide, If the revert to Assess is cancelled
g_form.setValue('u_reversion_owner', '');
g_form.setValue('u_reversion_reason', '');
g_form.setMandatory('u_reversion_owner',false);
g_form.setMandatory('u_reversion_reason',false);
g_form.setDisplay('u_reversion_owner',false);
g_form.setDisplay('u_reversion_reason',false);
return false;
}
if (typeof window == 'undefined')
serverReopen();
function serverReopen() {
try{
new FISChangeRequestManager().RevertToAssess(current);
current.update();
action.setRedirectURL(current);
}
catch(ex){
FISErrors.showStandardUIError();
action.setRedirectURL(current);
}
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Implementation Complete:
function markImplementationComplete(){
//Set Implementation complete to true
//g_form.setValue('u_implementation_complete',true);
//g_form.save();
//}
//make closure fields mandatory
g_form.setMandatory('close_notes',true);
g_form.setMandatory('close_code',true);
var answer = confirm("Are you sure you want to mark the implementation complete?");
if(answer)
{
if (g_form.getValue('close_notes') == '' || g_form.getValue('close_code') == '' ) {
alert('Please fill in the Close notes and Close code under Closure Information tab');
return false; // Abort submission
}
// Call the UI Action and skip the 'onclick' function
gsftSubmit(null, g_form.getFormElement(), 'implementation_complete'); // MUST call the 'Action name' set in this UI Action
}
//Make fields non mandatory, If the Implementation complete is cancelled
g_form.setValue('u_reversion_owner', '');
g_form.setValue('u_reversion_reason', '');
g_form.setMandatory('close_notes',false);
g_form.setMandatory('close_code',false);
return false;
}
if (typeof window == 'undefined')
serverReopen();
function serverReopen() {
try{
current.u_implementation_complete = true;
current.update();
action.setRedirectURL(current);
}
catch(ex){
FISErrors.showStandardUIError();
action.setRedirectURL(current);
}
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Generic Script include for most of the change request functionality. Currently we have been using it for revert function alone.
var FISChangeRequestManager = Class.create();
FISChangeRequestManager.prototype = {
initialize: function() {
},
//function to display Revert to Assess button
AllowRevertToAssess : function FISChangeRequestManager_AllowRevertToAssess(change){
try{
//Displays the UI action in Authorize/schedule/implement phase
if(change.type == 'normal' && ((change.state == '-2' || change.state == '-3') || (change.state == '-1' && gs.getUser().hasRole('change_manager')))){
return true;
}
//Displays the UI action for emergency change in schedule/implement phase
else if(change.type=='emergency' && (change.state=='-2' || (change.state==-3 && change.u_assessment_complete == true) || (change.state == '-1' && gs.getUser().hasRole('change_manager')))){
return true;
}
else {
return false;
}
}
catch(ex){
//log error
gs.error("Error: FISChangeRequestManager.DisplayRevertToAssess: ", ex);
throw ex;
}
},
//validate reversion fields before proceed
ValidateRevertToAssess : function FISChangeRequestManager_ValidateRevertToAssess(change){
try{
if(this.AllowRevertToAssess(change)){
if(change.u_revert_change == false && change.u_reversion_owner != '' && change.u_reversion_reason != '' && change.u_implementation_complete == false){
return true;
}
else
{
return false;
}
}
}
catch(ex){
//log error
gs.error("Error: FISChangeRequestManager.AllowToRevert: ", ex);
throw ex;
}
},
//Reversion counter increment function
RevertToAssess : function FISChangeRequestManager_RevertToAssess(change){
try{
if(this.ValidateRevertToAssess(change)){
//get user & reversion details to put them in work notes
var user = gs.getUser();
var cur_user=user.getFullName();
var owner=change.u_reversion_owner.getDisplayValue();
//set the revert change flag to true
change.u_revert_change = true;
//Increment Reversion counter
change.u_reversion_count = change.u_reversion_count + 1;
var count = change.u_reversion_count;
//Increment FIS reversion counter
if (change.u_reversion_owner == '2'){
change.u_fis_reversion_count = change.u_fis_reversion_count + 1;
}
//Increment Client reversion counter
else if (change.u_reversion_owner == '1'){
change.u_client_reversion_count = change.u_client_reversion_count + 1;
}
//Increment Vendor reversion counter
else if (change.u_reversion_owner == '3'){
change.u_vendor_reversion_count = change.u_vendor_reversion_count + 1;
}
//update the work notes with reversion details
change.work_notes='Change Reverted by '+cur_user+'\n'+'Reversion owner - '+owner+'\n'+'Reversion Reason - '+change.u_reversion_reason+'\n'+'Reversion Count - '+count;
gs.addInfoMessage(gs.getMessage("Change {0} has been reverted to assess state successfully",[change.number]));
}
else{
gs.addErrorMessage(gs.getMessage("Invalid Update. Change {0} has not been reverted to assess state",[change.number]));
}
}
catch(ex){
//log error
gs.error("Error: FISChangeRequestManager.IncrementReversionCounters: ", ex);
throw ex;
}
},
// This business rule clean up the madate fields which gets filled during the UI actions (Implementation complete and Revert to assess) hit
// If UI actions is being hit and upon filling mandate fields, User must hit the same UI action to proceed. Some times, User hits some other UI action which in turn saves the date of those mandate fields in the DB
//To prevent this case, this Business Rule clean up the value if the UI action condition is not meet (i.e. flag was not set, it clear its corresponding mandate fields)
CleanUpMandateFields : function FISChangeRequestManager_CleanUpMandateFields(change){
try{
if(change.u_revert_change == false){
change.u_reversion_owner ='';
change.u_reversion_reason ='';
}
if(change.u_implementation_complete == false){
change.close_notes = '';
change.close_code = '';
}
}
catch(ex){
//log error
gs.error("Error: FISChangeRequestManager.CleanUpMandateFields: ", ex);
throw ex;
}
},
type: 'FISChangeRequestManager'
};
Regards,
GB