Skip navigation

Coordinating application development within your organization can be like herding cats. One developer's code may collide haphazardly with someone else's, creating change conflicts that must be resolved. Developers may not be sending changes to—or retrieving changes from—a common instance. Total chaos could erupt! ServiceNow provides a number of development tools that may be the catnip to tame your development process disarray.

 

What tools does ServiceNow provide for development?

 

Team Development is another option that you may be using. In this latest installment of our best practices series, we describe how to tame this complex but powerful system by deploying changes properly.

 

What is Team Development?

 

Team Development supports parallel development on multiple, sub-production ServiceNow instances, where each instance acts as a source repository, or branch. Individual developers use separate sub-development (sub-dev) branches to work on different features, applications, or product releases at the same time. In the development environment, the sub-dev instances are peers with a common development parent (dev-parent). Changes from all developers working in the sub-dev instances are integrated and stabilized in dev-parent prior to testing and eventual release to production.

 

Best practice for deploying changes when using Team Development

When using Team Development, push changes only from sub-dev instances to a dev-parent instance. Team development functionality is not intended for pushing changes to test or production instances. To deploy changes in the production pipeline, use update sets instead:

 

Team_development.png

 

Why not push changes to test or production instances?

If it becomes necessary to back out a change on a team development instance, the backout goes all the way back down the chain, also undoing the work on the source instance. This can cause major problems on test and production instances. Update sets, on the other hand, can be backed out without affecting the source instance.

 

Also, using update sets in the test and production pipeline, as shown above, allows you to clone from production to test instances when your test users need newer data, without impacting your development process and instances.

 

For more information on Team Development, see

 

Check out the Developers Portal to learn more about the ServiceNow development tools at your disposal; no cat herding required. And in the meantime, don’t let Team Development run amok with your development process.

 

--

 

Behind the scenes here at ServiceNow, the Knowledge Management and Multimedia teams work closely with subject matter experts to disseminate critical information to our customers. We’ve found that certain topics come up frequently, in the form of best practices that can help you keep your ServiceNow instances running smoothly. This series aims to target those topics so that you and your organization can benefit from our collective expertise. If you have a best practices topic you’d like us to cover in this series, please let us know in the comments below.

 

To access all of the blog posts in this series, search for "nowsupport best practices series."

A common use case in ServiceNow is to have data driven forms that fill themselves in based input from other fields.  For example after selecting a user, fill in location fields, department fields, etc based upon the selected user's information.  This is typically accomplished using a ServiceNow client script using the out of the box g_form.getReference() function.  While this function is useful, it has its shortcomings including the ability to "dot-walk" into the referenced record's references.  For example if your form needs to display the user's location information like street, city, state, and zip, the getReference() function cannot "dot-walk" into the user's location record to gather these attributes because "location" is a reference on the user record.  The typical answer to solving this requirement is GlideAjax that includes a client side call to a server side script to gather the details and then pass it back to the client.  GlideAjax is quite useful and very powerful, however it can be difficult to setup since it requires somewhat complicated step by step instructions to make it work.

 

On top of detailed step by step instructions, GlideAjax setup is different between the desktop UI and the service portal UI.  If you are not careful, you can have GlideAjax "sprawl" where you have many script include records for point solutions.  There have been several ideas on the ServiceNow Community discussing how to solve this problem such as goranlundqvist's "Lets make GlideAjax a little more dynamic" and tim.harris's "Standardizing GlideAjax Calls to Prevent Script Include Sprawl".  Those posts have been very useful in getting people going with GlideAjax.

 

"getReferenceAdvanced" is an easier solution that is a simple function call form a client script.  In this function call, you can specify one or more attributes that you want from the referenced record including "dot-walk" attributes.  A global UI script enables this functionality on any form or service portal in your instance.

 

Note: The mobile app and UI do not support UI Scripts so this solution will not work for the app store mobile app or the mobile browser ($m.do) at this time.

 

Another challenge with GlideAjax is queries are happening server side by a system process and if you are not careful you may be exposing more data than the logged in user is supposed to have access to.  You will find many comments on the Community about this.  This solution solves that issue by using GlideRecordSecure instead of GlideRecord thus enforcing ACLs.

 

The Use Case:

I searched the Community for common use cases where the getReference function wasn't working and GlideAjax was proposed.  One customer had a form with a location reference field and the location's street, city, state, and zip needed to be filled into separate fields on the form.  Another user needed to fill in separate fields for email, department name, and department cost center's code after filling in the caller.  These are both excellent examples of where the coding to accomplish this use case can be complicated.

 

