Mandatory Fields on Service Catalog Checkout Form

If you’ve used the two-step catalog checkout before you’ve noticed the few fields on the final checkout screen. Users can provide information about the Requester and their location, along with some special instructions for the processing of the request. These fields are all optional however, so there’s no way to force a user to fill any of this information out. If you did need to force one or more of these fields to be mandatory, you could accomplish this by making a couple of modifications to the ‘servicecatalog_cart_template’ UI Macro.

Service Catalog Checkout Man Field


Because we’re working in the Service Catalog interface, making a field mandatory will work a little bit differently than in other places in the system. For this modification we will intercept the submission of the form and check each field to see whether it is empty or not. This can be done by making changes to the following lines in the ‘servicecatalog_cart_template’ UI Macro.

This solution requires a modification to an out-of-box UI Macro. While it may be necessary or desirable in your environment, just be aware that once you modify it, you own it! ServiceNow doesn’t upgrade (but will support) records updated from their out-of-box config.

–In the ‘servicecatalog_cart_template’ UI Macro, change the onClick event of the submit button in this line…

<button id="sysverb_insert" class="catalog catalog_next" type="submit" value="sysverb_insert">

to this…

</button><button id="sysverb_insert" class="catalog catalog_next" type="submit" value="sysverb_insert">

–Note that in Eureka instances of ServiceNow you’ll be changing this line…

<a class="request_catalog_button" href="#" type="submit">

to this…

</a><a id="sysverb_insert" class="request_catalog_button" href="#" type="submit">

–Add the ‘checkMandatorySubmit-CatalogCheckout’ global UI script function by navigating to ‘System UI -> UI Scripts’. You can modify this function to check any field(s) on the checkout form.

This UI Macro script can be pasted directly into the ‘servicecatalog_cart_template’ UI Macro to make the ‘Special Instructions’ field mandatory on checkout.

‘checkMandatorySubmit-CatalogCheckout’ global UI script
Name: checkMandatorySubmit-CatalogCheckout
Script:

function checkMandatorySubmit(){
var manFields = '';
var si = gel('special_instructions').value;
if(si == ''){
manFields = 'Special Instructions';
}
if(manFields == ''){
gsftSubmit($('sysverb_insert'));
}
else{
alert('The following mandatory fields are not filled in: ' + manFields);
return false;
}
}

Here’s another example UI script that makes the ‘Requested for’ field mandatory for ‘ITIL’ users.

‘checkMandatorySubmit-CatalogCheckout’ global UI script
Name: checkMandatorySubmit-CatalogCheckout
Script:

function checkMandatorySubmit(this){
var manFields = '';
var si = gel('sc_cart.requested_for').value;
if(si == ''){
manFields = 'Requested for';
}
if(g_user.hasRole('itil')){
if(manFields == ''){
gsftSubmit($('sysverb_insert'));
}
else{
alert('The following mandatory fields are not filled in: ' + manFields);
return false;
}
}
else{
gsftSubmit($('sysverb_insert'));
}
}

Date Posted:

February 18, 2010

Share This:

