SNH Data Table Widgets on Share

“The first time you do a thing is always exciting.”
Agatha Christie

I’ve never used Share before, but after completing the work on the Aggregate List Columns and bundling that work up with all of the other related projects and artifacts, I decided that I would go ahead and post the whole thing out there. I have always hesitated to throw stuff from here out there, mainly because most of the things that you will find on this site are not very well documented, at least not from the user’s perspective. But, I have considered doing it anyway on a number of occasions. I was pretty close to sharing the My Delegates Widget until I discovered that someone else had already beat me to it. I also thought about tossing out a number of other items such as the Dynamic Service Portal Breadcrumbs and the Service Portal Widget Help, but like quite a number of other things, those were just thoughts that never turned into any kind of action. This time, though, quite a number of things were all bundled together into a single Update Set, and I thought that maybe there just might be a thing or two buried in there somewhere that someone somewhere might find to be of value. We’ll see.

My other hesitation to posting this on Share was the fact that these are all Service Portal components, and ServiceNow has made it pretty clear that they would like to see folks abandon the Service Portal in favor of their latest approach to application development. While it may be true that the Service Portal is on the way out, it has been my experience that such transitions usually take some time to be fully realized, so there still may be an active Service Portal or two floating around out there for a while. Still, everyone always likes to jump on the new stuff, so the interest in Service Portal components is something that is bound to start dropping off over time. On the other hand, that actually serves as an argument for shoving it out there now, as waiting around would just mean even less relevance to the environment of the future.

Anyway, it’s done now. Share obviously has a much broader reach than this little blog, so it will be interesting to see if anyone happens to come across it out there with all of the other artifacts on the site. I did take a quick peek this morning, and it does look like a couple of brave souls have already hit the download button, but I don’t see any feedback posted as yet. That will probably take a little more time. Who knows; if it all works out, maybe one day I will throw something else out there. Only time will tell.

@mentions in the Ticket Conversations Widget, Revisited

“Continuous improvement is better than delayed perfection.”
Mark Twain

When I hacked up the Ticket Conversations Widget to add support for @mentions, I knew that a number of people had already asked ServiceNow to provide the same capability out of the box. I also knew, though, that these things take time, and not wanting to wait, I just charged ahead as I am often prone to do. However, I was happy to hear recently that the wait may not be all that much longer:

Hi,

The state of idea Service Portal – @Mention Support has been marked as Available

Work for idea is complete and planned to be released in the next Family version

Log in to Idea Portal to view the idea.

Note: This is a system-generated email, do not reply to this email id.
If you would like to stop receiving these emails you can change your preferences here.

Sincerely,
Community Team  

I am assuming that the “next Family version” is a reference to Quebec, although I have nothing on which to base that interpretation. It’s either that or Rome, so one way or another, it appears to be on the way. If and when it does arrive, I will gladly toss my version into the trash and use the real deal instead. I don’t mind building out things that I want that the product currently doesn’t provide, but as soon the product does provide it, my theory is that you fully embrace the out-of-the-box version and throw that steaming pile of home-grown customized nonsense right out the window. I actually look forward to that day.

But then again, that day is not today! Not yet, anyway.

Update Sets

“Good order is the foundation of all things.”
Edmund Burke

I’m starting to get quite the collection of various Update Sets from all of the little parts and pieces that I have been playing around with lately, so I decided to try to get a little organized and create a space for them all in the hopes of making it a little easier to hunt down what you might be looking for. You can see the result here. I also added a link to the header menu bar to make it easier to find.

I collected all of the different versions of each little project under a single title, which also serves as a link to the introductory article on the related subject. It’s not in any particular order, so you still might have to do a little nosing around to find anything specific, but at least everything is in one place now, and you can see all of the multiple versions of things together in one spot. It’s not much for style, but it’s functional, so that’s enough effort invested into that little project for now.

Parts is Parts

“Parts is parts.”
Wendy’s TV commercial

I love making parts. One of the reasons that ServiceNow is such a powerful platform is that it is built on reusable parts, and the platform encourages the development and use of reusable parts. I have known a number of developers who are extraordinary coders that can lay down reliable code at an amazing rate of speed, but no one can code faster than they can pull an existing part down from a shelf. When you build a part in such a way that you can reuse it again in another context, you not only solve your current problem, but you also create the solution for problems that you haven’t even encountered yet. That doesn’t just improve productivity, it also increases reliability. Parts on the shelf are on the shelf because you have used them somewhere before, and if you’ve used them before, then you’ve tested them before, which means that you’ve already gone through the exercise of shaking out all of those initial bugs. Faster and better — it’s a win/win.

When I started my Highcharts experiment, my goal was to create a reusable component for displaying any Highcharts graph. I was able to do that with my Generic Chart widget, but in the process, I also ended up showcasing a number of the other little parts and pieces that have been developing on the Now Platform. For example, when I wanted to add the ability to click on the chart and drill down to the underlying data, I ended up linking to my enhanced Data Table widget. I actually built that to support my configurable content selector, but once created (and tested) and placed on the shelf, it was there to later pull down, dust off, and utilize for other, previously unforeseen purposes.

To make the various selections for the four different parameters used in the workload chart, I ended up using the angular provider that I put together to produce form fields on the Service Portal. I didn’t create that to support the workload chart, but once it was created, there is was on the shelf to pull down and put to use.