The getReferenceAdvanced solution is much simpler.  In testing, I setup a catalog item form that prompts for a "Requested For" user which is pretty typically across any type of task/case intake form.  Once the user is selected details from the user's profile are filled in below the Requested For including location and department information.  Below is a screenshot of this form indicating the source of data when the getReferenceAdvanced function runs:

 

The Code:

This solution involves several components that is available for download from ServiceNow Share: getReferenceAdvanced Client Script Function, a GlideAjax AlternativeDownload the update set from Share, load/preview/commit it, and then you can leverage it in your client scripts.

 

  • UI Script called getReferenceAdvanced: The getReferenceAdvanced* functions are part of a global UI script which make it available to a client script on any form in any scope in your ServiceNow instance.  This client script validates the data passed to it and then makes a REST web service call back to the instance to gather data.
    • For security purposes the user's security token is passed to the REST web service which prevents unauthorized access to instance data as well as enforcing ACL's for the logged in user.
  • Scripted REST API called getReferenceAdvanced: The getReferenceAdvanced UI Script passes data to this Scripted REST API that then gathers the data requested and passes it back to the client script.  A Scripted REST API was used instead of GlideAjax because calling a web service behaves the same in the Desktop UI and the Service Portal UI which simplifies the code.  This web service requires authentication for security purposes and the user's session token is used for the authentication.

 

The Setup:

The desktop UI and the Service Portal UI behave a little differently so two different function calls are provided for the two different UIs:

  • Desktop:
    • getReferenceAdvancedDesktop("REFERENCE-FIELD-NAME", "SEMICOLON-SEPARATED-LIST-OF-FIELDS-YOU-WANT");
  • Service Portal:
    • getReferenceAdvancedPortal(g_form, "REFERENCE-FIELD-NAME", "SEMICOLON-SEPARATED-LIST-OF-FIELDS-YOU-WANT");
    • Notice the getReferenceAdvancedPortal function has a third input of "g_form".  This is a required input and is basically an object containing all the details about the form being displayed.  For some reason the g_form object is not passed to the UI Script from the Service Portal like it is with the desktop UI so it is required that it is passed.

 

The getReferenceAdvancedDesktop and getReferenceAdvancedPortal return a JSON object (name/value pair) with the field requested and its value from the reference record.  Because the data is returned in an Object, all the "dots" that were passed into the function are changed to underscores so that you can call out each data element individually.  For example the value of "location.street" is stored in the "location_street" attribute within the returned object.  This data can then be combined with the g_form.setValue() function to set values on the form.

 

OK so this sound complicated, how is this simpler and how do I use it?!!  Considering use case mentioned above and the test form screenshot, the following code is used in an onChange client script to fill in the form.

 

Desktop Script:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
    
    var reqFor = getReferenceAdvancedDesktop("requested_for", "location.street;location.city;location.state;location.zip;department;department.dept_head;department.cost_center.code");
    g_form.setValue("street", reqFor.location_street);
    g_form.setValue("city", reqFor.location_city);
    g_form.setValue("state", reqFor.location_state);
    g_form.setValue("department", reqFor.department);
    g_form.setValue("department_manager", reqFor.department_dept_head);
    g_form.setValue("department_cc_code", reqFor.department_cost_center_code);    
}

 

Service Portal Script:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
    
    var reqFor = getReferenceAdvancedPortal(g_form, "requested_for", "location.street;location.city;location.state;location.zip;department;department.dept_head;department.cost_center.code");
    g_form.setValue("street", reqFor.location_street);
    g_form.setValue("city", reqFor.location_city);
    g_form.setValue("state", reqFor.location_state);
    g_form.setValue("department", reqFor.department);
    g_form.setValue("department_manager", reqFor.department_dept_head);
    g_form.setValue("department_cc_code", reqFor.department_cost_center_code);
    
}

 

As you can see in the example script, instead of making multiple getReference calls, only one was made with a semicolon separated list of the attributes needed from the Requested For's user record.  This has a performance benefit because less database calls are being made as well as huge user experience increase because the user is waiting less time for the form data to be filled in.

 

Notice the getReferenceAdvanced* call is set to the "answer" variable that is then used for the setValue() function calls.  Again each of the attributes requested using "dot-walking" are updated with an underscore but using the same name.  If only one attribute is needed from the reference record, either of the following scripts will work.  In this example the user's department's manager (dept_head) is needed:

