Hiding an Empty Shopping Cart

“I love it when a plan comes together.”
Col. John “Hannibal” Smith

On the stock header of a ServiceNow portal there is an image of a shopping cart. As you order things from the Service Catalog, the number of items in your cart is displayed in the lower right-hand corner of that image. If you didn’t come to the portal to order something, the empty cart just sits there at the top of the screen for no reason, so I thought it might be nice to just hide the cart until there was at least one item in it.

There are already a couple of other items in the header that only appear if there is something there, the list of Requests and the the list of Approvals. I figured that I could emulate the approach taken on those items and it would work the same way.

Most of the things that drive ServiceNow are built using ServiceNow, and you can find them in the system database and edit them to do what you want. Some things, however, are built into the system, and there is no way that you can modify them. There is also a third category, and that is those things that actually are housed in the system database, but are locked down as read-only or ACL-controlled such that you cannot modify them. The Header Menu widget that contains the shopping cart code happens to fall into that third category. There it was right in front of me, but it was not editable, even though I am a System Administrator and I was in the right Update Set.

Nothing motivates me more than being told that I am being prevented from doing something that I want to do, so I immediately went to work trying to figure out a way to make changes to the Header Menu widget. As it turns out, it wasn’t that hard to do.

The first thing to do was to use the hamburger menu to export the widget to XML:

Export to XML (This Record)

Once I had my own copy on my own machine, I could look at the code and figure out what need to be changed and then change it. Digging through the HTML, I found out that there was already an ng-show attribute on the shopping cart for another purpose, so I just needed to add my condition to the list, and that should do the trick. Here is the relevant section of code:

  <!-- Shopping cart stuff -->
 <li ng-if="::options.enable_cart && data.isLoggedIn" ng-show="::!accessibilityEnabled" class="dropdown hidden-xs header-menu-item" role="presentation">
  	<a href
       data-toggle="dropdown"
       id="cart-dropdown"
       uib-tooltip-template="'item-added-tooltip.html'"
       tooltip-placement="bottom"
       tooltip-trigger="'none'"
       tooltip-is-open="$parent.itemAddedTooltipOpen"
       title="${Your shopping cart currently has} {{cartItemCount}} ${items}"
       aria-label="${Shopping cart}"
       role="menuitem">
    	<i class="fa fa-shopping-cart" aria-hidden="true"></i>
      <span ng-bind-html="'${Cart}'" aria-hidden="true"></span>
      <span ng-if="cartItemCount > 0" aria-hidden="true" class="label label-as-badge label-primary sp-navbar-badge-count">{{cartItemCount}}</span>
		</a>
    <div class="dropdown-menu cart-dropdown">
      <sp-widget widget="data.cartWidget"></sp-widget>
    </div>
  </li>

A little further down in the code there was reference to a variable called cartItemCount. Using my puissant powers of deductive reasoning, I concluded, based on the name of the variable and its usage, that this variable contained the number of items in the cart. This is exactly what I needed for my condition, so I changed this line:

<li ng-if="::options.enable_cart && data.isLoggedIn" ng-show="::!accessibilityEnabled" class="dropdown hidden-xs header-menu-item" role="presentation">

… to this:

<li ng-if="::options.enable_cart && data.isLoggedIn" ng-show="cartItemCount > 0 && !accessibilityEnabled" class="dropdown hidden-xs header-menu-item" role="presentation">

Now that I have figured out what change to make and have implemented the change, all I need to do is get it back into the instance. Fortunately, ServiceNow provides a way to do that, and it has the added benefit of bypassing those pesky rules that were preventing me from editing the thing directly in the tool.

If you open the System Update Sets section and go all the way down to the bottom and select Update Sets to Commit, there will be a link down at the bottom of that page titled Import Update Set from XML. Click on that guy, and even though your exported and modified XML document is not technically an Update Set, you can pull it in via that process and it will update the widget with your changes.

Returning Exported XML Back to the Instance

Now when I am on a portal that uses the Header Menu widget, you only see the Shopping Cart when there is something in the cart. Whenever it is empty, it drops out of the view.

I like it!