UI Action: Can I pass a value from the client function to the server function?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-27-2015 12:50 PM
UI Action with Client == true
Current table is incident.
Intention is to take input via user confirmation in the client-side function & pass a value based upon that into a problem record that will be submitted in the server-side function.
I tried declaring a variable outside the functions and setting its value in the client-side function but its value is apparently not available to the server-side function.
I've tried doing a g_form_setValue in the client-side function to get a value into the current incident & than use that value to set a value in the new problem record. To save that to the incident, I used
gsftSubmit(document.getElementById('sysverb_update_and_stay'));
but it doesn't perform an update.
I followed that with
gsftSubmit(null, g_form.getFormElement(), 'create_problem');
to call the 'Action name' set in the UI Action but the problem is not created.
The UI action works fine if I don't bother with the second "confirm" or try to do the first gsftSubmit. Script with both is as follows.
//client-side 'onClick' function
function confirmProblem(){
var answer = confirm('Are you certain you want to create a problem record for this incident?');
if (!answer){
return false; //abort problem creation
}
var assignGroup = g_form.getReference('assignment_group');
var notify = confirm('Instead of waiting until you have modified the problem, do you want to notify the ' + assignGroup.name + " group immediately?");
alert("notify: " + notify);
if (notify){
g_form.setValue('u_problem_notify_on_create', true);
alert("notify on create: " + g_form.getValue('u_problem_notify_on_create'));
}
gsftSubmit(document.getElementById('sysverb_update_and_stay'));
alert("just before the second gsftSubmit");
//Call the UI Action and skip the 'onclick' function
gsftSubmit(null, g_form.getFormElement(), 'create_problem'); //MUST call the 'Action name' set in this UI Action
alert("just after the second gsftSubmit");
}
createProblem();
//server-side fn
function createProblem(){
var prob = new GlideRecord("problem");
prob.short_description = current.short_description;
prob.cmdb_ci = current.cmdb_ci;
prob.priority = current.priority;
prob.impact = current.impact;
prob.urgency = current.urgency;
prob.description = current.description;
prob.assignment_group = current.cmdb_ci.u_level_3_support_group;
prob.u_notify_on_create = current.u_problem_notify_on_create;
var sysID = prob.insert();
current.problem_id = sysID;
var mySysID = current.update();
gs.addInfoMessage("Problem " + prob.number + " created");
action.setRedirectURL(prob);
action.setReturnURL(current);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-27-2015 05:55 PM
Hi Douglas, you can do it with GlideAjax.
This would be your UI Action:
function confirmProblem(){
var answer = confirm('Are you certain you want to create a problem record for this incident?');
if (! answer){
return false; //abort problem creation
}
var assignGroup = g_form.getReference('assignment_group');
var notify = confirm('Instead of waiting until you have modified the problem, do you want to notify the ' + assignGroup.name + " group immediately?");
var ga = new GlideAjax('ProblemCreator');
ga.addParam('sysparm_name','execute');
ga.addParam('notify', notify);
ga.addParam('incident_id', g_form.getUniqueValue());
ga.getXML(problemCreated);
function problemCreated(response) {
var answer = response.responseXML.documentElement.getAttribute('answer');
alert('You just created a problem. Problem number = ' answer);
}
}
And you have to create a script include named ProblemCreator with this code:
var ProblemCreator = Class.create();
ProblemCreator.prototype = Object.extendsObject(AbstractAjaxProcessor, {
execute: function() {
var incident = this._getIncident( this.getParameter('incident_id') );
return this._createProblem(incident, this.getParameter('notify') );
},
_getIncident: function(id){
var incident = new GlideRecord('incident');
incident.get(id);
return incident;
}
_createProblem: function(incident, notify) {
var prob = new GlideRecord("problem");
prob.short_description = incident.short_description;
prob.cmdb_ci = incident.cmdb_ci;
prob.priority = incident.priority;
prob.impact = incident.impact;
prob.urgency = incident.urgency;
prob.description = incident.description;
prob.assignment_group = incident.cmdb_ci.u_level_3_support_group;
prob.u_notify_on_create = notify;
var prob_id = prob.insert();
incident.problem_id = prob_id;
incident.update();
return prob.number;
}
});
I think this will only need a couple of tweaks.
Good luck!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-27-2015 06:23 PM
GlideAjax may be a better way to handle this (kudos Edwin!) since it eliminates the need for the "notify" field. However, I would not update the incident for the form the user is on via GlideAjax. This will deviate from UI/UX paradigms in ServiceNow and could confuse users (when Update or Save is clicked, the form reloads with the most recently saved data. In essence, this reload is a confirmation/notification). Instead, you could cut the incident updating out of the Script Include, and instead add a call to gsftSubmit to the UI Action's problemCreated callback function.
The result would be the GlideAjax would save the problem and then the form's Submit/Save action would be triggered. Either way, with any Ajax, you might want to provide some visual UI indicator that something is going on, otherwise users might think the button isn't responding and click it again... and again... and again with a Problem record potentially being created each time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-27-2015 07:43 PM
Thanks for the feedback Travis! Really good advice, I will make sure to remember this tip for future development projects.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-27-2015 06:10 PM
Hi Douglass,
First, setting a field and updating is the best way to send data to the server during a form update. The reason the global variable in the script did not work is because there is not actually a "client script" and a "server script", the WHOLE script is actually executed twice in different contexts. You can read more about the way this trick works at http://www.servicenowguru.com/system-ui/ui-actions-system-ui/client-server-code-ui-action/.
Second, your script is throwing an error because of the createProblem() function call on the client side, though this doesn't seem to be causing any major problems at the moment. Nevertheless, preceding it with if (typeof window == 'undefined') will fix this. See the link above for a full explanation, the article really is worth the read.
Third, the REAL issue seems to be the first gsftSubmit. That call on the client is the equivalent of clicking the Save button (update and stay)... in other words the createProblem() function is never executed server side because the first gsftSubmit triggers a different UI Action server side. Your second gsftSubmit is spot on though. I ran the following script through some tests, custom fields excluded and it appears to work:
(I left the alerts in place though I assume you will remove some of them.)
//client-side 'onClick' function
function confirmProblem(){
var answer = confirm('Are you certain you want to create a problem record for this incident?');
if (!answer){
return false; //abort problem creation
}
var assignGroup = g_form.getReference('assignment_group');
var notify = confirm('Instead of waiting until you have modified the problem, do you want to notify the ' + assignGroup.name + " group immediately?");
alert("notify: " + notify);
if (notify){
g_form.setValue('u_problem_notify_on_create', true);
alert("notify on create: " + g_form.getValue('u_problem_notify_on_create'));
}
//gsftSubmit(document.getElementById('sysverb_update_and_stay')); Removed, this is equivalent to clicking Save, uses Save UI Action server side
//alert("just before the second gsftSubmit");
//Call the UI Action and skip the 'onclick' function
gsftSubmit(null, g_form.getFormElement(), 'create_problem'); // This ensures that THIS UI Action is used server side
alert("just after the second gsftSubmit");
}
// Prevents createProblem from running client side while still executing server side
if (typeof window == 'undefined')
createProblem();
//server-side fn
function createProblem(){
var prob = new GlideRecord("problem");
prob.short_description = current.short_description;
prob.cmdb_ci = current.cmdb_ci;
prob.priority = current.priority;
prob.impact = current.impact;
prob.urgency = current.urgency;
prob.description = current.description;
prob.assignment_group = current.cmdb_ci.u_level_3_support_group;
prob.u_notify_on_create = current.u_problem_notify_on_create;
var sysID = prob.insert();
current.problem_id = sysID;
var mySysID = current.update();
gs.addInfoMessage("Problem " + prob.number + " created");
action.setRedirectURL(prob);
action.setReturnURL(current);
}
I hope this helps.
Kind regards,
Travis