I built my dynamic Server Portal breadcrumbs because I really didn’t like the way that the out-of-the-box breadcrumbs widget required you to pre-define the trail of pages displayed by the widget. That philosophy assumes that each of your pages can only be reached through a single path. For someone who likes to build and leverage reusable parts, this just seemed a little too restrictive to me. This was yet another “part” that I had build with my content selector in mind, but which was equally useful once I started linking out from my workload chart. In fact, it was while working with my workload chart that I discovered a flaw in my breadcrumbs widget. That’s another nice thing about working with reusable parts: when you fix a problem, you don’t just fix it for your purposes; you fix it for everyone else who is using it for whatever other purpose. That’s the difference between cloning and reusing. If you clone a part and find a flaw, you fix your copy, but the original and any other clones are unaffected. If you reuse a part and fix a flaw, you fix it for everyone.

That’s why I love making parts.

Retina Icons

“Simplicity is the ultimate sophistication.”
Leonardo da Vinci

I was thinking about doing something with the form-field-addons that are a standard part of a ServiceNow UI form, and so I started looking at some of the ones that are currently in use on some of the existing forms. That led me down a path of looking into the source for the various icons used, which eventually led me to this:

https://community.servicenow.com/community?id=community_blog&sys_id=925eaaaddbd0dbc01dcaf3231f961940

According to this blog entry, you just add /styles/retina_icons/retina_icons.html to your existing instance URL and you can see them all. So I did:

Full list of Retina Icons

Pretty cool … that gets the little wheels turning just a bit …

Service Portal Form Fields

“Everything begins with an idea.”
Earl Nightingale

Even though I tend to prefer the Service Portal environment over the original ServiceNow UI, the one thing that you just can’t beat on the original side of the house is the built-in support for form fields. As soon as you create a Table in ServiceNow, a corresponding form is also created, built using a generic infrastructure that is driven off of the embedded data dictionary. Every field on the form is formatted in a consistent way using consistent components supporting consistent features. So far, I have not seen anything comparable to that in the Service Portal environment.

On a standard ServiceNow UI form, every field on the page will have the same set of standard elements based on the same basic template, customized to the specifications of the specific field as contained in the data dictionary. For example, here is the HTML from the Incident ID field on the Incident form:

   <div id="element.incident.number" class="form-group " style="">
      <div class="" data-type="label" choice="0" type="string" id="label.incident.number" nowrap="true"><label onclick="return labelClicked(this);" for="incident.number" dir="ltr" class=" col-xs-12 col-md-3 col-lg-4 control-label"><span id="status.incident.number" data-dynamic-title="" mandatory="false" oclass="" class=" label_description" aria-label=""></span><span title="" class="label-text" data-html="false" data-original-title="">Number</span></label></div>
      <div class="col-xs-10 col-sm-9 col-md-6 col-lg-5 form-field input_controls">
         <div ng-non-bindable="" class="hidden"><input id="sys_original.incident.number" name="sys_original.incident.number" value="INC0010037" type="hidden"></div>
         <input id="incident.number" name="incident.number" aria-required="false" onchange="onChange('incident.number');" maxlength="40" value="INC0010037" style="; " autocomplete="off" ng-non-bindable="" class="form-control" spellcheck="false" type="text">
      </div>
      <div class="col-xs-2 col-sm-3 col-lg-2 form-field-addons"></div>
   </div>

Looking through the code, you can spot a number of unique standard elements, each with its own specific purpose, and many with a standard ID:

  • element.incident.number
  • label.incident.number
  • status.incident.number
  • sys_original.incident.number
  • incident.number

So, in theory, it seems as if you could use the above block of HTML as a guide and set up some kind of AngularJS component to replicate that entire concept over on the Service Portal side of the house. Unfortunately, I’m not all that familiar with AngularJS, but it sounds like an interesting challenge. Who knows … maybe someone has already put this together. Surely someone smarter than I am has already thought of doing this, and maybe has already figured all of it out. Even if that’s true, it would still be fun to try on my own. You know what I always ask myself: how hard could it be?

It works!

“The main thing is to keep the main thing the main thing.”
— Stephen Covey, The 7 Habits of Highly Effective People

Since the moment that it first came out, I was a big fan of Steve McConnell‘s Code Complete. The idea that there was a right way and a wrong way to code things made perfect sense to my binary-centric way of looking at the world. Clean, precise, elegant, and efficient code is admirable goal, and it’s right up there near the top of my list of things for which I should always strive.

But it’s not at the very top.

Like Abraham Maslow‘s Hierarchy of Needs, some things are just more equal than others. My #1 requirement of my code is, was, and always will be passing this simple test: Does it work? Once we clear that threshold, we can make it pretty. We can make it clean. We can make it efficient. We can even make it elegant and stylish and amazingly beautiful. But only if it works. I’m not ashamed of my ugly code that does what it was intended to do, but I’m quite embarrassed of my luxuriously styled simple and elegant routines that fail that most important characteristic of them all. If it doesn’t work, none of the rest matters at all.

Coding to me has always been an iterative process. I’m drawn to the things that I’ve never done before, so I seem to always be staking out new territory and getting involved with things that I know little about. I try things. Most of these initial efforts tend to end in spectacular failure, but then I try something else. I’m constantly searching for that thing that works. Once I clear that bar, then I start asking if there are ways in which it could be done better. But if, and only if, I can first discover what works.

Hopefully, the things that I end up posting out here made it out here because they work. There may be a better way to have done it, or a more efficient approach to the problem, and I’m definitely always on the look-out for those, but it better work. If it doesn’t work, I would definitely like to know about it. I love to make things better, faster, cheaper, and oh so beautiful, so I am always open to hearing those ideas as well. But the number one test will always be that same old simple question: Does it work?