g_form.setValue("department_manager", getReferenceAdvancedDesktop("requested_for", "department.dept_head").department_dept_head);

--OR--

var reqFor = getReferenceAdvancedDesktop("requested_for", "department.dept_head");
g_form.setValue("department_manager", reqFor.department_dept_head);

 

In order to use the getReferenceAdvanced UI script working in your Service Portal(s), you will need to configure your Service Portal Theme.  As specified by James.Neale in this Community Article:

  1. Navigate to Service Portal\Themes and select your theme.  If you are using the OOB Service Portal, click Stock.
  2. Scroll down to the "JS Includes" Related List and click New.
  3. Set the name to getReferenceAdvanced or whatever makese sense to you, Source should be set to UI Script and then select the getReferenceAdvanced UI Script and click Submit.
  4. Repeat steps 1-3 if you have multiple Service Portals that need this capability.

 

Error Handling/Troubleshooting:

To make this as painless as possible to setup, error handling has been set in the getReferenceAdvanced UI Script.  These alert popup messages will appear when testing your client script:

  • If you call getReferenceAdvanced* in your client script and forget to specify a reference field, you will receive the following message: The getReferenceAdvanced() function requires a field to be passed.
  • If you call getReferenceAdvanced* in your client script and is NOT a reference field, you will receive the following message: The getReferenceAdvanced() function only works with reference fields.  The field specified is not a reference field.
  • If you call getReferenceAdvancedPortal in your client script and you don't pass the g_form object, you will receive the following message: The getReferenceAdvanced() function requires the g_form object to be passed from the Service Portal.  Please pass that as the first parameter.
    • Remember that Service Portal client scripts (Type is Mobile/Service Portal) require you to use the getReferenceAdvancedPortal() function and the first parameter needs to be g_form as shown on the example scripts above.
  • If you call getReferenceAdvanced* in your client script and you don't pass the fields needed from the reference record, you will receive the following message: The getReferenceAdvanced() function requires a string of field(s) you wish to return.
  • If you call getReferenceAdvanced* in your client script and the field passed does not have a value, you will receive the following message: The getReferenceAdvanced() function requires the field 'FIELD-NAME' to have a value.


Please mark this post or any post helpful or the correct answer so others viewing can benefit.

free-portal.png

Thank you to everyone that was able to attend our CreatorCon breakout at Knowledge last week. It was great finally meeting so many of you.

Due to overwhelming demand, we are releasing the Presentation and Update Set for the theme we built during the breakout. To keep things simple, I’ve rebuilt the Update Set to not modify any of the out-of-box records and instead create new records. Also keep in mind this theme only styles the homepage and does not alter the content or layout.

Click here to get access to the theme: https://serviceportal.io/free-service-portal-theme/

--------------------------------
Nathan Firth
Principal ServiceNow Architect
nathan.firth@newrocket.com
http://newrocket.com
http://serviceportal.io

Sitting here at the table, trying to take in all the emotions and knowledge that was gathered in Knowledge 17. It's been a ride, and sadly not enough time to meet everyone I wanted to meet.

 

Remember also that this is written when comparing to Istanbul release.

 

I held a round table about what obstacles you might run into when moving from CMS to Service Portal and some solutions for them. Since I didn't have any PowerPoint or similar, I promised to do a blog post about my findings. And before moving on. This is not a post about all nice features of Service Portal. I'm only highlighting the issues that you might run into moving from CMS to Service Portal.

 

I would also recommend that you try to see the move as a "portal 2.0" and not just a clone from CMS to Service Portal. You got a totally different tool set at your disposal, so be sure that you know what it can do so you don't miss a great opportunity to take you portal to the next level.

 

Beneath I will mention something I call "normal" UI and compare it to Service Portal. When I talk about Service Catalog and "normal" UI I'm talking about this:

 

 

