Adding Fields to the Service Catalog Checkout Screen

Adding Fields to the Service Catalog Checkout Screen

I‘ve written before about some customizations that can be made to the catalog checkout screen in ServiceNow. The catalog checkout screen gives users one last opportunity to review their order and provide some additional details about the overall request before submitting an order. One common customization request I’ve heard before is to add additional fields to this checkout screen.

This article is an extension of an idea presented on the ServiceNow wiki that shows one way to approach this problem. The solution described here overcomes some of the problems with the wiki solution and gives a little bit more detail about how the solution works so that it’s easier for you to customize on your own. I’ll also include some formatting examples and show how you can add more than one additional field to the checkout screen.

This article describes an advanced customization that requires edits to an out-of-box UI Page and UI Macro. While it is possible (and often necessary) to make these types of edits, you should be aware that modifying these records prevents ServiceNow from upgrading them in the future.

Add your new field(s) to the checkout screen

1Modify the ‘servicecatalog_cart_template’ UI Macro as follows…
Look for the section of code that has hidden input elements (designated by ‘input type=”HIDDEN”‘) and insert the following line directly after the other hidden elements. This line of code is used to store the unique cart ID for the user session. This ID will be referenced later on in a UI Page client script.

If you need to add multiple fields you can do so by adding the appropriate html. It’s also pretty simple to change the layout of the fields and their columns if you understand a little bit about html tables. Here’s an example that shows how to add two fields (Company and Requested Date) to the checkout form in a 2-column layout.

You may have noticed the ‘ui_reference’ and ‘ui_date’ lines in the code above. These lines actually reference UI Macros by those names. The UI Macros are a great way to set up fields on a UI Page like this without having to set up all the specific pieces of the field element. There are several UI Macro field elements you can utilize out-of-box. These can be found by searching the UI Macros table for elements that start with ‘ui_’.

Passing the field values to the catalog cart and request

2Add the following script to the ‘Client Script’ field on the ‘servicecatalog_checkout_one’ UI Page (note that this sample is for the 2-field checkout addition and you’ll need to modify this script on the ‘var newField1’ and ‘var popVal’ lines if you’re only using one field). Its purpose is to get the values from the new checkout fields as they change and send them to the request ticket when the request is generated. You’ll want to pay attention to the separators used here to designate when a new field/value pair starts. The underlying code reserves some characters in this situation so I made a judgment call based on what I thought would work most of the time. The bottom line is that these need to match what you look for in the business rule in the next step.

If you need to add additional fields to your checkout page you’ll need to customize this function to include those additional field/value combinations.

//If found, add the field/value pairs to the 'hints' parameter for the cartif(cart_item.next()){//Aggregate all of the field-value pairsvar popVal ='company'+ nameValSeparator + newField.value+ fieldSeparator +'requested_date'+ nameValSeparator + newField1.value;//Send the values to the request record
cart_item.hints="<hints><entry key='sysparm_processing_hint' value='setfield:request.u_cartpop="+ popVal +"'/></hints>";
cart_item.update();}}

If you’re just adding a single field to the checkout page (and have no plans to potentially add more fields) then you could simply modify the script above to eliminate the ‘u_cartpop’ and ‘popVal’ pieces all together. These pieces exist for the sole purpose of passing multiple field/value pairs on to the request. If you just need a single field, comment out the first ‘popVal’ line, change ‘u_cartpop’ to the name of the field on the request form you need to populate, and use the single field example included in step 1 above.

If you are looking for a more extensible solution that you could add to in the future, or if you already know that you will need more than one field added to the checkout form, read on!

Populating the field values

—This final portion is the major piece that I’ve changed from the solution described on the ServiceNow wiki. The whole purpose of these last steps is to allow you to populate more than one field on the request ticket. The ‘hints’ parameter in the UI Page client script above only accepts a single name/value pair to set. To work around this limitation, the script above concatenates all of the name/value pairs and passes them in as a single string to a custom field you need to create called ‘CartPop [u_cartpop]’.

3Create a new string field on the Request [sc_request] table named ‘CartPop’.
The field will be used to capture the field/value pairs string being passed from the checkout page. It should have a length that is long enough to accommodate all of the field/value pairs being passed in from your checkout page. A 1000 character limit should be more than enough to pass in values from several additional fields. This field can be removed from the request form once it is created.

4Create a new business rule on the Request [sc_request] table with the settings as shown below. The purpose of the business rule is to get the value of the ‘u_cartpop’ field, parse the field/value pairs out of it, and populate those values into the correct field(s) on the request record.

If you’ve done everything correctly you should be able to order a catalog item, view and populate your new fields on the checkout form, and see those fields populated on the Request record as shown here…

Validating checkout fields / Making checkout fields mandatory