31 Comments

  1. alli February 22, 2010 at 9:34 pm

    Hi,

    can you add other variables here? like a glide list? and pass it on the request?

    thanks

    alli

  2. Mark Stanger February 23, 2010 at 12:43 am

    It is possible, but it’s kind of tricky if you want to do a watch list. :) Here’s a link to an article describing how to add fields to the checkout form.

    https://servicenowguru.com/system-ui/adding-fi

    • alli February 23, 2010 at 7:31 am

      I tried that one, but I can’t make the glide list work

  3. Jason Stephens December 29, 2010 at 11:55 pm

    This works great. You saved me a lot of work on this one. As always – thanks Mark!

  4. Jason Stephens January 4, 2011 at 11:43 pm

    I think I may have found an issue. If I order something as an ITIL user, fill in my name, and go ahead with the order, my assignment rules will not pick up the “requested for” value. So – my task does not assign correctly. Works fine if I follow the same process as a non-ITIL user. I’m thinking the “requested for” is not populated at the time my rules are running.

  5. Ashwin March 20, 2013 at 6:15 am

    Hi,
    I tried this madification and it did not work for me. Although, I did get the message “‘The following mandatory fields are not filled in: ” .. but the request is being submitted.
    I have this modification done in a demo instance
    https://demo018.service-now.com/

    Could you please let me know if there is a way to fix this.

    Kind Regards,
    Ashwin

    • Mark Stanger March 20, 2013 at 6:23 am

      I just tested in 2 separate browsers on demo018 and it’s working perfectly for me there. The alert appears and you can’t submit the order unless you have the additional comments filled in.

      • Ashwin March 20, 2013 at 6:42 am

        Hi Mark,
        thank you for the quick reply.
        The steps I have taken is
        1. Self Service -> Service Catalog
        2. Select “New Employee Hire” under On Boarding Services.
        3. Fill in all the details and click “Choose Option” button at the bottom.
        4. Click “Check Out”
        %. Do not fill in the “Special Instructions” and click “Submit Order”.
        6. Now, we will get a alert message “The following mandatory fields are not filled in: Special Instructions”.
        7. Click OK.
        8. Now, in couple of seconds, the page will navigate to another page which says “Thank you, your request has been submitted”.

        I am currently using this in IE 9. Please let me know if I am doing something incorrect.

        Kind Regards,
        Ashwin

        • Mark Stanger March 20, 2013 at 6:53 am

          I followed the exact same steps in IE9 and it’s working perfectly for me. I don’t know what the issue is in your case, but you might try on a different computer or a different browser. There’s not much more I can do to assist you on this.

        • Ashwin March 20, 2013 at 6:55 am

          Mark,

          Just figured out that, this issue is happening in IE9 but works fine in chrome…
          Any fix you can suggest for IE9 please?

          Regards,
          Ashwin

  6. neetu July 2, 2013 at 6:36 am

    Hi Mark,

    Can we autopopulate the Requested For’s value (rather than the currently logged in user) on the checkout screen with the variable set – Requested For’s value which I am using in my order guide.

    Regards/Neetu

    • Mark Stanger July 2, 2013 at 6:42 am

      I don’t know of a simple way to do that. Even if you could, I think it would cause problems in the Service Catalog since you can have multiple request items in a request. The various ‘requested_for’ variables would potentially conflict and override each other when trying to populate the final value for the request.

      • neetu July 2, 2013 at 6:53 am

        Thanks for prompt reply!!

        My requirement is – for eg: There is an order guide – New Employee Hire (out of the box ). There is a variable named “Employee’s Name?” on form. I want to make it reference type and let the user to choose any value from it. Then, whatever the value user choose should get autopopulated into the “Requested For” field on the checkout Page.

        So Is there any way to get it work..

        Regards/Neetu

        • Mark Stanger July 2, 2013 at 6:55 am

          There’s no way to do that that I’m aware of. Order guide variables are only used to populate request item variables. You’re still going to have the problem of many request items in a cart and having them conflict.

  7. Russ Hart July 26, 2013 at 8:02 am

    Hi Mark,

    Has this stopped working on Calgary ? If I leave the requested_for empty I get the alert. But when it’s populate clicking on the submit button does nothing .. Thanks

    • Chris Haslage August 2, 2013 at 7:46 am

      Russ,

      Same here, not working for me at all in Calgary. For starters:

      – The button is not a button anymore, it’s an HTML link.
      – Adding gsftSubmit(); to checkMandatorySubmit causes an error:
      — Uncaught TypeError: Cannot read property ‘sys_action’ of undefined js_includes.jsx?v=07-22-2013_1931&lp=Wed_Jul_24_13_07_09_PDT_2013&c=5_62:10475

      I am curious if Mark has a solution for this.

    • Chris Haslage August 2, 2013 at 8:12 am

      The solution Russ is this:

      return checkMandatorySubmit(); in the button should be return checkMandatorySubmit(this);

      Then in the function, do these 2 changes:

      function checkMandatorySubmit(thiz) {

      if(manFields == ”){
      gsftSubmit(thiz);
      }

      That should work. You will have to close your browser or clear the cache. I found that out the hard way.

      • Michael Domke December 13, 2013 at 9:41 am

        The key here is that the html element must be a Button, not an anchor tag. If anyone has a solution to get the anchor tag to work I sure would love to learn what it is. It’s styling capabilities are much more dynamic.

      • Stephen Hey June 2, 2014 at 3:35 am

        This worked for me. Thanks Chris! It also appears that Mark has updated his example, but still uses the . This will also work with

  8. Nate October 23, 2013 at 1:51 pm

    I’d like to make the ‘Deliver to’ section a list of choices instead of free text. How would I go about doing this? I can’t seem to find the table containing the ‘Deliver to’ variable.

  9. Dave September 26, 2014 at 10:47 am

    Hi

    Currently on Eureka and seem to have hit a problem, when clicking on Submit its not doing anything anymore. Get the following error.

    ReferenceError: checkMandatorySubmit is not defined

    Any Ideas

    Thanks

    • Mark Stanger September 26, 2014 at 4:08 pm

      Looks like SN changed a few things in Eureka. You should be able to fix this by creating a global UI script. I’ve modified the instructions above to reflect this workaround.

      • Dave September 29, 2014 at 2:26 am

        Mark, works a treat. Thanks

  10. Paul May 19, 2015 at 5:56 am

    Have you planned any updates for this to work in Fuji without editing the base system code?

  11. Junior September 23, 2015 at 3:51 pm

    Paul, in the cart layouts, just remove the OOTB macro and create a new one, copy/pasting the OOTB macro’s contents. Then you can edit it freely without stepping on the protection levels.

    I think your issue here is that the code has further changed with fuji. Now the onlick is this: “onclick=”checkout(this, forms[‘sc_cart.do’]);””
    I’m not sure exactly what all is being done, but it definitely deviates further from what Mr. Stanger had. I am trying to figure this out myself right now, hopefully will find a solution shortly.

  12. Junior September 24, 2015 at 10:27 pm

    Okay, I got it working in Fuji. This is very long and involved, so if Mr. Stanger wants to format it to make it more pretty, that’s fine.

    First step, navigate to cart layouts and find the proper screen. I’m using the two-step, so I go to Maintain Cart Layouts -> Browser Screen -> Cart Preivew Screen (Two Step). This is the cart screen, and it’s made up of UI Macros which compose each section. Now, you don’t want to (and you cannot) update these UI Macros, or you own them. The great thing they’ve done with Fuji is make it easier to update the cart without invalidating upgrade paths, we just have to figure out the rest now. So, take the ui macro sc_cart_view_buttons at order 800. This is the footer buttons, one of which is checkout. Create a new UI Macro, and copy the XML from the sc_cart_view_buttons ui macro over to the new macro (I called my sc_cart_view_buttons_new). Now, go back to the cart screen, select Edit, and remove the sc_cart_view_buttons, then add the sc_cart_view_buttons_new ui macro. Now, make sure you set it to order 800 or 900 or whatever to have it last. Now you can edit this macro (make sure you didn’t just do insert and stay on the OOTB one or it will be protected and read only as well). So, open this macro, find the line for the checkout button:

    Change it to this:

    Notice the change in the onClick property. We are calling a function, and if that function returns true, then we perform the checkout method.

    Now, we have to capture that new function, so go to System UI -> UI Scripts, create a new UI Script. I called mine, much like Mark did above, checkMandatorySubmit. Here, you will actually check to see if the fields you want are populated. I am checking the special_instructions as well as a custom field I’ve added called sc_cart.approver. Make sure to tick the Global checkbox, and below is the code you will need:


    function checkMandatorySubmit(parm1, parm2){
    //g_form.getValue('sc_cart.approver'),g_form.getValue('special_instructions')
    //alert("Here");
    var manFields = '';
    var si = gel('sc_cart.approver');
    //alert("parm1.value is: " + si.value);
    if(si.value == ''){
    manFields = 'Approver';
    }

    var si2 = gel('special_instructions');
    //alert("parm2.value is: " + si2.value);
    if (si2.value == ''){
    if (manFields == ''){
    manFields = 'Business Justification';
    } else {
    manFields = manFields + " and Business Justification";
    }
    }

    if(manFields == ''){
    return true;
    }
    else{
    alert('The following mandatory fields are not filled in: ' + manFields);
    return false;
    }

    }

    Now, that UI Script uses GlideAjax to call a script include. You will need to create this as well. Below is the information on the script include:
    Name: cartAjaxProcessor_Custom
    Client Callable: Make sure you check this
    Script:
    var cartAjaxProcessor_Custom = Class.create();

    cartAjaxProcessor_Custom.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    updateApprover: function(){
    var approver = this.getParameter(‘sysparm_value’);
    gs.log(“Approver is: ” + approver);

    var cart = new GlideRecord(‘sc_cart’);
    cart.addQuery(‘user’, gs.getUserID());
    cart.addQuery(‘active’, ‘true’);
    cart.orderBy(‘sys_created_on’);
    cart.query();

    if(cart.next()) {
    cart.u_approver = approver;
    cart.update();
    }
    }
    });

    This script include updates the cart so that the cart will grab the new values. For the custom approver field I added, I had to add a field to the cart to hold this. Now that the cart is updated, we need to get this data over to the request. So, on the request, you create a new business rule to pull the data in from the cart. Below is the information on that Business Rule:
    Name: Set Approver from Cart
    Table: Request [sc_request]
    Insert: True
    When: before
    Script:
    function onBefore(current, previous) {
    //This function will be automatically called when this rule is processed.
    var user = gs.getUserID();
    gs.addInfoMessage(“user is: ” + user);
    var gr = new GlideRecord(‘sc_cart’);
    gr.addQuery(‘user’, user);
    gr.addQuery(‘active’, ‘true’);
    gr.orderBy(‘sys_created_on’);
    gr.query();

    if(gr.next()) {
    gs.addInfoMessage(“approver is: ” + gr.u_approver);
    current.u_approver = gr.u_approver;
    } else {
    gs.addInfoMessage(“couldn’t find cart”);
    }
    }

    This should just about do it. I hope this helps you all out, as I know that I spent a very long time figuring this all out.

    • Mike Tadder June 6, 2016 at 12:40 pm

      Junior

      I found our reply to “Mandatory Fields on Service Catalog Checkout Form” about getting this to work in FUJI. I would like to use it but you seemed to have omitted something I need. You stated

      ” So, open this macro, find the line for the checkout button:

      Change it to this:

      Notice the change in the onClick property. We are calling a function, and if that function returns true, then we perform the checkout method.”

      Can you please provide the rest of the what “Change it to this:” actually is?

  13. Junior September 25, 2015 at 12:07 am

    Okay, so I was half-way asleep whenever I posted my above post. I added a LOT more in there than just making it mandatory. To make it mandatory, all you need is to update the UI Macro, create the UI Script. That’s it. The rest is for copying fields to the cart then the request in the event you add additional fields. I couldn’t figure out how to edit my old post, so if someone can enlighten me on how to edit my own post, that would be awesome :)

    • Mike T April 22, 2016 at 3:02 pm

      Junior

      I found our reply to “Mandatory Fields on Service Catalog Checkout Form” about getting this to work in FUJI. I would like to use it but you seemed to have omitted something I need. You stated

      ” So, open this macro, find the line for the checkout button:

      Change it to this:

      Notice the change in the onClick property. We are calling a function, and if that function returns true, then we perform the checkout method.”

      Can you please provide the rest of the what “Change it to this:” actually is?

    • ND July 4, 2016 at 11:03 am

      Junior,

      Thanks for the info you’ve posted. However, there is still some piece missing in your post. You did not mention which part of the sc_cart_view_buttons macro has to be edited and how the UI script can be called from it. I’m also working over Fuji version and finding it difficult to edit the xml.

      Thanks!

  14. Mike Tadder August 4, 2016 at 6:27 am

    Mark

    I using FUJI and have read through all the postings. While Junior’s post was very helpful it appears to be missing something. I can get the checkMandatorySubmit to fire and receive the message “‘The following mandatory fields are not filled in: ” .. but the request is still being submitted.

    Any solutions for this

Comments are closed.

Categories

Tags

Loading

Fresh Content
Direct to Your Inbox

Just add your email and hit subscribe to stay informed.