Collaboration Store, Part XXXIV

“The key is not to prioritize what’s on your schedule, but to schedule your priorities.”
Stephen Covey

So far, we have completed the first two of the three primary components of the project, the initial set-up process and the application publication process. The last of the three major pieces will be the process that will allow you to install an application obtained from the store. Before we dive straight into that, though, we should pause to take a quick look at what we have, and what still needs to be done in order to make this a viable product. At this point, you can install all of the prerequisites and then grab the latest Update Set, install it, and go through the set-up process to create either a Host or Client instance. Once you get through all of that, you are ready to publish any local Scoped Application to the store, which will then be shared with all other instances in your Collaboration Store community.

What you cannot do, just yet, is to find an application published to the store by some other instance and install it on your own instance. That’s the missing third leg of the stool that we will need to take on next. But that is not all that is left to be done. Once we get the basics to work, there are quite a number of other things to address before one could consider this to be truly usable. Some things are just annoyances, but others are definite features that you would have to consider essential for a complete product.

Speaking of annoyances, one of the things that I really don’t like is that when you publish an app to XML for distribution, the resulting Update Set XML does not include the app’s logo image. Clearly it is a part of the app, and if you push an app to an internal store and pull it down into another instance, it comes complete with the logo, so why they left that out of the XML is a mystery to me. I don’t like that for a couple of reasons: 1) when you pull down the XML for this app, you do not get the logo, and 2) when we use the XML to publish an app to the store, the logo is missing there as well. I have seen people complain about this, but I have not, as yet, seen a solution. I would really like to address that, both for my own apps as well as for the process that we are using in this one.

Speaking of logos, another feature that I would like to have is to provide the ability for each instance to have its own distinctive logo image, so that everything from that particular instance could be tagged with that image as a way to visually identify where the app originated. That’s not a critical feature, which is why I did not include it initially, but it has always been something that I felt should be a part of the process, particularly when you start thinking about ways to browse the store and find what you are looking for. That’s definitely on the We-will-get-around-to-it-one-day list.

Browsing the store is another thing that will need some attention at some point. Right now, we just want to prove that we can set-up the app, publish an application, and install an application published by someone else. Those are the fundamental elements of the app. But once we get all of that worked out, being able to hunt through the store to find what you want will be another important capability to build out. We’re not done with the fundamentals just yet, so we don’t want to put too much energy into that issue right at the moment, but at some point, we will need to create a user-friendly way to easily find what you need.

That, of course, leads into things like searchable keywords, tags, user ratings, reviews, and the like, but now is not the time to head down that rabbit hole. Still, there are a lot of possibilities here, and this could turn into a life-long project in and of itself. That’s probably not a good thing, though!

Anyway, we won’t get anything done if we don’t focus, so we need to stay on task and figure out the application installation process. Once again, there are several options available, but the nicest one seems to be the process that you go through to install an app from an internal store. That’s basically a one-click operation and then the app is installed. Unfortunately, that particular page is neither Jelly nor AngularJS, so you can’t just peek under the hood and see the magic like you can with so many other things on the Now Platform. Another option would be to hack up a copy of the Import XML Action on the Update Set list page to push in the attached XML from a published app version, but that only takes things so far; you still have to Preview the Update Set, resolve any issues, and then manually issue the Commit. It would be much nicer if we could just push a button and have the app installation process run in the background and notify you when it was completed. Obviously, we have some work to do here to come up with the best way to go about this, and we had better figure that out relatively soon. Next time, if we are not dealing with test results from the last release, we will need to start building this out.

Portal Widgets on UI Pages

“Our life is frittered away by detail. Simplify, simplify.”
Henry David Thoreau

There are two distinctly different environments on ServiceNow, the original ServiceNow UI based on Lists, Forms, and UI Pages, and the more recent Service Portal environment based on Widgets and Portal Pages. The foundation technology for UI Pages is Apache Jelly. The foundation technology for Service Portal Widgets is AngularJS. From a technology perspective, the two really aren’t all that compatible; when you are working with the legacy UI, you work in one technology and when you are working with the Service Portal, you work in the other.

Personally, I like AngularJS better than Jelly, although I have to admit that I am no expert in either one. Still, given the choice, my preferences always seem to tilt more towards the AngularJS side of the scale. So when I had to build a modal pop-up for a UI Page, my inclination was to find a way to do it using a Service Portal Widget. To be completely honest, I wanted to find a way to be able to always use a widget for any modal pop-up on the ServiceNow UI side of things. That way, I could hone my expertise on just one approach, and be able to use it on both sides of the house.

The solution actually turned out to be quite simple: I created a very simple UI Page that contained just a single element, an iframe. I passed just one parameter to the page, and that was the URL that was to be the source for the iframe. Now, that URL could contain multiple URL parameters to be passed to the interior widget, but from the perspective of the UI Page itself, all you are passing in is the lone URL, which is then used to establish the value of the src attribute of the iframe tag. There are two simple parts to the page, the HTML and the associated script. Here is the HTML:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
	<iframe id="portal_page_frame" style="height: 400px; width: 100%; border: none;"></iframe>
</j:jelly>

… and here is the script:

var gdw = GlideDialogWindow.get();
var url = gdw.getPreference('url');
document.getElementById('portal_page_frame').src = url;

The script simply gets a handle on the GlideDialogWindow so that it can snag the URL “preference”, and then uses that value to establish the source of the iframe via the iframe’s src attribute. To pop open a Service Portal Widget using this lightweight portal_page_container, you would use something like the following:

var dialog = new GlideDialogWindow("portal_page_container");
dialog.setPreference('url', '/path/to/my/widget');
dialog.render();

That’s it. Simple. Easy. Quick. Just the way I like it! If you want a copy to play with, you can get it here.

Update: There is an even better way to do this, which you can find here.