TUESDAY, FEBRUARY 07, 2012

Readonly Variables on a Standard Form

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!


Check out this post if you’re interested in hiding empty variables in a variable editor on a standard form!

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…

Abort on Variable Change Business rule
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:

//Add an information message, abort the submission, and reload the page
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.

Copy Variables to Work Notes Business Rule
Name: Copy Variables to Work Notes
Table: Requested Item
When: Before
Insert: True
Script:

var wn = 'Variables:';
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.

All Variables Readonly Client Script
Name: All Variables Readonly
Table: Incident, Change request, Request item, Catalog task, wherever!
Type: onLoad

function onLoad(){
   //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){
      //Special handling to allow scroll/copy in textarea and fix lost date on save issue
      if((elmt.tagName.toLowerCase() == 'textarea') || (elmt.tagName.toLowerCase() == 'input' && elmt.type.toLowerCase() == 'text')){
         elmt.readOnly = true;    
      }
      //Everything else gets disabled
      else{
         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();
   });
}

Comments

Posted On
May 24, 2010
Posted By
alli

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

Posted On
Jun 24, 2010
Posted By
Russ hart

I’m looking for a way to hide all of the variables that have no value. Could I use a similar script ?

Thanks

Posted On
Jun 24, 2010
Posted By
Mark Stanger

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.

Posted On
Jun 16, 2011
Posted By
Mark Stanger

There is a way now! It’s just been published here.
http://www.servicenowguru.com/scripting/business-…

Posted On
Jun 24, 2010
Posted By
Russ Hart

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

Posted On
Jun 25, 2010
Posted By
Mark Stanger

This issue only happens in IE. I’ve posted an updated script to fix it.

Posted On
Jul 08, 2010
Posted By
Jay Ford

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?

Posted On
Jul 08, 2010
Posted By
Mark Stanger

Unfortunately, I don’t know of a way to do this currently.

Posted On
Jul 08, 2010
Posted By
Jay Ford

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 wn = 'Variables:';
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;
Posted On
Jul 08, 2010
Posted By
Mark Stanger

Cool! Thanks for posting your solution!

Posted On
Sep 14, 2010
Posted By
Rob Ballin

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.

Posted On
Sep 14, 2010
Posted By
Mark Stanger

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.

Posted On
Sep 14, 2010
Posted By
Rob Ballin

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.

Posted On
Oct 03, 2011
Posted By
Mark Stanger

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.

Posted On
Dec 02, 2010
Posted By
austin123

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.

Posted On
Dec 02, 2010
Posted By
Mark Stanger

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.

Posted On
Feb 01, 2011
Posted By
Veronica Hoard

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.

Posted On
Feb 01, 2011
Posted By
Mark Stanger

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…

g_form.setReadonly('variables.short_description', false);
Posted On
Feb 01, 2011
Posted By
Veronica Hoard

This line worked perfectly! Thank you!

Posted On
Feb 01, 2011
Posted By
Veronica Hoard

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.

Posted On
Feb 01, 2011
Posted By
Mark Stanger

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.

Posted On
Oct 03, 2011
Posted By
Mark Stanger

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.

Posted On
Feb 24, 2011
Posted By
Cindy Hasler

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.

Posted On
Feb 24, 2011
Posted By
Mark Stanger

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.

Posted On
Feb 24, 2011
Posted By
Cindy Hasler

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.

Posted On
Feb 24, 2011
Posted By
Mark Stanger

No problem. Yes, the script and condition will be the same no matter what task table you use it on.

Posted On
Feb 25, 2011
Posted By
Cindy Hasler

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?

Posted On
Nov 03, 2011
Posted By
Wendy

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.

Posted On
Jun 06, 2011
Posted By
Abhiram Bharadwaj

Hey Mark,

Is there any way to write an Onchange script when any of these variables change ?

Thanks :)

Posted On
Jun 06, 2011
Posted By
Mark Stanger

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.

Posted On
Jun 06, 2011
Posted By
Abhiram Bharadwaj

Thanks Mark ..

Posted On
Jul 18, 2011
Posted By
Christian Tuebing

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.

Posted On
Sep 29, 2011
Posted By
Paula Cullen

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.

Posted On
Sep 30, 2011
Posted By
Mark Stanger

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.

Posted On
Sep 30, 2011
Posted By
Paula Cullen

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.

Posted On
Sep 30, 2011
Posted By
Mark Stanger

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.

Posted On
Sep 30, 2011
Posted By
Paula Cullen

You rock! Thanks.

Posted On
Oct 18, 2011
Posted By
Ashaki

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

Posted On
Oct 18, 2011
Posted By
Mark Stanger

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.

Posted On
Nov 17, 2011
Posted By
David Martin Clavo

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

Posted On
Nov 17, 2011
Posted By
Mark Stanger

Sounds like a ServiceNow bug to me. Thanks for posting the feedback here. That’s definitely something to look out for.

Posted On
Jan 16, 2012
Posted By
Brent Spiller

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.

Posted On
Jan 17, 2012
Posted By
Mark Stanger

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.

Leave a Reply


Notify me of followup comments via e-mail. You can also subscribe without commenting.

Latest Comments

  • Mark Stanger: This linkage all happens for you if you use the task survey plugin. You can look on the wiki for more...
  • Vineeth: I want a way in which if a survey is filled in by the user the response are stored in the survey response...
  • Mark Stanger: This functionality doesn’t connect to an FTP server. See this line in the post above…...
  • Mark Stanger: The report page is back-end XML so there’s no way to directly manipulate the behavior of that...