General things:

  • Is there a migration tool or a clear path?
    • Nope, sadly not. No one button to press. The path isn't so clear either and depending how customized/complex you CMS portal is, you got a quick migration or a very tough one.
  • Do I still need to know Jelly?
    • It's gone, for the positive side, most of all see this as a real nice thing. But it also gives you a real headache if you have done a lot of customization in Jelly. all these needs to be redone for the portal. I recommend that you first of all go through the functionalities that exists in OOB widgets, and go from there. Remember that there is many more OOB widgets in Istanbul than Helsinki and I bet there will be even more/better ones in Jakarta that is coming out soon. Also remember that the variable type "Macro" has a UI Macro connected to it, and that will of course not work since it uses Jelly. A little more about it further down in the Service Catalog section.

 

  • How does it work with mobile devices and this "responsive" pages people are talking about?
    • Yes, Service Portal has the responsive/mobile in it's mind. You will easy get a portal that renders the pages after what device/resolution is used to access the portal.

 

  • Iframes, do we use them in the portal?
    • You might need it still for some more complex stuff. But for easier things like lists, forms etc. there are even OOB widgets to handle these.

 

  • Dynamic blocks then with my nice layout and code?
    • Nope, you will need to redo all this. most of the stuff is in Jelly and the other stuff is mainly built in widgets. Some code might be reusable in the Server Scripting and for example CSS.

 

  • I still use IE9 on my client computer!
    • Well, Service Portal needs new version than IE9 to get the angular to work. But there is other places in ServiceNow that also uses angular, which will give you problem. But I would also say that there is bigger problem than ServiceNow if clients still using IE9 which Microsoft stopped supporting quite a while ago.

 

  • How about the URL, will that be the same?
    • URL to the start page will be the same, if it's decided to keep it. For sub pages and stuff(ex. KB article) it will be changed. So if you got URLs referring to different parts of you CMS, these needs to be updated. Also remembers you might has notifications etc. that has a link that isn't correct for the Service Portal.

 

  • Contextual search, I love it. Is it there?
    • Well, yes and no. From the start, it didn't work. Now there is a patch from HI to make it pretty good(Link here), but leave some room for improvements. No idea how it looks like in Jakarta. There is also a few versions of this done by other companies, but haven't seen anyone for free yet.

 

  • We have multiple CMS sites for different users, can I have that in Service Portal as well?
    • You can, OOB ServiceNow redirect all logged on "none role" users to one specific portal. This can be customized so depending on your parameters the user will get redirected to different portals. I wrote a quick post about it HERE. You can also make a more clever portal that just changes looks depending on the user as well. A bit more complex, but might be the correct way to go.

 

Service Catalog:

  • I heard there is only one Catalog per Portal, is that true?
    • Yes, that is true. OOB there is only support for one portal. Here you need to think of how the design for the whole enterprise would look like. Should you have multiple portal and more "OOB" or should you start customize OOB Widgets to handle more than one catalog? There are both pros and cons for both solutions and I think there is probably a couple of hydrid version etc. as well of the two examples I have. Example with multiple Portals is that the search will only be in the specific portal the user is at. Istanbul has added "search sources" which gives your the opportunity to make the search go outside the specific portal and can be uses to search in multiple. But when you want the user to be able to browse multiple catalogs at the same time, you need to customize the OOB widgets for displaying this.

 

  • You mention variable types about, is there more to know?
    • Yes, there is quite a few things here:
      • Macro: As I mention above, in CMS you could have UI Macros connected to the Macro variable. They don't work in Service Portal since it doesn't support Jelly. A good thing is thou that the variable now has a widget field where you can redo the same functionality in a widget and connect it to the same macro. What to remember here is that if you got variables that are going to be used on items that are used on both Service Portal and the "normal" UI, you need both UI Macro and Widget. This since the Widget won't work in the "normal" UI and vice versa. Which means you perhaps should think of having fullfillers etc. also use the catalog in the Service Portal "view" instead of maintaining both a widget and UI Macro.
      • Other Variable types: Variables behave different depending on they are shown in the Service Portal or the "normal" UI. For example in the "normal" UI you can use a container to expand/collapse the variables inside the container like this:

        And on Service Portal the option to expand/collapse is gone and you also see the thin gray line is gone as well:

        If you go to the documentation for variable types you can see that some types has the text "The Xxxx variable is yet not supported on service portal and mobile devices". This doesn't mean that it don't work at all, but it might have a different look or functionality.

      • Help Text: There are also other things that behave different and the help text is one of them. In the "normal" UI it is a nice expand/collapse feature with some blue background like this:

        and on Service Portal it is suddenly a grayed out text like this:
  • So, how about Order Guides?
    • Order Guides works like they should, besides the variable type issue mention above. But there is one major change when comparing to the "normal" UI and it's the layout. "Normal" UI has a tabbed format of the Order Guide while the OOB widget has all items in a vertical row.

  • Do I need to do anything with my Catalog Client Scripts & Catalog UI Policies?
    • You probably will. Simple stuff will probably work, but there is a few things to think about:
      • UI Type needs to be set to either "All" or "Mobile / Service Portal". If not, it won't load in the Service Portal. But switching over to "mobile" also means that for example your GlideForm API get reduced since the mobile version doesn't have all the nice features the normal one has. Here is a link to the Mobile GlideForm API
      • DOM Manipulation using stuff like $, jQuery doesn't work and need to be replaced. Same thing goes for getControl, getElement etc.
      • If you got some variable sets that all items use. Perhaps it's an idea to put this into the widget it self. Always make sure it's what you really want and need.

 

  • So, how do I test if the things work?
    • Well, first of all. Don't use the "Try it" button. Things might work when you go test through the "normal" UI but not in the Service Portal. Then you have the other way around as well, since variable type macro with widgets won't work in the "normal" UI..
      Then of course since client scripts and UI Polices works different depending on how you access them, test them on the places they will be used. And do that also since the variables them self might look difference depending on where you access them as well.

 

