M
andatory fields are usually pretty simple to work with. ServiceNow provides simple UI policy and client script methods to make fields and variables mandatory. You may have noticed as you have worked with checkbox variables in the service catalog that these methods don’t apply. The reason for this makes perfect sense if you think about it. A checkbox has only two possible values…true or false. When the checkbox variable loads it is already set with a value of false (unchecked). Because of this, there’s never a situation where a checkbox variable wouldn’t satisfy a mandatory check. It will ALWAYS have a value!
What people usually want in these scenarios is to require a user to select a minimum number of options from a certain group of checkbox variables. In these scenarios, this minimum number of items checked really represents the standard for a mandatory check for that group of checkboxes. There’s not a simple way to handle these situations, but I’ve set up some client script solutions that allow you to perform this type of validation if it is needed.
This onLoad script will place a red mandatory indicator next to the label for a set of checkbox variables. Just paste the script into an ‘onLoad’ catalog client script and set the ‘mandatoryLabelName’ variable below with the Name value of the label variable for your group of checkbox variables. NOTE: This script requires an associated ‘Label’ variable to work with your checkbox variables and will not work in Service Portal. For Service Portal you should simply add a form info message as shown in the script below. See this post for details on how to set up label variables with checkboxes.
Name: Mandatory checkbox label indicator
Type: onLoad
Applies to: A Variable Set OR A Catalog Item
Script:
try{
mandatoryLabelName = 'checkbox_variables';
$('status.' + g_form.getControl(mandatoryLabelName).id).show();
}catch(e){}
}
This onSubmit script will check a set of checkbox variables to make sure at least some of them are checked. All you have to do is paste the script into an ‘onSubmit’ catalog client script and set the ‘mandatoryVars’ and ‘mandatoryCount’ variable values below with the checkbox variables the script should apply to and the minimum number of checked boxes.
Name: Mandatory checkboxes
Type: onSubmit
Applies to: A Variable Set OR A Catalog Item
Script:
//Set the mandatory checkbox variable names and total mandatory count here
var mandatoryVars = 'option1,option2,option3,option4';
var mandatoryCount = 2;
var passed = forceMandatoryCheckboxes(mandatoryVars, mandatoryCount);
if (!passed) {
//Abort the submit
var message = 'You must select at least ' + mandatoryCount + ' options.';
g_form.addErrorMessage(message);
return false;
}
}
function forceMandatoryCheckboxes(mandatory, count) {
//Split the mandatory variable names into an array
mandatory = mandatory.split(',');
var answer = false;
var varFound = false;
var numTrue = 0;
//Check each variable in the array
for (var x = 0; x < mandatory.length; x++) {
//Check to see if variable exists
if (g_form.hasField(mandatory[x])) {
varFound = true;
//Check to see if variable is set to 'true'
if (g_form.getValue(mandatory[x]) == 'true') {
numTrue ++;
//Exit the loop if we have reached required number of 'true'
if (numTrue >= count) {
answer = true;
break;
}
}
}
}
//If we didn't find any of the variables allow the submit
if (varFound == false) {
answer = true;
}
//Return true or false
return answer;
}
Wanted to check if this could be applied to surveys as at the moment ‘mandatory’ only applies to Single Linear Text types. However not applied to Multiple Choice types with custom Question Choices. Possible?
Good question. Unfortunately, there’s no real support for client scripting in surveys currently so you’re limited to the options in the tool.
That even worked in an Order Guide!!! Thanks Mark
For some reason, this only seems to work in an order guide when you have that tab selected.
If you are on the “Choose Options” page of an order guide but do not have that catalog item (tab) selected, the onsubmit script does not seem to run.
This is in Fuji
This worked beautifully on our development site but var refs = document.getElementsByTagName(“LABEL”);
returns a length of 0 on our other site even though there are labels in the catalog item. Do you have any idea if there is a system property which could be causing this problem?
Is there a ‘Label’ variable associated directly with the checkbox variables as explained here?
https://servicenowguru.wpengine.com/system-definition/m…
If you’ve got it set up that way and you’re still having issues then there may be a difference in versions between your dev and your other site.
It was a version mismatch. Thanks!
I’ve had this implemented for quite awhile, however a customer discovered an issue. When multiple checkboxes are selected, the label indicator turns green, but if they uncheck one of the checkboxes, the indicator turns back to red even though there are other selections selected. Is there a way to remediate that or is that just how it is?
Just the way it is.
Hi Blair,
Even I am experiencing this issue. Have you discovered a way-out for this, a workaround?
Sakshi,
No – we haven’t found a workaround.
Thanks.
I have discovered that adding the following line to a UI Policy Script, (or catalog client script if you feel so inclined) when the checkbox item is unselected script will fix this “bug” and not present the user with a false negative (indicator goes red)
[code]
var mandatoryLabel = ‘Phone options’;
//Get all of the LABEL tag elements and check for a matching label
$$(‘label’).each(function(labels) {
if(labels.innerHTML.indexOf(mandatoryLabel) > -1){
//Set the ‘changed’ class name for the label element
labels.previousSibling.removeClass(“mandatory”).addClass(“changed”);
}
});
[code]
We recently upgraded to Berlin 5, hotfix 2 and this script stopped working. Has anyone else had this issue?
Hi Blair, I haven’t heard of anyone else reporting that. Have you set up a simple test against a ServiceNow demo instance? Results there would help to identify whether this is something with the scripts or maybe a conflict with something else in your environment.
Mark,
It works on the demo instance. It must be something in our environment. Thanks
I am trying to implement this in an order guide and it doesn’t work. Individually, it does but not when I include it in an order guide. Any suggestions ???
It would depend on how your catalog item is set up. If the catalog item has no other mandatory variables then this may not work in an order guide. This is because the solution relies on an ‘onSubmit’ script. The ‘onSubmit’ script will not be processed unless the tab that the item is in is viewed first. The only good way to get around this based on how SN order guides work would be to make sure that the item with the mandatory checkboxes was the first tab in the order guide. If you have more than one item with mandatory checkboxes or you can’t order your items like that you’ll probably need to change your checkboxes to ‘Yes/No’ choice dropdowns with a ‘–None–‘ option as the default.
I got this to work in Calgary, but when we upgraded to Dublin, the mandatory indicator stopped working. It stopped looping to find the label. Any idea why ? Thanks
Looks like SN has added some extra spacing around the label text. The script I provided looks for an exact match so the spacing is throwing it off. I’ve updated the mandatory indicator script above to do a ‘contains’ search on the innerHTML so that should work better. Give it a try and let me know how it works!
YOU ARE THE BEST !!!!! It worked !!!! Thank you so much !!!
Good Afternoon Mark,
I implemented this script and it does work. Thank you very much for sharing this script!
However I do have an exception that if the requester has a certain role,
the mandatory checkboxes are hidden and are no longer required. However, on submit, the system is still requiring
the forced mandatory checkboxes to be selected.
How can I get around this?
Any assistance is appreciated.
Best Regards,
Audrey
Hi Audrey. You should just have to modify the ‘onSubmit’ script so that it includes the custom conditions you need. You can check to see if a user doesn’t have that certain role like this…
if(!g_user.hasRole(‘YOURROLENAMEHERE’)){
//Continue with the script here if they don’t have the role
}
Hi Mark,
Is there a option that is the opposite of this:
//Set the ‘mandatory’ class name for the label element
labels.previousSibling.className = ‘mandatory’;
e.g. notMandatory ?
I put your block of code in an onChange GlideAjax client script I have and the setting works fine. However when the condition changes I would like to reset the value back to default (no red indicator).
Any idea’s? Thanks, -e
Should just be the same line but with an empty string being set as the className.
Hello Mark,
I have this script working just fine on when someone is going to submit initially on other forms but my current problem is when I am trying to get the script working on tasks.
I have checkboxes that only appear on one of the tasks and one must be selected before submitting. But the onSubmit script tries to apply it to every task even if the checkboxes are not being displayed on the task being worked on.
We are on Calgary about to move to Dublin if that makes a difference. I have checked the box for Tasks on the Catalog Client Script and unchecked the others.
Is there a simple workaround to get it to only work on the task that the checkboxes are being displayed on?
I think the problem on standard forms is that the naming convention for variables is different. You need to prefix the variable names with ‘variables.’ so that a variable named ’email’ becomes ‘variables.email’.
http://wiki.servicenow.com/index.php?title=Client_Script_Access_to_Variable_Fields_on_Task_Records
I think you can fix the script above to work on standard forms by changing this line…
if(g_form.getValue(mandatory[x]) == ‘true’){
to this…
if(g_form.getValue(‘variables.’ + mandatory[x]) == ‘true’){
The change does have it work correctly on the task where the checkboxes are visible (thank you for the reminder about task variables). But the issue still is happening. The checkboxes are not visible on all tasks and it still checks on every task and throws the alert. It seems that the script needs to check and see if the checkboxes are visible before running but I haven’t been able to find a successful solution to checking that.
I’ve adjusted the script above to check for the presence of at least one of the given options before throwing the alert. That should give you what you need.
Good Afternoon Mark,
Thanks for your suggestion. I will try it tomorrow when I return to work, and update you with the results.
Kind Regads,
Audrey
Good Evening Mark,
Since the role information is referencing the role table,
my colleague added the following lines to the script and it worked:
var userRole;
var RoleRecord = new GlideRecord(‘role_table’);
var user = g_form.getValue(“student_ref”);
Sorry for the late response and thanks very much for your help!
Kind Regards
Audrey
I changed the check boxes to Yes/No and set default to None on an Order Guide which has [3] Items.
Howeve, the problem I am having is that when I click on Choose Options, it does not take me to the
selected item.
Am I missing a step?
Would you please advise?
Kind Regards and Thanks
Audrey
Good Afternoon Mark,
I resolved this issue by updating the conditions to Yes in the Rule Sets.
However, since I have [3] Yes/No/None variables on the Order Guide,
where when one is selected the other [2] are read only. and I would like to
make them required. I am not sure how to do this.
Any ideas?
Thanks
Audrey
This script is what i was looking for a long time. works perfect. thanks (y)
This doesn’t seam to work in Eurika, or am I missing something? When I add the onload client script you provided the group of check boxes become visible but the red mandatory bar is missing.
The information worked great!
Question though… I am on Fuji and the mandatory fields are designatged with asterisks, this code assigned a red pipe like symbol next to the field label (similar to Eureka). Does any one know the correct class statement to change it to a red asterisk to make it look like the rest of the Fuji UI?
Hey Robert, I’ve updated the code above with a fix for this that works in Fuji and Geneva with the correct indicator.
I am only in need of one mandatory checkbox, so I left out the count part of the script. I am getting the alert message as expected, but I also get the alert when the box is checked. Here is my script:
function onSubmit() {
//Set the mandatory checkbox variable names and total mandatory count here
var mandatoryVars = ‘Confirmation’;
var passed = forceMandatoryCheckboxes(mandatoryVars);
if(!passed){
//Abort the submit
alert(‘You must select “I Agree” to submit’);
return false;
}
}
I think you’ll want the count part regardless. If you put that back in exactly as shown above it should work great!
I put in as follows:
function onSubmit() {
//Set the mandatory checkbox variable names and total mandatory count here
var mandatoryVars = ‘Confirmation’;
var mandatoryCount = 1;
var passed = forceMandatoryCheckboxes(mandatoryVars, mandatoryCount);
if(!passed){
//Abort the submit
alert(‘You must select I Agree checkbox to submit.’);
return false;
}
}
And I am still receiving alert message when checkbox = checked.
Did you include the ‘forceMandatoryCheckboxes’ portion of the script above? You need to include that function in your client script.
Worked! You rock, thank you.
I’m having an issue where the system is prompting for mandatory checkbox even when it is hidden. Do you have a way to account for this scenario? Thank you.
Mandatory is mandatory whether hidden or not. If you hide a variable, you should always make it not mandatory at the same time. If you’re using the ‘onSubmit’ script above, it needs to include whatever conditions you have in your environment to make sure that item is included in the mandatory check.
Thank you for this tips.
It seems that for the Geneva release, the ‘label’ tag have been replaced by the ‘legend’ tag when we use label variable for a checkbox group
Modified script:
try{
var mandatoryLabel = 'Options';
//Get all of the LEGEND tag elements and check for a matching label
$$('legend').each(function(labels) {
if(labels.innerHTML.indexOf(mandatoryLabel) > -1){
//Show the mandatory indicator
labels.select('.required-marker')[0].show();
}
});
}catch(e){}
}
Thanks for the feedback. See above for an updated script that makes this whole thing much cleaner on Fuji or newer instances.
Thank you very much Aumeric B. It seems your updated script works in Geneva Patch 5. I updated one catalog item and it works as in Fuji.
Aymeric B – thank you for the update… does anyone happen to know why this does not work when a field is initially hidden via UI policy? I have a number of fields that are shown conditionally and when they UI policy shows the field the asterisk does not appear. The above script works fine if the field is shown onLoad. I am testing this script currently in Helsinki but had the same issue in Geneva as well.
figured it out… needs to be changed to an onChange script… just choose the label as the variable changing
I have implemented the script but cannot see the mandatory indicator on the label using either ” label” or “legend” in the indicated line. We are using Fuji patch 13. We want to force a selection from a list of benefits, but I feel the issue is in no mandatory label. The “Receive” label is right before a long list of checkboxes. Anything obviously wrong here?
Yeah, the problem was with the script that I had out here until a few minutes ago. It didn’t work on Fuji or beyond because of the CSS changes ServiceNow has made! The good news is that a fix is available now above and the script is actually much simpler. Please note that you’ll need to use the ‘name’ value of the variable rather than the ‘Label’ value now.
The script doesn’t seem to work in the Service Portal. Is there a way to have this work in the Service Portal? We are in Helskini Patch 4.
Unfortunately, this is probably a limitation of the Service Portal…and one of the reasons I’d be hesitant to adopt it at this point. Client script support in Service Portal isn’t great. Check out this community post for suggestions and a list of supported APIs.
https://community.servicenow.com/thread/232934
Hi Mark,
Can the same script be used on the form as well (e.g. incident, problem) by replacing variable names by column names?
You could re-use a lot of the logic, like the function and the looping, but this is designed specifically for catalog items. Form elements would be different as well in that you can’t really include a mandatory indicator for a set of items in a label like you can here.
This is awesome. Any idea on how to update the mandatory asterisk so that it grays out whenever a person selects one of the checkboxes or reverts when all checkboxes are cleared?
I think it’s possible, but it’s a pretty big script hack that’s not likely to make it through upgrades very often. It would also require a new ‘onChange’ client script for every single checkbox. I’m sure it could be figured out, but it’s not worth the trouble and risk in my opinion.
Hi Mark, this works well in the native UI. But the code below does not work in Service Portal 🙁 Any chance you’ve come across a solution for SP? Thanks – Regina
try{
mandatoryLabelName = ‘checkbox_variables’;
$(‘status.’ + g_form.getControl(mandatoryLabelName).id).show();
}catch(e){}
Unfortunately, no. Service Portal just doesn’t allow for any sort of client-side code flexibility.
Apologies, i didn’t realize JR already raised the question. Please disregard. Thanks
I love your website. Thank you. As someone who’s only been administering SN for just over 4 months, you’re a godsend.
Anyway, hoping to contribute here if anyone else has a similar situation. I’m creating a sort of a-la-carte non-standard software request for new hires. In the request, some options (all checkboxes) that have prerequisites. Example: There are softwares X and Y. The requester can choose just X if he likes, but if he chooses Y, he must also choose X.
So I came up w/ this, in a client script, which works quite well (not 100% perfect but certainly livable). If Y is selected, then X gets auto-selected, and becomes read-only (only while Y is selected). If the user deselects Y, then X gets deselected too (this is nit-picky but ideally a part of me wants it to stay selected but not read only). Anyway, here it is:
Name: Sel X if Y is selected
Type: onChange
Applies to: A Catalog Item
Applies on a Catalog Item view: true
if (newValue == 'false') {
g_form.setValue("var_X", 'false');
g_form.setReadOnly('var_X',false);
return;
}
if (g_form.getValue("var_Y", 'true')) {
g_form.setValue("var_X", 'true');
g_form.setReadOnly('var_X',true);
return;
}
}
Awesome Aaron, and thanks for sharing! I can think of a few places where a script like this might be helpful. One thing I love about ServiceNow is that there’s always cool new stuff to share and learn. Good luck continuing this going forward!
Hi Mark,
Just wondering, if any changes have been made to get the onSubmit script to work in the portal with Helsinki release?
Yes! Thanks for the reminder. I just figured out a way to get the ‘onSubmit’ script to work in all locations. I still don’t know why ServiceNow won’t isn’t supporting ‘g_form.getControl’ but I found an effective workaround in this case. The mandatory indicator script above still won’t work in Service Portal, but I think the ‘onSubmit’ script is the important one anyway. Take a look at the script above and give it a try.
Hi Mark,
I am still having an issue with the ‘onSubmit’ script working within the Service Portal. Looks like ‘g_form.getControl’ is still in the script above?
Thanks for the help!!
It’s in the one for the mandatory label (along with an explanation that that piece won’t work in the Service Portal) but it isn’t in the one that actually forces mandatory checkboxes.
Hello Mark
I have this code somewhat working. The only problem I am having is on my form the these fields are hiding unless you click “yes” to Catering. This is working fine. But if you select “No” the fields are hiding as expected and you click submit and the popup appears but it should only appear if Catering is Yes and No choices are selected.
Can you help, please
The script is working as designed but you need to modify the conditions where the script should apply. You’ll need to add those conditions into the client script so that it doesn’t run unless those conditions are met.
Mark,
I pasted your script and still getting errors when selecting siteview and new_user, group_class or specific_topic. But it works when I select wellview with the other options.
function onSubmit(){
//Set the mandatory checkbox variable names and total mandatory count here
var mandatoryVars = ‘wellview, siteview, new_user, group_class, specific_topic’;
var mandatoryCount = 1;
var passed = forceMandatoryCheckboxes(mandatoryVars, mandatoryCount);
if(!passed){
//Abort the submit
alert(‘You must select at least ‘ + mandatoryCount + ‘ options.’);
return false;
}
}
function forceMandatoryCheckboxes(mandatory, count){
//Split the mandatory variable names into an array
mandatory = mandatory.split(‘,’);
var answer = false;
var varFound = false;
var numTrue = 0;
//Check each variable in the array
for(x=0;x= count){
answer = true;
break;
}
}
}
}
//If we didn’t find any of the variables allow the submit
if(varFound == false){
answer = true;
}
//Return true or false
return answer;
}
Mark I have 2 variables one is called Application which has 2 check boxes called wellview and siteview and the other is Request Training with 3 chec kboxes called new_user, group_class and specific_topic.
Hi Mark,
The modified code to show the mandatory flag works great. Once a user selects one of the check boxes, how would you go about dimming the flag. Prior to the need to update the code after moving to Helsinki the following was working fine:
labels.previousSibling.className = ‘mandatory required-marker label_description’;
labels.up(‘table’).className=’question_spacer io_table is-filled’;
No so any longer. Any ideas?
You’ll have to ensure that it is set correctly on change of each checkbox, but this should change the indicator for you.
mandatoryLabelName = ‘YOURLABELVARNAMEHERE’;
$(‘variable_’ + g_form.getControl(mandatoryLabelName).id).addClassName(‘is-filled’);
Very helpful!!!
On my instance I had to declare var x in the for loop in order for the client script to execute. This was in a scoped app on version Jakarta patch 8a. Works great
Thanks Mark