Parse URL Parameters in a Client Script

Home/Scripting/Client scripts/Parse URL Parameters in a Client Script

Parse URL Parameters in a Client Script

H

ere’s a useful script I’ve used before to grab parameters from a URL in Service-now.com. Simply pass the name of the parameter into the function and it will return the corresponding parameter value.

So if you had a Service-now.com URL that looked like this…
https://demo.service-now.com/incident.do?sys_id=-1&sysparm_query=active=true&sys_myparm=abcde

You could get the value of the ‘sys_myparm’ URL parameter by calling the function below like this…

var myparm = getParmVal('sys_myparm');

Here’s the ‘getParmVal’ function…

function getParmVal(name){
    var url = document.URL.parseQuery();
    if(url[name]){
        return decodeURI(url[name]);
    }
    else{
        return;
    }
}

I’ve often used this to automatically populate catalog variables based on a redirect URL. For example, if I were redirecting to a catalog item and I wanted to pass in a couple of variable values I could construct my URL like this…

var url = 'com.glideapp.servicecatalog_cat_item_view.do?sysparm_id=e826b8c50a0a3c1e019410bb1031d102' + '&sysparm_category=hardware' + '&sysparm_comments=Hello World!!!';

This URL contains 3 major pieces of information…

  1. Pointer to the catalog item – identified by item sys_id (‘com.glideapp.servicecatalog_cat_item_view.do?sysparm_id=e826b8c50a0a3c1e019410bb1031d102’)
  2. A parameter containing a category value (‘&sysparm_category=hardware’)
  3. A parameter containing a comments value (‘&sysparm_comments=Hello World!!!’)

By passing parameters in through the catalog item URL you can use an ‘onLoad’ catalog client script (set against the item or a variable set) to pull those parameters out and populate them into your catalog item variables like this…

function onLoad() {
   //Populate the variables with the parameters passed in the URL
   //Use the 'getParmVal' function below to get the parameter values from the URL
   var cat = getParmVal('sysparm_category');
   var comments = getParmVal('sysparm_comments');
   if(cat){
      g_form.setValue('my_category_variable',cat);
   }
   if(comments){
      g_form.setValue('my_comments_variable',comments);
   }
}

function getParmVal(name){
    var url = document.URL.parseQuery();
    if(url[name]){
        return decodeURI(url[name]);
    }
    else{
        return;
    }
}

When working in the Service Portal, ServiceNow severely restricts the objects available for use in client scripts, causing scripts like this to break. Brad Tilton provided this workaround on the ServiceNow community for the ‘getParameterValue’ function that is designed to work around this issue.

function getParameterValue(name) {  
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");  
    var regexS = "[\\?&]" + name + "=([^&#]*)";  
    var regex = new RegExp(regexS);  
    var results = regex.exec(top.location);  
    if (results == null) {  
        return "";  
    } else {  
        return unescape(results[1]);  
    }  
}

Please note that this code snippet should be used within a client script or catalog client script on a form you’re rendering through the Service Portal. If you’re working within a widget and want to use a url parameter you would want to use angular’s $location service.

By | 2017-03-01T06:49:58+00:00 October 14th, 2010|Categories: Client scripts|Tags: , , |53 Comments

About the Author:

53 Comments

  1. Matt Gaide October 25, 2010 at 4:39 pm - Reply

    I often use RP.getParameterValue(parameter name) in conditions for UI actions as well as other places.

  2. Craig Varrichio April 13, 2011 at 6:43 am - Reply

    In many circumstances you can also either use action.getGlideURI() or gs.action.getGlideURI() as well. Here’s a snippet from one of my UI Actions:

    var uri = action.getGlideURI();

    var parentCollectionID = uri.get(‘sysparm_collection’);

    var currentParentID = uri.get(‘sysparm_collectionID’);

    • Mark Stanger April 13, 2011 at 9:54 am - Reply

      Thanks for the tip. This would work in a UI action, but I’m not sure that it would apply to client scripts. Is this something that works in client scripts as well?

  3. Blair July 25, 2011 at 11:41 am - Reply

    Mark,

    I want to pass in a few variables on an order guide. However, I want the order guide to open in an IFrame within the CMS. Is this possible?

  4. Andrew Wilmut February 29, 2012 at 4:58 pm - Reply

    Hi Mark,
    What about the left nav? When I add: ‘nav_to.do?uri=’ to the URL it no longer works??

    https://instance.service-now.com/nav_to.do?uri=com.glideapp.servicecatalog_cat_item_view.do?sysparm_id=29b5a6ad0a0a0b5200d0125d6c0053c8&sys_myparm=de

    • Mark Stanger February 29, 2012 at 6:33 pm - Reply

      I’ve never had to deal with that scenario since ‘nav_to.do’ always redirects to the URL without the frames. I wouldn’t think that it would come up much because of that.

      • solution January 29, 2016 at 10:32 am - Reply

        URLs may come in like this: https://XXXXX.service-now.com/&sysparm_input=Approved
        OR they may come in like this: https://XXXXX.service-now.com/nav_to.do?uri=%26sysparm_input=Approved

        NOTE: If using “nav_to.do?uri=” (which loads the record inside the ServiceNow frame) as in the second example above, you must use “%26” (the URL-encoded character “&”) before the custom sysparm.

        this is because the nav_to.do page/processor/thing seems to strip any sysparms from the url before passing it into the frame. Normally the processing of any sysparms would be done by scripts sitting in the frame html, at least that’s my guess.

  5. Tom Brown October 31, 2013 at 9:01 am - Reply

    I see how that works, and I’ve attempted to do the same with one of my service catalog items. However, I continue to get a ‘Not Authorized’ window when I try a link with a parameter in it. Here’s the URL I’m trying:

    https://.service-now.com/com.glideapp.servicecatalog_cat_item_view.do?sysparm_id=ebaf65dc0a0a3c49009a3135931427c1%26account=jqpublic

    I saw the ‘not authorized’ before I added the client script, so I don’t think I’m even getting to the ‘onload’ part to call it. I’m sure it’s something basic, but I can’t find a reference to it in this context. If I remove the %26account=jqpublic, then it loads the item with the fields blank, as it should.

    • Mark Stanger October 31, 2013 at 9:10 am - Reply

      Try just an ‘&’ symbol instead of ‘%26’.

      • tom brown October 31, 2013 at 9:41 am - Reply

        Ack. That was it. Serves me right for not starting from scratch. Thank you very much for the script and the reply!

  6. Phil January 27, 2014 at 6:54 am - Reply

    Hello, for some reason my script won’t pass the parameter to the url if there is a space in it. For example, I am passing first name and last name to corresponding first name and last name variables. If you enter in first name field a name like “Tom”, and last name “Brady”, works well. If you enter ” Tom” or “Tom Joesph”, it will not populate the parameter for first name. Any ideas?

    function onLoad() {
       //Populate the variables with the parameters passed in the URL
       //Use the 'getParmVal' function below to get the parameter values from the URL
       var first_name = getParmVal('sysparm_first_name');
       var last_name= getParmVal('sysparm_last_name');
       if(first_name){
          g_form.setValue('first_name',first_name);
       }
       if(last_name){
          g_form.setValue('last_name',last_name);
       }
    }

    function getParmVal(name) {
       name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
       var regexS = "[\\?&]"+name+"=([^&#]*)";
       var regex = new RegExp(regexS);
       var results = regex.exec( window.location.href );
       if(results == null){
          return "";
       }
       else{
          return unescape(results[1]);
       }
    }
    • Mark Stanger January 27, 2014 at 8:09 am - Reply

      The first step I would take would be to alert out the value of that URL parameter to see exactly what it contains. I suspect that the spaces in the name need to be escaped in some way. If it’s just spaces you might just use a javascript replace function to replace the spaces with ‘%20’. You can google for how to do that. You might also be able to encode it using something like this when you’re creating the URL.

      var first_name = encodeURI(current.first_name);

  7. Ujjwal Kumar April 30, 2014 at 11:32 am - Reply

    Hi Mark,

    I have a requirement where the customer wants to open a catalog item directly through a link in an email. The url must contain some added field values which will be used for populating data on the catalog form(on load). We have 2 scenarios here-

    1. If the user has already logged in the Service now instance and then he uses the url. The form loads perfectly and the fields get autopopulated.
    2. If the user has not logged in and then he uses the url. He is redirected to login page . after providing the login credential the catalog form loads but the fields are not getting autopopulated. Also, I could find that the url is getting truncated in this case.

    The url contains this structure : https://instance_name/com.glideapp.servicecatalog_cat_item_view.do?sysparm_id=6737a0b88171d90071a8e2c1496753a0&asset_sysid=1cfc1ee6815a954071a8e2c1496753c2&ci_type=xyz&update_required=Yes

    Please help in finding the issue.

    Thanks,
    Ujjwal

  8. MG July 7, 2014 at 8:20 am - Reply

    Does this have to be a Catalog Client Script or can it be just a normal client script?

    • Mark Stanger July 7, 2014 at 8:59 am - Reply

      Works just as well on a standard form using a standard client script. Just replace variable names with field names.

    • Mark Stanger July 7, 2014 at 11:39 am - Reply

      Looks like it’s the encoding of ‘%26’ in your URL. That’s a ServiceNow thing, but you should just have to replace all of those characters with a standard ‘&’ to eliminate that error.

  9. Erik Myrold July 23, 2014 at 11:49 am - Reply

    Hi Mark,

    Would this work with Record Producers as well?

    So on a change form (with a client script) be able to parse and stuff params from URL into a record producer variable?

    thanks,

    -e

    • Mark Stanger July 23, 2014 at 5:19 pm - Reply

      Yes, it should work exactly the same way on a record producer.

  10. Bryan August 4, 2014 at 3:03 pm - Reply

    Hi Mark,

    Thanks for all your great posts. I noticed that when I try to use this in an UI action that redirects to a service catalog item, it does not grab the sysparms. (probably because the actual url is masked/removed when the record producer loads?) Thanks again!

    (
    ui action – form link
    client = false
    update = true
    )
    script:
    var id = current.sys_id;
    var url = ‘https://[instance]/com.glideapp.servicecatalog_cat_item_view.do?sysparm_id=983e58a46f91a10023bd5965bd3ee483&u_par_req=’ + id;

    action.setRedirectURL(url);

    • Mark Stanger August 4, 2014 at 3:09 pm - Reply

      I think you need to take out the ‘https://[instance]/’ portion from your URL. A relative link should work just fine there and should maintain the link parameters. You might try logging it out in your client script to see what the URL is on your record producer.

    • Bryan August 4, 2014 at 3:12 pm - Reply

      To follow up, I alerted out the url from the getparmval function from your on load script and it returns null.

      • Bryan August 5, 2014 at 11:09 am - Reply

        Turns out the culprit was our TinyUrl system property. Thanks for the great script!

  11. Scott January 8, 2015 at 3:12 pm - Reply

    We use this to carry the short description and a couple other values across. We’ve noticed that if the short description contains a special character (most commonly a # or &) the special character and everything after that is excluded. Is there a simple fix to this?

    • Mark Stanger January 8, 2015 at 3:16 pm - Reply

      Check out my response to Phil in the comment thread. It talks about encoding the information, which should help.

  12. Alex Wells January 26, 2015 at 10:23 am - Reply

    There is an API built into the DOM which allows you to get query parameters on the client without doing any of your own regex-ing:

    var x = document.URL.parseQuery()

    Try this from a console in your browser of choice, it’ll return a map of key/value pairs corresponding to the query params. Then you can just lookup the param you want with the usual javascript object access:

    x[‘sysparm_name’]

    for instance.

    • Mark Stanger February 6, 2015 at 10:23 am - Reply

      Alex, thanks for the great feedback and sorry for the delay in getting back with you on this. Your solution is much cleaner so I’ve adjusted the code above to leverage it instead!

  13. JM May 15, 2015 at 10:48 am - Reply

    Does this method work with a GlidePaneForm? I am trying to pass parameters into the new GlidePaneForm to pre-populate fields, but alert(window.location.href) returns no parameters.

    UI Action:
    var dialog = new GlidePaneForm(‘new_item’, ‘incident’);
    dialog.setTitle(“New Incident”);
    dialog.setSysID(-1);
    dialog.addParm(‘sysparm_view’, ‘Add’);
    dialog.addParm(‘sysparm_tid’, ‘Test TID’);
    dialog.addParm(‘sysparm_form_only’, ‘true’);
    dialog.render();

    Client Script (onLoad):
    alert(window.location.href);
    var tid = getParmVal(‘sysparm_tid’);
    alert(tid); // is blank

  14. V K July 24, 2015 at 9:04 am - Reply

    HI Mark,

    This may be unrelated to this post – I landed here as I was looking for an earlier post for a solution you had proposed for being able to tell the context of a service catalog request. I want to be able to tell if a request for a catalog item is coming via an order guide or otherwise (standalone request). i believe, in that post you talk about the getGlideURI method and being able to leverage the fact that the URL for an order guide always contains certain keywords. If all this information is enough to ring a bell, could you please redirect me to where I need to be?

    • Mark Stanger July 24, 2015 at 9:39 am - Reply

      I’m not sure exactly what you’re looking for, but here’s all of the content I have on order guides.

      https://www.servicenowguru.com/tag/order-guide/

      • V K July 24, 2015 at 1:19 pm - Reply

        Thanks for the response Mark! There was a post which talked about how the URL had a certain keyword everytime the request is a standalone request versus one that comes via an order guide. That was we can tell context of the origin of a request

  15. Matthew October 27, 2015 at 8:59 am - Reply

    Mark,
    The above seems to work when the catalog item is being called using the standard user interface (non-cms). How would this work using CMS?
    Thanks!
    Matthew

    • Mark Stanger October 27, 2015 at 9:07 am - Reply

      Should work the same way in the CMS as long as the parameters are included in the URL.

  16. Matthew October 27, 2015 at 1:03 pm - Reply

    hey Mark,
    Quick follow up. The only change I had to make was on this line:
    var url = document.URL.parseQuery();

    Since our CMS is built on iframes, we had to change this to:
    var url = top.document.URL.parseQuery();

    Example url:
    https://myurl.com/catalog.do?sysparm_document_key=sc_cat_item,1234567890abcdefghijklmnop?&sysparm_accomplish=peter&sysparm_needed=griffin

    Thanks for the great article!

    • Erik Stolberg April 6, 2016 at 4:39 pm - Reply

      If the record producer/catalog item is within an iframe and you call the top page URL with parameters, in addition to the “top.document…” change, I had to use “top..g_form.setValue()” to set form values.

    • Andrea August 5, 2016 at 3:54 pm - Reply

      This one piece is exactly what I was missing! We also use iFrames, and my getParmVal alert kept returning undefined. Thank you for posting your solution Matthew, and thanks to Mark for your awesome script.

  17. Beth May 31, 2016 at 12:58 pm - Reply

    An interesting side note:

    I needed something similar to this but far more flexible. I’ve implemented this code on one of our very complex, frequently-changing offerings, and so far it looks to be working well. It iterates through the provided URL parameters and tries to match based on the key of the parsed object. Obviously everything hinges on the parameter name, but so far it looks like g_form for invalid variable names fails gracefully and moves on to the next variable.

    Just an interesting variation that might be of interest if you need something a little more ‘set it and forget it’.

    function onLoad() {
    url = document.URL.parseQuery();

    //attempt to load the rest of the items by iterating through the url object
    for(var key in url) {
    //discard any sysparms
    if(key.toString().indexOf(“sysparm”) < 0){
    var val = url[key];
    g_form.setValue(key,val);
    console.log("Key: "+key+" value:"+val);
    }
    else{
    //console.log("Key Skipped: "+key);
    }
    }
    }

  18. Cassidy August 25, 2016 at 1:02 am - Reply

    Hi Mark.

    Great tutorial and the code works great, i run into a few problems though, which I hope you can help me with.
    I can only execute this code from the Google Chorme Dev console, and only if i choose the iFrame as the context. Is there any way to execute this, coming from another page?

    • Mark Stanger August 25, 2016 at 5:26 am - Reply

      It should work from anywhere, as shown in the final catalog client script. In some cases, you need to introduce a bit of a delay to the client script using ‘setTimeout’ to make sure the page is loaded before your client script attempts to run. You can google ‘javascript settimeout’ for some examples of how to use that.

  19. Tom March 1, 2017 at 2:14 am - Reply

    Hi Mark,

    Thank you for this great tutorial. I am trying to get this working on the mobile application, but the getParmVal method does not work on the native app. Do you have a workaround for this?

    Thanks in advance,

    Tom

    • Mark Stanger March 1, 2017 at 6:51 am - Reply

      Thanks Tom. Unfortunately, ServiceNow’s Service Portal and Mobile apps don’t support any of this type of custom scripting very well. I’ve posted a potential workaround at the bottom of the article. It should work in Service Portal but I’m not sure about the mobile app. Please give it a try and see.

  20. Lisa Silvaroli May 16, 2017 at 6:22 am - Reply

    Please excuse me as this topic is very new to me but I am trying to achieve the same results. I’m not understanding where to find the URL… any more direction you can give would be greatly appreciated!

    • Jim Pisello July 14, 2017 at 10:18 am - Reply

      Hi Lisa,

      The URL can be found in your web browser’s address bar.

  21. Lisa Silvaroli July 17, 2017 at 8:01 am - Reply

    I am using:
    javascript:
    var answer = RP.getParameterValue(“sysparm_user”); answer;

    It is passing the user but displaying the sysID – is there a way to get it to display the display name?

  22. Terryio April 12, 2018 at 9:44 am - Reply

    Thanks, it works perfectly in service portal.

Leave A Comment