Knowledge

  • Only one Knowledge per portal as well?
    • Yes, here is just the same issue as for the Catalogs with the same thoughts and pros & cons.

  • How about public Knowledge, is that doable?
    • With Service Portal it's a lot easier to have a knowledge public(user not needed to login to search it)

  • Where did copy permanlink go?
    • It's gone. But on the other hand you can easy just copy the URL from the browser instead. Just remember that if you have old links to the knowledge base, they won't point to the new Service Portal.

 

Thats about what I have for the session and what came up while we talk. If you got more things, please post it in the comments and I'll add it.

 

//Göran

 

sn-community-mvp.pngSymfoni Logo Color Box.jpg

//Göran

ServiceNow Witch Doctor and MVP
-----------------------------------
For all my blog posts: http://bit.ly/2fCzj1g

By default, all end users logging in can be redirected to a specific portal. OOB this is the portal with the suffix "sp".

 

Many users has risen the demand to be able to redirect end users to different portal depending on specific parameters. In this post I will give you a simple example how to redirect the end user to a different portal depending on which company they belong to. I believe that after this, you should be able to use the same way to setup your own conditions and reuse the rest of the code.

 

So sit back, get your coffee and press play =)

 

 

//Göran

 

Symfoni Logo Color Box.jpgsn-community-mvp.png

//Göran

ServiceNow Witch Doctor and MVP
-----------------------------------
For all my blog posts: http://bit.ly/2fCzj1g

Finally I got sometime to finish off the Multiple Catalog series. In this part let's delve into search and breadcrumbs.

 

As we know the OOB Homepage and typeahead Search widget supports only single catalog. In order to support the search for multiple catalogs, we need to clone typeahead search widget and give an unique name to widget id.

 

And in server script getCatalogItems function need to updated.

 

function getCatalogItems() {

  var catalogs = [];

  var sc_cat = new GlideRecordSecure('sc_catalog');
  sc_cat.addQuery('active', true);
  sc_cat.query();

  while(sc_cat.next())
  {
  catalogs.push(sc_cat.sys_id.toString());
  }


  var sc = new GlideRecord('sc_cat_item');
  sc.addQuery(textQuery, data.q);
  sc.addQuery('active',true);
  sc.addQuery('no_search', '!=', true);
  sc.addQuery('visible_standalone', true);
  sc.addQuery('sys_class_name', 'NOT IN', 'sc_cat_item_wizard');
  sc.addQuery('sc_catalogs', catalogs);
  sc.query();

  var catCount = 0;
  while (sc.next() && catCount < data.limit) {
  if (!$sp.canReadRecord(sc))
  continue;

  var item = {};
  if (sc.getRecordClassName() == "sc_cat_item_guide")
  item.type = "sc_guide";
  else if (sc.getRecordClassName() == "sc_cat_item_content") {
  var gr = new GlideRecord('sc_cat_item_content');
  gr.get(sc.getUniqueValue());
  $sp.getRecordValues(item, gr, 'url,content_type,kb_article');
  item.type = "sc_content";
  }
  else
  item.type = "sc";

  $sp.getRecordDisplayValues(item, sc, 'name,short_description,picture,price,sys_id');
  item.score = parseInt(sc.ir_query_score.getDisplayValue());
  item.label = item.name;
  data.results.push(item);
  catCount++;
  }
}

