Embedding widgets in Service Catalog

In Service Catalog you have the ability to embed a UI Macro as a variable in your catalog items or record producers. UI Macros are based on Jelly and as such they will not render in Service Portal. To work around this, you can now embed a widget for your UI Macro variables when displaying your catalog in Service Portal.

In this example, we’re going to create three variables, and make the third variable a widget that will display the sum of the other variables. Create a catalog item with the following variables:

  • Single Line Text: “value1”
  • Single Line Text: “value2”
  • Macro: “results”

On the “results” variable record, you will see a “Default Value” tab, with a reference to the Widget. Create and select a new widget called “Embedded Results”, and use the following values:


Client Script:

Now when you view this catalog item in the portal, the embedded widget will display the results of the two variables:


Note, that the “field.change” event fires when the field loses focus, so you will have to tab or click out of the field to see the results.



  1. Hi Nathan,

    Similar to $rootScope.$on(“field.change” ,function(evt, parms) Is there any way to write something like $rootScope.$on(“onsubmit”, function(evt,params){}); I want to do some validation before submit.

  2. Hi Nathan,
    Is it possible to reverse the process?
    Meaning that I will enter data in the widget and after that the widget will update the variable?
    Lior grinberg

    1. Hi Lior (& Nathan),

      I have the same requirement as you, i.e. the reverse of what Nathan describes here, did you manage to find a way to do it?



  3. Hello Nathan,
    I am using one widget inside another widget.

    I have cloned the catalog item widget and inside am using a macro field and calling the another widget for dynamically add the data.

    I want to make the dynamic row mandatory based on the catalog item variable. How can be achieved?


  4. Hi Nathan,

    I have a question regarding to this Macro variable that you created on the catalog item above ‘results’. After you fill out the form and submit the ticket, the Macro variable doesn’t show on the Variable Editor in Requested Item form. It shows only the first two (value1, value2) variables. Do I need to configure anything else to display Macro variable with the ‘Default Value’ as embedded Widget? Is this a ServiceNow bug? What is your thought?

    Thank You,
    Henry Pech

    1. The embedded widget is only available in Service Portal and the rest of the platform will not be able to render or access the value from it.

      1. First thank you for you quick response Nathan. This is a disadvantage for Service Portal comparing to CMS. CMS allows Macro and Macro with Label variables to be displayed on the Requested Item form in the Variable Editor formatter. Is there a workaround to achieve this goal with the embedded widget?

        Thank you,
        Henry Pech

  5. Hi I was just wondering, when doing this is there a way to send default values for the options schema of the widget, ie does the ‘default value’ field get passed to the widget ?

    I would like to be able to pass values to initialise the widget when using the macro variable type. This way I can create one widget and have it display / behave differently based on the options schema.

    If I could get at the default value in the server script I could write the code to read it and initialise the options accordingly?

  6. What if one of the custom fields you created is mandatory.

    How does your submit/buy now button in the parent widget get this custom fields label and append it to the OOB Submit button message?

  7. Hi Nathan,

    How would you deal with persistence if you wanted to store this value and later (say in a workflow) wanted to do something with it?

  8. Hi Nathan,
    I have made use of this logic for implementing one of requirements in service catalog from my client.But i am facing a problem here.
    To get the input value to the server side i am using c.server.update() in the client controller.And i am able to get the value too.
    But after submitting the item,the values i have entered is getting disappeared in the RITM form after submission.

    Could you please help me on this.

    I have put this code in “SC catalog item” widget which is a global widget for displaying catalog item forms in the portal.

    Below is the code i am using :

    Client controller :
    $rootScope.$on(“field.change”, function(evt, parms) {
    if (parms.field.variable_name == ‘request_for’) {
    c.data.ServiceRequested = parms.newValue;
    c.server.update().then(function(data) {
    c.data.ServiceRequested =undefined;

    Server side :
    if(input.ServiceRequested!=””) {
    var gr = new GlideRecord(“u_catalog_approval_routing_details”);
    gr.addQuery(“u_catalog_item”, data.sys_id);
    if (gr.next()) {

    1. Without seeing your environment with your tables and workflows, it’s impossible for me to answer this as it could be a thousand different things. However glancing at your code quickly… it doesn’t look like your updating anything on the GlideRecord.

      These types of questions are probably better suited for the community, as it’s very difficult to read big blocks of code in the comments section.

  9. Hi. I have implemented this and it is successfully running in an instance of Istanbul release but not running in London release.in th London instance in serviceportal, the catalog variable name is coming like “IO:SYS_ID of the variable”. i think this is the reason why it is not running in London instance. any solution for this problem?????
    Thanks in advance.

    1. Yes, ServiceNow changed the field name format in London. Just use console.log() to determine the new field names and update the script.

  10. I tried this with 2 variables and it worked great. I added a 3rd and 4th variable and it will not fire. Is there a limit on the # of variables that can be used?

    function hours ($rootScope) {
    var c = this;
    $rootScope.$on(“field.change”, function(evt, parms) {
    if (parms.field.variable_name == ‘saturday_hours’) {
    c.data.saturday_hours = parseInt(parms.newValue);
    if (parms.field.variable_name == ‘sunday_hours’) {
    c.data.sunday_hours = parseInt(parms.newValue);
    if (parms.field.variable_name == ‘monday_hours’) {
    c.data.sunday_hours = parseInt(parms.newValue);
    if (parms.field.variable_name == ‘tuesday_hours’) {
    c.data.sunday_hours = parseInt(parms.newValue);
    c.data.total_hours = (c.data.saturday_hours + c.data.sunday_hours + c.data.monday_hours + c.data.tuesday_hours);

  11. This was a good article. The updated about London was very helpful as well.

    What other events can be monitored for besides “field.change” ? Looking for documentation on this and cannot find anything.

  12. Hello
    In your example,
    parms.field.variable_name doesnt return the name of the variable but IO:sys_id of this

Leave a Reply

Your email address will not be published. Required fields are marked *