One last step that you may need to take is to make sure that certain checkout fields are filled out or validated before submission. I’ve written about how to do this in a separate article found here.

34 Comments

I can’t make this work for the Watch List. I tried it a few different ways and finally asked SN because I kept getting “undefined”. They told that it wasn’t possible with the watch list at this time, and it would be a fix in a future release. I wanted to mention this because I didn’t want anyone to fight with it as long as I have and not realize this….

I wanted to say thank you for this post. I demoed this today to our ESS team and they loved it. I only had one question come up – is there any way to make the submit not happen if the reference value in the field is not valid? We are using this functionality to get around the watch list issue I noted in my earlier comment, and our field is referencing the sys_user table. I can type Joe Blow if I want and still submit successfully. Is there any kind of “check” I can add to this to force the value to be valid before submit? Thanks again – this is a great post.

You would have to validate the contents of that field before submission. In order to do that, you would have to override the submit function with a custom check of your own on that field. This is the same thing you would do if you wanted to make checkout fields mandatory. This article shows you how that could be done.

Well – I’m not really interested in making it mandatory – I just want to validate that the value is legitimate. Since it is pulling from the user record, I want to validate that the value is an actual user name and it will be valid when it is copied to the watch list. I realize I’m stretching it, I just thought it may be possible.

I understand that, but the process you would go through would be the same. The simplest way to do what you’re wanting to do is to check the value of the field on submit to see if anything is there. If the field has a valid value, it will store the sys_id of the referenced record.

I need to hide a field from catalog check out screen but, I do not want to modify OOB UI macro (If I touch it, Service-now will not upgrade this piece this from the next upgrade). Where should I run a ‘onLoad’ script, so when it runs, on the fly we hide unwanted fields etc.

The only way to do this without editing the UI macro is to create a global UI script and hide the fields using client-side scripting. While this is possible, I don’t know that I would really recommend it as a better solution since the global UI script would have to run on every form load in your entire system. You can make it pretty lightweight so that it doesn’t really impact anything, but it’s not something you’ll want to make a habit out of. Your global UI script would need to look something like this…

addLoadEvent(hideCheckoutFields);function hideCheckoutFields(){//Check to make sure we are on the checkout page if($('sc_cart.do')){try{//Remove cart stuff here...}catch(e){//alert('Error'); };}}

I have used this technique to add an approver field to the check out page. I use the value entered to populate a “Department Approver” field on the sc_request record. (I am using the ‘simple’ method of setting a single value on the request rather than the more complex method you describe here for populating multiple fields.

It works fine if I create the request as an admin user. If I do it as an itil or end user, the value does not propagate through to the sc_request record. I know that the setCartValue() client script function is working, as I can go and see the cart_item.hints field is set with the correct text.

Do you have any idea why this value would not get propagated through to my target field? I have checked ACLS, and the user can write the target field on the request record. The instance has the high security plugin enabled, and I went and set the “Security manager default behavior in the absence of any ACLs on a table” to “Allow” just in case, but that made no difference.

Do you have any idea what would be stopping this value propagating for any but admin users?

It sounds like it’s definitely security-related then. I would set up a test against an instance that isn’t running the high security plugin if you can just to see if it works there. If it’s a high security issue then I’m not sure what the issue might be for sure. You might have to contact someone to take a closer look at your instance to see what’s going on.

Margie,
I just ran into the same issue with the High Security plugin enabled. I was using mutiple added fields on the checkout screen and this technique would not work for non-admin users. I also tried different ACL options, and could not find the right combination to make it work. I eventually modified the code to use an GlideAjax script. Here is how I did it.

UI Page: servicecatalog_checkout_one
Info: I did a couple things different. I am not using the “onchange” event on the fields. My fields are actually pre-polpulated. If someone didn’t change them I wanted to still get the pre-populated info. So the “observe” watches for you to click the “Submit Order” button.
Client Script:

BUT I have a little addition when using Michael Browns Script Include: You need to check the checkbox “Client callable”, otherwise it won’t work.

P.S.: If found a simple way to check required fields on the checkout before submitting, also by using the Client Script field and slightly modifying the submit button. And now with the “observe(‘click’, );” method I have even a better idea! I will create a thread once I completed it.

For some reason, we occasionally have a request get created without the information from the checkout screen. It’s as if the hints field never gets updated, even though we force setting the value on any changes to any field, as well as upon submission. The biggest headache is we can’t reproduce it at-will to find the root cause. I’m thinking it may be a timing issue or race-condition. Have you seen this behavior before?

It’s been awhile, but I FINALLY figured out why custom fields added to the checkout screen may not get passed to the request. The root cause is order guides that aren’t fully submitted (user didn’t click Check Out).

When you click Choose Options in an order guide, inactive items are added to the cart (sc_cart_item), one for each item that passes the rule base conditions. They will become active, but only have clicking Check Out. However, if you navigate away form the order guide to a different catalog item without clicking Check Out, the inactive items remain in the cart. If other items are later added to the cart and then the user goes to checkout, there will still be a mix of both active and inactive items in the cart. So when this runs:

I’m having an intermittent issue with this code. I’ve created the AJAX solution since we are using the high security and I’ve added the cart_item.addQuery(‘active’, ‘true); to the ajax. We are also on Eureka, if that makes a difference.

I added gs.logs to the ajax as part of my debugging and found that the uid and popVal are being filled in. I’m not always getting a log statement from in the query before setting the cart_item.hints. So it seems like it’s not always getting the cart_item.

Have you seen this happen before? Is there anything else I should check out in the system?

Ok, I think I’ve found a pattern. One of the added fields is a choice list. It seems if I visit the field on the checkout screen, then this works, but if I don’t visit the field (tab to it or click on it), then this breaks. I don’t have the “none” value turned on for the choice list because I don’t want the order to be submitted with a choice being made.

I know this is an old post but it’s still relevant and we’re on Eureka.

Tim,
I have the same problem as you and here’s what I did to fix it.

On the Client Script section of the UI Page: servicecatalog_checkout_one, add the following line at the end:
addLoadEvent(sendHintsToCart);

Essentially I’m updating the cart as soon as the checkout page loads. I’m also adding onChange event calling the same function for each of the variables.

This is a proactive approach rather than reactive i.e. waiting for click. The cart is being deleted after submission so it’s probably a timing issue. We’re trying to update the cart while it’s being deleted.

I notice that the fields are all reference fields. Is there anyway to make a select box referencing a table for its list of options? I’ve been trying to create this and can’t figure it out. The second part would be triggering a second box with based on the selection of the first.

The example above uses a reference field and a date field. You can use a choice field using one of the ‘ui_choice’ macros. You may have to try a few things to get it working just right but other field types are possible.

They’ll be added to the Request record, but you can personalize the request item form and get to the information by drilling into the ‘Request’ field. You could also use a business rule to copy the information from the parent request to the child request items if you want.

I see the line inthe script, “value=’setfield:request.u_cartpop=”, and I assume that I would just sub in “sc_req_item” where it says “request”, but that does not work. The main issue we are having is that we will have separate work order numbers for each requested item, and I need to be able to copy those over to the requested item level.

I have it working as in your example, only issue is with the multiple variables.

Hi guys,
I created a free text field with ‘ui_input_field’.
We are using the field so the requester can enter the name of a new user (its free text as the new user would not be on the system yet so we cant look it up)
However, I find that when a name contains an apostrophe the screen just hangs. for example. John O’Brien.
Has anyone else seen this?

I am not changing anything with the new cart layout process but adding this solution into it. I get as far as executing the setCartValue client script. However, no data is being passed to Request. I have triple checked everything, so I am wondering if the new cart process is conflicting or something is still not right in my setup.

How would I do this with the new cart layout process in Fuji and Geneva?

I tried your solution that the cart value newly added additional fields are not working for non admin users.

Can you please explain me, the use of first two lines in the below script, since you have mentioned that it will work while clicking on order now button, for my case, it has to work, when I click on “Check out” Button.

Do you know why companies like Amazon, Zappos, Southwest Airlines, or the plumber in the next town keep getting more business from consumers like us? The answer is quite simple. It’s because they provide exceptional customer service every chance possible. Their entire brand is built on the promise of great service. Sounds easy, right? On […]

We are excited to announce the official release of our new book, 10 Pillars of ServiceNow Success for CIOs. The book is an educational resource to guide CIOs and their teams on their journey to transforming their organizations using ServiceNow. The 75-page book discusses best practices derived from more than 500 ServiceNow implementations—all aimed at […]

Famous leaders on the world stage have struggled to articulate a vision to gain the kind of mass support that changes history. Without a clear and consistently communicated vision, momentum for the cause...

Welcome to Part X of Crossfuze’s 10 Pillars of ServiceNow Success for CIOs blog series! First, a story to illustrate the challenge of fully integrating your ServiceNow ecosystem: Kyle is an experienced CIO...

Welcome to Part IX of Crossfuze’s 10 Pillars of ServiceNow Success for CIOs blog series! First, a story about the universal, pervasive challenge of demand management: Jason is a veteran CIO who has made many friends and allies within his company by being a “yes man.” He bends over backward to fulfill everyone’s IT service […]

Since 2009, ServiceNow Guru has been THE go-to source of ServiceNow technical content and knowledge for all ServiceNow professionals. Whether you're a new admin or a seasoned consultant, you're guaranteed to find quality solutions that will aid you in your ServiceNow journey!