Once this widget is created, use the new widget ID in homepage search widget

 

data.typeAheadSearch = $sp.getWidget('new-typeahead-search', typeAheadSearchOpts);

 

Once the widget is successfully created use the new typeahead search widget across all the pages.

 

Breadcrumbs

 

To point the correct breadcrumbs we have update the client controller in following widgets

  • Multi SC categories widget that was created earlier
  • SC Category Page widget
  • SC catalog Item widget

 

Here is the sample script for multi SC categories client controller

 

var bc = [{label: 'Catalogs', url: '?id=multi_catalog'}];

 

if ($scope.data.sc_catalog) {

bc[bc.length] = {label: $scope.data.catalog_name, url: '#'};

}    

$rootScope.$broadcast('sp.update.breadcrumbs', bc);

 

 

 

This concludes multiple catalog functionality in Service Portal.

 

 

Previous Blogs in this series

Portal diaries: Service Portal – Multiple Catalogs (Part 1)

Portal diaries: Service Portal – Multiple Catalogs (Part 2)

I don't like using a real user's credentials when setting up a new Remote Instance (or Update Source) record:

 

 

This can become a problem when the user changes their password or changes positions internally or even leaves the company entirely.  You would then have to change the Remote Instance record for each of your instances.  Usually the person who creates the record ends up using their own credentials because it's easier and faster to do so, but it's not the best way.  Creating a new user and assigning them the "admin" or "teamdev_user" roles just gives them more access than what is needed. Creating a service account with just the right access will save you from future headaches.  For more information about service accounts, see this post - User account or service account? What to use for web service tasks.

 

Spoiler alert - I've attached an Update Set XML export to save you from creating the records manually, but wanted to describe what needs to be done anyways.

 

I create a new User record with the following details:

User ID - #update.sets.integration

First name - Update Sets

Last name - Integration

Password - follow your established security rules to create a secure password

Active - checked

Web service access only - checked (important)

 

Checking the "Web service access only" check box will only allow that "user" to login to the instance using API calls and not into the regular user interface.

 

The next thing to do is create a new Role called "u_update_sets_integration".  Once you save the new record, add the "soap_query" Role as a Contained Role so that users with the new Role will inherit the "soap_query" Role as well:

 

 

Once you do that, assign the new Role to the "Update Sets Integration" user:

 

Next, you need to assign the "u_update_sets_integration" Role to two different Access Control records, one each for the "sys_update_set" and "sys_update_xml" tables.  You can use the following URL to find the appropriate ones (change "instancename" to your own name of course):

https://instancename.service-now.com/sys_security_acl_list.do?sysparm_query=GOTOname%3Dsys_update_set%5EORname%3Dsys_upd…

 

You need to add the "u_update_sets_integration" Role to the Requires Role Related List for both of the Access Control records:

 

The last thing you need to do is update the Remote Instance record with the new credentials.  There will, however, be an issue when you try to save it:

 

ServiceNow will validate the credentials are correct and will verify what roles the user has in the remote instance instead of verifying if it can perform the required operations.  So you will have to temporarily give the Update Sets Integration User the "teamdev_user" role.  You can remove it once the Remote Instance record has been updated.

 

So now you have a user with just the right amount of access to import your Update Sets and it should not count as a licensed user (always check with your ServiceNow sales rep).  Obviously performing all these steps manually does not make sense and would negate any gains this would give you so you should use the attached Update Set XML file instead.  Import it into your personal dev instance to see all the records that are created and feel comfortable with the changes before adding it to your instances.

 

And don't forget to change the password for the new User record if you import the attached XML file (it is blank in the Update Set).

*** Please Like and/or tag responses as being Correct.
And don't be shy about tagging reponses as Helpful if they were, even if it was not a response to one of your own questions ***

Jim Coyne

"Try It (Portal)" Tool

Posted by Jim Coyne May 4, 2017

Here's "Try It (Portal)", a new tool in my useful tools series.  It's a "Form button" UI Action that will open up a new tab/window and load the current catalog item within the Service Portal:

_Screenshot.png

It's very similar to the OOB "Try It" UI Action that redirects the current window to the catalog item, but this one will open the Service Portal in a new tab/window for you.  There's nothing really special about it, but it saves you from loading the portal and trying to find it in order to test it out.

 

UI Action details:

Name: Try It (Portal)

Table: Catalog Item [sc_cat_item]

