A
while ago I helped to answer a forum posting for someone who was looking for a way to present catalog variables to an end-user on a Request Item form but restrict the editing of those variables. At the time, I came up with a solution that worked, but that I really wasn’t happy with. I recently came across another forum posting where the poster wanted to do something similar. The difference for the most recent poster was that the variables were to be shown on an Incident form (which had been generated by a record producer). There were some subtle differences in the way variables were presented on the different forms that made my original script unusable for the incident form. So, I’ve had to revisit this topic to come up with a better solution and I’ve decided to compile all of the different options for making variables read only on a regular form. These solutions can be used in a variety of places, but will most often be applied to the Catalog Item, Catalog Task, Incident, or Change Request tables. Enjoy!

Locking down variables by role without a script…
Its probably best to avoid writing any script at all if you can to lock down access to variables. Service-now allows you to add roles to any variable in the system for this purpose. If you want to lock down variables without using a script, the solution can be found here. This solution is very simple but often doesn’t give you the type of flexibility that you need to restrict access to variables. It also requires you to set access to each and every variable in the system individually.
Locking down variables via business rules…
Probably the simplest way of locking down variables on a standard form via script is to create a business rule that checks to see if the variables have changed and then to abort the submission of the task record if they have changed. To do this, you just have to create a ‘before’ business rule on the table you want to restrict the editing of variables. The business rule should have a condition of ‘current.variable_pool.changes()’. You can put whatever you want in the script field but it should include ‘current.setAbortAction(“true”);’. If the user changes variable values and tries to submit the record they would get an alert telling them that they are not allowed to change variables. Here’s a sample…
Name: Abort on Variable Change
Table: Requested Item (or whatever table you want to restrict changes to)
When: Before
Update: True
Condition: current.variable_pool.changes()
Script:
gs.addInfoMessage('You are not allowed to change variable values on this record.');
current.setAbortAction(true);
action.setRedirectURL(current);
The other option is to simply not show the variables at all and instead dump them into the work notes or comments fields. Here’s a script I found on the forums that takes all of the variables for a given item and sends them to the work notes field on that same item.
Name: Copy Variables to Work Notes
Table: Requested Item
When: Before
Insert: True
Script:
for (key in current.variables) {
var v = current.variables[key];
wn += '\n' + v.getGlideObject().getQuestion().getLabel() + ': ' + v.getDisplayValue();
}
current.work_notes = wn;
Locking down variables via client scripting…
Service-now actually provides a simple way to make a variable on a standard task form read only via client scripting. If you just need to disable one or two variables on a single item then this is probably the best scripting option. The solution is documented here.
More often than not however, if you are disabling variables at all, you are disabling them entirely or disabling them for a certain group of users. For that case, you could use a script like this one to lock down all of the variables on a form. This script looks for the ‘Variables’ label on the variable formatter and disables the variables associated with it. It is designed to work on any task table in Service-now.
Name: All Variables Readonly
Table: Incident, Change request, Request item, Catalog task, wherever!
Type: onLoad
try{
//Get the 'Variables' section
var ve = $('variable_map').up('table');
//Disable all elements within with a class of 'cat_item_option'
ve.select('.cat_item_option', '.slushselectmtm', '.questionsetreference', '.form-control', '.checkbox').each(function(elmt){
elmt.disabled = true;
});
//Remove any reference or calendar icons
ve.select('img[src*=reference_list.gifx]', 'img[src*=small_calendar.gifx]').each(function(img){
img.hide();
});
//Hide list collector icons
ve.select('img[src*=arrow]').each(function(img){
img.up('table').hide();
});
}
catch(e){}
}
great post Mark,
solved the issue I’m having with making variables readonly
don’t have to wait for the hi server to solved the problem I raised
thanks
I’m looking for a way to hide all of the variables that have no value. Could I use a similar script ?
Thanks
You might be able to use what I have written as a basis, but I would guess that they would end up being pretty different. Checking each variable to see if it has a value would probably be pretty complicated due to all of the different variable types. My guess is that if I were to try and write a script for that it would probably have to be a pretty big hack to account for everything.
There is a way now! It’s just been published here.
https://servicenowguru.wpengine.com/scripting/business-…
Thanks Mark .. another quick question.. is it possible to amend the above script to exclude the container start variable type otherwise you can’t collapse containers when viewing items ? thanks
This issue only happens in IE. I’ve posted an updated script to fix it.
I am using your ‘Copy Variables to Work Notes Business Rule’ in a workflow to copy the variables to the description of my sc_req_item. Is there any way to get the script to use the variable order from the catalog item to order the variables when writing using your script?
Unfortunately, I don’t know of a way to do this currently.
With a little help from wattsj here http://community.service-now.com/forum/2498 I was able to get the items to order by the order value. Thought I’d share.
var varown = new GlideRecord('sc_item_option_mtom');
varown.addQuery('request_item', current.sys_id);
varown.applyEncodedQuery('ORDERBYsc_item_option.order');
varown.query();
while (varown.next()){
gs.log('found something');
var question = Packages.com.glideapp.questionset.Question.getQuestion(varown.sc_item_option.item_option_new);
question.setValue(varown.sc_item_option.value);
if (question.getLabel() != '' && question.getDisplayValue() != ''){
wn += '
' + question.getLabel() + ': ' + question.getDisplayValue();
}
}
current.description = wn;
Cool! Thanks for posting your solution!
Mark,
Thank you for the client script that makes the variables read only on the Request Item form. I have noticed that if you have a date variable filled in and you make an update to the form i.e. change assigned to etc, that the date type variable will be wiped of data. I assume that it has something to do with the removal of the calendar icons, but I am not positive. If you could elaborate a workaround for this issue that would be greatly appreciated.
The only workaround I can recommend is to use one of the other methods provided in the article. The fact that the date fields don’t retain their value doesn’t really have anything to do with the script provided here. It’s really a bug that you should contact Service-now support about. Making a field read-only with a client script should not make that field lose its value upon save…regardless of the script used.
Thanks for the quick response. I agree that data should not be lost due to a read only function, but I don’t see in your script where that is depicted. I’ve noticed that a standard g_form.setReadonly(‘date’, true) greys out the value box, yet doesn’t remove the calendar icon, allowing for dates to be changed at any point even after a read only function has been applied. I will create a HI Server ticket regarding this setReadonly issue.
Thanks again keep the posts coming a lot of excellent information has come from the Guru.
FYI, I’ve modified my client script code above to fix this issue. By using the ‘readOnly’ property instead of the ‘disabled’ property on those elements you don’t lose the dates on save. This doesn’t fix the out-of-box ‘g_form’ calls though. That still needs to be addressed by ServiceNow development.
I’ve used the client script code provided and it is still resetting my date variables. Based on Mark’s fix, the code should now be fixed to use ‘readOnly’ instead of ‘disabled’. However, I’m not seeing ‘readOnly’ anywhere in his script. Am I missing something?
Here is what I have:
function onLoad(){
try{
//Get the ‘Variables’ section
var ve = $(‘variable_map’).up(‘table’);
//Disable all elements within with a class of ‘cat_item_option’
ve.select(‘.cat_item_option’, ‘.slushselectmtm’, ‘.questionsetreference’).each(function(elmt){
elmt.Disabled = true;
});
//Remove any reference or calendar icons
ve.select(‘img[src*=reference_list.gifx]’, ‘img[src*=small_calendar.gifx]’).each(function(img){
img.hide();
});
//Hide list collector icons
ve.select(‘img[src*=arrow]’).each(function(img){
img.up(‘table’).hide();
});
}
catch(e){}
}
Make sure that the ‘elmt.Disabled’ line looks like this (including the proper case)…
elmt.disabled = true;
If that doesn’t work then you can try ‘elmt.readOnly = true;’.
i have two catalog variables – location and stock room. both are reference variables. based on what user enters in location, stock room values are available. i have a business rule to set reference_qual for stock room. however, current.variable_pool.location is giving me “undefined”. please can you tell me what am i doing wrong.
I think you need to use ‘current.variables.location’ instead. If you have further questions about this please post them on the forums since it’s not really pertinent to this article.
This was a great fix to making the variables read-only on my catalog tasks. I have one variable that I need to have available due to some other scripting we have. How would I exclude this one variable to not be read-only? The variable is “new_user” on the Corporate Directory catalog item.
Hey Veronica,
You should just be able to use a standard ‘g_form.setReadonly’ call to make that variable writable. I just confirmed that this works with the ‘short_description’ variable on the Service-now demo instance. I did notice problems with ‘g_form.setReadonly’ for reference variables though. This has nothing to do with the scripts I’ve written here so if you can get it to work for a standard string variable but not for a reference variable then you’ll want to contact support.
You should just need to add a line like this right inside of the closing bracket for the ‘onLoad’ function…
This line worked perfectly! Thank you!
On the “All Variables Read Only” client script, I noticed after some testing on my catalog items, this script wipes out my variable for the requested_date. I took out the latter of the code then it did not work at all as far as making all variables read-only.
Yep. See the comments above by Rob Ballin. The issue you describe affects both date and date/time variables and doesn’t have anything to do with the script here. It is a Service-now bug. You can reproduce it simply by using “g_form.setReadonly(‘variables.myDateVar’, true)” in a standard client script and saving the form. Any time date variables are readonly when the form is saved they will lose their values. I know that this issue has been reported to Service-now before, but it probably wouldn’t hurt to pile on to get the bug fixed.
You may also consider the ‘Locking down variables by role without a script’ method described above.
I’ve modified my client script code above to fix this issue. By using the ‘readOnly’ property instead of the ‘disabled’ property on those elements you don’t lose the dates on save. This doesn’t fix the out-of-box ‘g_form’ calls though. That still needs to be addressed by ServiceNow development.
We display the variable editor on both the requested item and the catalog task and have tried to implement Copy Variables to Work Notes Business Rule several times with no success. Even though we have the condition statement, the business rule fires whenever any field on the item is changed. Strangely enough, the rule appears to work for users with admin privileges. I have set debugging on and really can’t figure out what the problem is. Should the business rule on sc_task look exactly like the rule on sc_req_item with the exception of the change to the table? Would setting the service catalog property which initiates auditing of variables contribute to the problem? Thanks in advance for any help you can provide.
The ‘Copy variables to work notes’ script is only intended to be run on insert and should replace the variable editor completely. If you want to use that method you should remove the variable editor on the form and change your business rule to only run on insert. If you’re going to continue to display the variable editor, you should use one of the other methods above to accomplish what you need.
I apologize….We were trying to use the Abort on Variable Change Business rule and I think the problem may be caused by the fact that a client script was trying to hide one of the variables. I’d still like to confirm that the business rule for sc_task is exactly the same as the rule for sc_req_item with the exception of the table. Thanks so much for the quick response.
No problem. Yes, the script and condition will be the same no matter what task table you use it on.
As it turns out, the problem with the Abort on Variable Change Business rule was caused by our apparent misuse of Label variables. The rule worked if the catalog item contained no labels or if the labels preceded checkboxes. If the label preceded a text field or was used alone, the business rule aborted the update no matter what field on the form was changed. (ex. we changed nothing but the requested item short description and the update was aborted) Thankfully I was able to recreate this on the demo site. We can fix our catalog items for future use but is there anything which can be done to resolve this issue on items submitted before the fix? We’d really like to use this solution since it seems use the least resources.
We tried the business rule on forum 2498 to copy variables to work_notes and consistently received a warning about “Table handling an extremely large result set” on the sc_itemOptionMTOM encoded query. Should we be moving entries out of this table as requested items are closed?
What do you mean by ‘misuse of Label variables’? I want to use this business rule to prevent users from modifying catalog variables, but am also getting an error when saving, even when no catalog variable has been touched.
Hey Mark,
Is there any way to write an Onchange script when any of these variables change ?
Thanks 🙂
There really isn’t any easy way to do this. You can request it as an enhancement, but for the time being there’s not much you can do other than make them readonly or hide them. Variables just aren’t designed for use on a regular form like normal fields are.
Thanks Mark ..
Hi Mark, using the client script I noticed that when using IE7 (never tested others) you loose the ability to hover over the information icon in reference fields. In Firefox it works fine, also Webkit based browsers. However in IT7… Not sure what causes this, just thought I’d let you know.
Hey All,
We’ve got all of our variables read only on our RITMS and Catalog Tasks but I’ve come across a problem where the fields won’t scroll in IE8 so if the user adds more than 5 lines of text to the field, the rest is lost to the person working the ticket. It scrolls just fine in Firefox but since IE is our company standard, I’m kinda stuck!
Any help would be hugely appreciated since we’re going live on Sunday!
Paula.
The reason this happens is that IE handles the ‘disabled’ flag differently than every other browser known to man :). The workaround for this is to use the ‘readOnly’ attribute instead for textarea elements. I’ve updated my client script above (for making all variables readonly) to check for this exception. I also cleaned up the entire script so it should be more efficient now than it was before.
Excellent, Mark. One last thing…it’s working in the RITMS and Catalog Tasks except in the Self-Service view, everything is editable! I’ve tested this with both my admin account and with an ess test user.
Check any other scripts running against those forms. You’ve got a syntax error in another client script that’s causing all other scripts to fail.
You rock! Thanks.
Hi Mark – great post. It work exactly as I need. however, we have several approvers on a requested item and I’m looking for a script that locks the variable field after the requested item is approved. Thanks
This code can do that. All you have to do is add the correct condition to it so that it is applied at the correct time. Just check to see if the approval field on the request item is set to approved and then apply one of the solutions here.
Hello Mark,
First of many thanks for all the scripts. With some tweaking this helped me solve some issues we had.
I have a comment about the “abort if variables change” business rule. I think there is a bug with slushbucket (list collector) variables, and maybe with others.
The BR sometimes thinks these variables change even if they don’t . After printing the ‘current’ and ‘previous’ values I saw that they had the same list of sys_id BUT in different order. Therefore current.variables.changes() returns true.
I guess this is a SNow bug…
Cheers,
David
Sounds like a ServiceNow bug to me. Thanks for posting the feedback here. That’s definitely something to look out for.
I see that ‘Variables’ is just text inserted into the Work Notes. What must be modified specific to my instance to get this to populate correctly? When tested, the submitted form is empty.
Hey Brent, I don’t know of any issue with the script. If you’ve set it up as described, you should end up with the value recorded in work notes. One important piece to this is that the work notes field is a journal field, so it will always be blank after submission. The entries for a journal field will only be displayed in the activity section of the record.
This is nice – good work. Can this be modified for mandatory instead of read-only? I know we can make any variable mandatory from the get-go, but I need it to be mandatory for only one task that the workflow generates. Maybe there’s a way to do this from the workflow, but I haven’t been able to figure it out.
Again – great work as always!
Thanks Jason. There’s no simple way to incorporate the enforcement of mandatory fields into graphical workflow. If you want to make a field mandatory though, you need to use the ‘setMandatory’ client script on the standard form to do it. These rules are typically pretty complicated to set up for standard forms since there are so many variables involved.
Hi Mark,
Is is possible to modify the code and remove calendar button for one field only. In Record producer form I have made field readonly, but it’s still showing me the calendar option.
Regards,
ND
It’s possible, but it’s going to require some investigation and customization of the script. I don’t have any sample code I can provide you for that.
Hi Mark,
After upgrading to Berlin I have noticed the lock down variables client script isnt deactivating manditory fields
I have alot of forms that have fields controlled by ui policy and once submitted all fields become visable on the editor but ones that are manditoty but not filled in are still prompting to be filled in.
I know the way SN interacts with the DOM has changed in berlin but i dont know enough to figure out why this has stopped working
If the fields are being made mandatory by catalog UI policy, then the UI policy wouldn’t be enforced on the standard forms anyway. I would guess that you’ve actually got the ‘Mandatory’ checkbox checked on the variables you’re seeing issues with. You could try to include ‘g_form.setMandatory’ in the client script to make each readonly variable not mandatory as well. I would recommend not using the ‘Mandatory’ checkbox on variables if you are though since it often ends up causing problems like this.
Hi Mark,
I have a question with list collectors and the inability to have them scroll in IE. It appears you’ve answered this for textarea fields but is there something that can be done for list collectors in IE browsers?
Thanks,
Sam
It might be possible, but it’s not very simple to do because you have to target those variables differently in the DOM. I don’t have a way to do that currently.
Hi,
I have written the following condition in a business rule:
if(current.u_active == ‘true’){
—
—
}
This condition works fine if I am updating records manually.
But this condition does not work for transform map,which is calling the same Business Rule.
After removing quotes of TRUE,it worked for transform map too.
Does anyone have idea of why this happened?
Anyone having issues with the Read Only Variables script with Calgary? Seems to work fine in making the fields read only/disabled, but if I update or save the form it actually wipes out the variables that were disabled, not the text areas that were read only. Not sure if it’s in conflict with something else I’ve done, but when I deactivate the code the variables stay after an update.
In looking around I found posts around JavaScript that keeping a field as Disabled doesn’t allow it to be submitted, so my theory is/was that since the value isn’t being submitted, Service-Now is thinking that the field was changed to be a blank or default value.
My work around was to add an additional onSubmit client script that sets Disabled to equal False instead of True, so the values are saved and seen the next time around. So far this is working for me in my tests.
This worked really well for us in Aspen and Berlin, just noticed it in testing out the early release of Calgary, perhaps they’ve added something to be more stringent around .Disabled…
I have the same problem as Ian described with Calgary. Ian, could you tell us about your work around in more details?
Calgary has some new checkboxes on Catalog UI Policies: “Applies on Requested Items” and “Applies on Catalog Tasks” where you can make the fields read-only.
Correct. Most of this solution probably won’t be necessary with the Calgary release.
I wanted to make two variables editable for all users. So I have added the below code in the client script that makes all the variables read only. If the variable is a radio button type, it is working fine and making the field editable. If the variable is a multiline text type, it is not making the variable editable.
g_form.setReadonly(‘variables.laptop_desktop’, false);
Any help?
ServiceNow had a couple of bugs when setting fields read only that I had to account for in this code (one with no scrolling or copy/paste in multiline text variables and one with date variables being blanked out on save). That’s what’s causing the ‘setReadonly’ command to fail. I’ve removed that section from my code above so you can give it a try. Let me know how it goes.
Hi Mark, I have encountered similar issue where the multiline text field is not editable.. could you please confirm if the below script is the latest that will fix the mutiline text field issue?
function onLoad(){
try{
//Get the ‘Variables’ section
var ve = $(‘variable_map’).up(‘table’);
//Disable all elements within with a class of ‘cat_item_option’
ve.select(‘.cat_item_option’, ‘.slushselectmtm’, ‘.questionsetreference’).each(function(elmt){
elmt.disabled = true;
});
//Remove any reference or calendar icons
ve.select(‘img[src*=reference_list.gifx]’, ‘img[src*=small_calendar.gifx]’).each(function(img){
img.hide();
});
//Hide list collector icons
ve.select(‘img[src*=arrow]’).each(function(img){
img.up(‘table’).hide();
});
}
catch(e){}
}
Hi Mark,
We tried to place this script in our eureka instance and is working great except for the HTML field type.
Any help would be much appreciated.
Thank you.
Best Regards,
NJ
Modified script worked perfectly. Thanks you so much, Mark..
From what I’m seeing, setting a variable to “disabled” in Calgary seems to behave differently than it did in Berlin and results in actually modifying the contents of the variable to be blank in the Options (sc_item_option) table. Not immediately, but as soon as you make a change to a task with variables on it for example, all the disabled variables will be empty when you re-open the form. Is anyone else seeing that behavior? Or is my system merely broken? 🙂
The behavior is actually the result of a bug that ServiceNow introduced by attempting to fix a separate bug. If you’re running on Calgary, there are actually better options now with UI policy and Client scripts. I’ve updated this article with a notice at the top to reflect the new functionality.
I like how this new functionality allows more customization flexibility on allowing this and that field, but it blows that I now have to go back and create 80+ Catalog UI Policies, well, keeps me busy at least.
The link “Find Here” under Locking by role needs to be updated.
http://wiki.servicenow.com/index.php?title=Using_Service_Catalog_Variables#Applying_Roles
Thanks Jim, I’ve updated the link above.
Hi Mark
Is there any way of adapting the Read Only client script for the mobile UI.
Specifically without using document.get or $( as they have issues on Mobiles.
Regards
Neil
No way that I know of currently. The mobile UI still suffers from so many of these types of issues that I generally just disable it and use the standard UI.
Can someone please tell me why this is not working: i have used the script for setting the variables to read only. It’s working fine but we need to set them to read only if u_reviewed == true. I have added this to the script. Without the getvalue line it works fine. With the getValue line it’s not working.
try{
if(g_form.getValue('u _review') == true){
//Get the 'Variables' section
var ve = $('variable_map').up('table');
//Disable all elements within with a class of 'cat_item_option'
ve.select('.cat_item_option', '.slushselectmtm', '.questionsetreference').each(function(elmt){
elmt.disabled = true;
});
//Remove any reference or calendar icons
ve.select('img[src*=reference_list.gifx]', 'img[src*=small_calendar.gifx]').each(function(img){
img.hide();
});
//Hide list collector icons
ve.select('img[src*=arrow]').each(function(img){
img.up('table').hide();
});
}
}
catch(e){}
}
best regards
Is ‘u_review’ an actual form field or is it a variable as well? If it’s a variable, then you’ll need to use ‘variables.u_review’ to refer to it. I would adjust your script so that you just have that line so that you can isolate the issue and troubleshoot just the one piece.
Hi all.
This not work for the HTML variables type. For orders variables type is working great.
Any help would be much appreciated.
I needed to make all variables on sc_task (Catalog Task) form read only.
Started making client script to make all variable fields read only by looping fields on g_form and calling g_form.setReadOnly(fieldname).
This however doesn’t remove teh lookup spyglass next to reference variables, or seem to mark them as read only, nor does setDisabled().
Then while browsing for other similar methods such as g_form.setDisabledField() I came across an undocumented method
g_form.setVariablesReadOnly(true|false)! This works brilliantly, not saure how long it has been around for. I am on Fuji patch3-04-07-2015
Hello,
Viewing this post got me thinking if it will be possible somehow to pass down all the variables or variable set from an “Order Guide” to the request form? Maybe in a tab? Let me know if it is possible. Thanks!
Hi Mark, I have modified the code with elmnt.readOnly = true. I can see the date resetting is fixed but still i can see the dropdown variables are editable here. Please provide some advice.
Only think I can say is to copy the code exactly. One thing to note is the variable name ‘elmt’, not ‘elmnt’ as you have in this comment.
Hi Mark,
I had put this into our environment and it was working great, but we have a form with checkboxes and list collectors and it’s showing them as editable, not read only. I’m not sure why and was wondering if you might have an idea?
thanks!
Looks like the class names on those variable types have changed slightly. I’ve updated the script above with something that should work. Give it a try and let me know how it goes.
HI Mark,
This doesn’t seem to work in Service Portal.
Any thoughts?
Thanks and Regards,
Kirti
You could try something like this if you want to use the traditional client script method…
https://community.servicenow.com/message/799314#799314
I think that going forward you might consider the ‘Ticket Fields’ service portal widget instead. That shows all of the variables by default in a readonly form.
Thanks Mark!
BR helped me restrict write from the variables.