Order: 100

Action name: u_try_it_portal

Active: checked

Show update: checked

Form button: checked

Client: checked

Onclick: u_tryInPortal()

Hint: View this item within the Service Portal (opens a new tab/window)

Condition: current.active == true && new CatalogItemTypeProcessor().canTryIt(current.getRecordClassName()) && !(current.getRecordClassName() == "sc_cat_item_content" && current.content_type == "external")

 

Script:

function u_tryInPortal(){
  //view this item within the Service Portal in a new tab/window
  window.open("sp?id=sc_cat_item&sys_id=" + g_form.getUniqueValue(), "_blank");
}

 

If your Service Portal has a different URL suffix, just change the "sp" on line 3 to whatever is appropriate for your instance.

 

The condition is basically the same as the OOB "Try It" UI Action except I removed "current.canWrite()" because this UI Action is not performing a save.

 

I've attached an XML export of my UI Action record if you want to just import that.  Try it out in a personal dev instance first.

 

Related Posts:

"Developer Toolbox" Tool

"Preview GlideRecord Script" Tool

"Preview in Background Script" Tool

"Xplore GlideRecord Script" Tool

"View Data to Preserve" Tool

"Create Module From Query" Tool

"Clear User Settings" Tool

"Grab Grouped Information" Tool

Showing a Schema Map From a List View

*** Please Like and/or tag responses as being Correct.
And don't be shy about tagging reponses as Helpful if they were, even if it was not a response to one of your own questions ***

If any scoped application developed depends on a plugin then that is tracked as part of dependency.  Dependency is a must for scoped applications that are submitted to the ServiceNow store. This is to ensure that customers who purchase the scoped application are aware of all the prerequisite plugins to be installed prior to installing the app on their instance. In this blog, I will talk about when a dependency is tracked automatically in a scoped application and steps to capture dependencies manually

 

How to automatically track plugin dependencies

The system can automatically identify and add dependencies on the plugin when you:

  • Extend a table
  • Add a field to a table
  • Call a script include

 

For example, let's assume I have activated "Facilities Service Management" plugin on my instance. As part of my scoped app use case, I need to create a custom table "Now Fac Space" and extend it from the OOTB table "Facility Space" (the table which was created when we activated FSM plugin).

 

  1. Create a custom table "Now Fac Space" and extended from Facility Space

    create custom table.jpg

  2. Navigate to System Application>Application>Click on Edit button under application "Now application" and check for related list "Dependencies"

    dependencies.jpg

You will note the dependency on the plugin "Facilities Service Management" is automatically tracked and is captured as part of dependency list in scoped app "Now application". The reason the dependency is tracked automatically here is because we extended an OOTB table which belongs to "Facilities Service Management" plugin.

 

How to capture Plugin Dependencies manually

The system cannot identify dependencies on client-side resources such as UI-based JavaScript libraries. In such cases, you must manually add the dependency. Below are the steps to be followed to add dependency manually.

 

For example, let's assume I have to capture the "orchestration" plugin dependency manually in my scoped app "Now application".

 

  1. On your instance navigate to System Applications>Studio
  2. Click on open Studio tab.

    Studio+servicenow.jpg

  3. Now select one of the applications from the list (for example, Now application)

    code+search+application.jpg

  4. Click on File>Settings.

    Screen Shot 2017-04-25 at 2.04.56 PM.png

  5. From the Dependencies related list, click Edit and select the exact dependency from the left slush bucket and move it to right and save the form. For ex: added "Orchestration" plugin as a dependency.

    dependencies related list.jpg

 

Wooo we have successfully added "Orchestration" plugin as a dependency in scoped application. There will be message warning on the screen with the name of the prerequisite plugin to be installed when the customer tries to install this application on his instance.

 

Global dependency is not captured as a dependency in any application because global artifacts can be created by the user on any instance manually

 

The same steps apply in case a manual dependency is to be captured on any scoped application.

 

We have successfully covered how a dependency is tracked automatically and how to capture dependency manually in scoped application. If any scoped application intended to be published on the store and has a dependency on plugins, vendors have to make sure that all required plugins are captured as part of dependencies in scoped application. This is to ensure that customers who purchase the application from the store are aware of all the prerequisite plugin before installing the app on their instance.

- Pradeep Sharma (@sharma_pradeep)
ServiceNow

PS: Hit like, Helpful or Correct depending on the impact of the response

Filter Blog

By date: By tag: