How to keep the menu header in service portal visible all the time?

YenGar
Mega Sage

Hi community, 

Is there a way to keep the header menus (My requests, my approvals', etc) in the header menu of the service portal always visible even if the user doesn't have anything there?

Currently, the menus only show when the user has at least one item in those menus but we need it to show all the time. 

I have modified the menuTemplate to see if it would keep it visible but it didn't do anything. I also cloned the header menu widget and it didn't show anything at all in the header... Please see below. 

Updated menuTemplate

<a ng-if="item.items.length == 0 && !item.scriptedItems" ng-href="{{item.href}}">{{ item.label }}</a>
<a ng-if="item.items.length > 0" href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ item.label }} <span class="caret"></span></a>
<ul ng-if="item.items.length > 0" class="dropdown-menu" role="menu">
    <li ng-repeat="item in item.items" ng-include="'menuTemplate'" />
</ul>
<a   ng-if="item.scriptedItems.count" href="javascript:void(0)" data-toggle="dropdown" title="{{item.hint}}">
   <span ng-bind-html="item.label"></span>
       <span ng-if="!item.scriptedItems.omitBadge" class="label label-as-badge label-primary sp-navbar-badge-count">{{item.scriptedItems.count}}</span>
</a>

<sp-dropdown-tree ng-if="item.scriptedItems.count" items="item.scriptedItems.items" />

Updated Menu Header Widget - client script (line 47)

function ($scope, spUtil, $rootScope, $timeout, spAriaUtil) {
	$scope.loadingIndicator = $rootScope.loadingIndicator;
	$scope.cartItemCount = 0;
	$scope.wishlistItemCount = 0;
	$scope.itemAddedTooltipOpen = false;

	$scope.accessibilityEnabled = spAriaUtil.g_accessibility === "true";

	$scope.$on("$sp.service_catalog.cart.count", function($evt, count) {
		$scope.cartItemCount = count;
	});

	$scope.$on("$sp.service_catalog.wishlist.count", function($evt, count) {
		$scope.wishlistItemCount = count;
	});

	var cancelTooltipPromise;
	$scope.$on("$sp.service_catalog.cart.add_item", function() {
		$timeout.cancel(cancelTooltipPromise);

		$scope.itemAddedTooltipOpen = true;
		cancelTooltipPromise = $timeout(function() {
			$scope.itemAddedTooltipOpen = false;
		}, 3000);
	});

	$scope.$on('sp_loading_indicator', function(e, value) {
		$scope.loadingIndicator = value;
	});

	$scope.toggleCart = function() {
		$timeout.cancel(cancelTooltipPromise);
		$scope.itemAddedTooltipOpen = false;
		$timeout(function() {
			$("#cart-dropdown").dropdown("toggle");
		});
	};

	// PRB1108244: visibleItems array is used to improve keyboard nav 
	// in menu, refresh it as needed
	$scope.$watch('data.menu.items', function() {
		$scope.visibleItems = [];
		if ($scope.data.menu.items) {
			for (var i in $scope.data.menu.items) {
				var item = $scope.data.menu.items[i];
				if (item.items || (item.scriptedItems && item.scriptedItems.count >= 0))
					$scope.visibleItems.push(item);
			}
		}
	}, true);

	// Get list of record watchers
	var record_watchers = [];
	if ($scope.data.menu.items) {
		for(var i in $scope.data.menu.items) {
			var item = $scope.data.menu.items[i];
			if (item.type == 'scripted') {
				if (item.scriptedItems.record_watchers)
					record_watchers = record_watchers.concat(item.scriptedItems.record_watchers);
			}
			if (item.type == 'filtered') {
				record_watchers.push({'table':item.table,'filter':item.filter});
			}
		}
	}

	// Init record watchers
	for (var y in record_watchers){
		var watcher = record_watchers[y];
		spUtil.recordWatch($scope, watcher.table, watcher.filter);
	}
}

 

Can anyone tell me what I am doing wrong? How can I get the header menus show up all the time?

 

Any help is appreciated!

 

Thank you, 

Yeny

 

1 ACCEPTED SOLUTION

Allen Andreas
Tera Patron

I'm on Kingston and this works for me...

menuTemplate:

<a ng-if="item.items.length == 0 && !item.scriptedItems" ng-href="{{::item.href}}" target="{{::item.url_target}}" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span>
</a>
<a role="button" ng-if="item.items.length > 0" href class="dropdown-toggle sp-menu-has-items" data-toggle="dropdown" aria-controls="menu-apply" aria-haspopup="true" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span> <span class="caret"></span>
</a>
<ul ng-if="item.items.length > 0" class="dropdown-menu" role="group" id="menu-apply">
  <li ng-repeat="item in item.items" ng-include="'menuTemplate'" />
</ul>
<a role="button" ng-if="item.scriptedItems.count >= 0" href data-toggle="dropdown" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span>
  <span ng-if="::!item.scriptedItems.omitBadge" class="label label-as-badge label-primary sp-navbar-badge-count">{{item.scriptedItems.count}}</span>
</a>
<sp-dropdown-tree role="menu" aria-label="{{::item.label}}" ng-if="item.scriptedItems.count >= 0" items="item.scriptedItems.items" />

 

Client Controller:

function ($scope, spUtil, $rootScope, $timeout, spAriaUtil) {
	$scope.loadingIndicator = $rootScope.loadingIndicator;
	$scope.cartItemCount = 0;
	$scope.wishlistItemCount = 0;
	$scope.itemAddedTooltipOpen = false;

	$scope.accessibilityEnabled = spAriaUtil.g_accessibility === "true";

	$scope.$on("$sp.service_catalog.cart.count", function($evt, count) {
		$scope.cartItemCount = count;
	});

	$scope.$on("$sp.service_catalog.wishlist.count", function($evt, count) {
		$scope.wishlistItemCount = count;
	});

	var cancelTooltipPromise;
	$scope.$on("$sp.service_catalog.cart.add_item", function() {
		$timeout.cancel(cancelTooltipPromise);

		$scope.itemAddedTooltipOpen = true;
		cancelTooltipPromise = $timeout(function() {
			$scope.itemAddedTooltipOpen = false;
		}, 3000);
	});

	$scope.$on('sp_loading_indicator', function(e, value) {
		$scope.loadingIndicator = value;
	});

	$scope.toggleCart = function() {
		$timeout.cancel(cancelTooltipPromise);
		$scope.itemAddedTooltipOpen = false;
		$timeout(function() {
			$("#cart-dropdown").dropdown("toggle");
		});
	};

	// PRB1108244: visibleItems array is used to improve keyboard nav 
	// in menu, refresh it as needed
	$scope.$watch('data.menu.items', function() {
		$scope.visibleItems = [];
		if ($scope.data.menu.items) {
			for (var i in $scope.data.menu.items) {
				var item = $scope.data.menu.items[i];
				if (item.items || (item.scriptedItems && item.scriptedItems.count >= 0))
					$scope.visibleItems.push(item);
			}
		}
	}, true);

	// Get list of record watchers
	var record_watchers = [];
	if ($scope.data.menu.items) {
		for(var i in $scope.data.menu.items) {
			var item = $scope.data.menu.items[i];
			if (item.type == 'scripted') {
				if (item.scriptedItems.record_watchers)
					record_watchers = record_watchers.concat(item.scriptedItems.record_watchers);
			}
			if (item.type == 'filtered') {
				record_watchers.push({'table':item.table,'filter':item.filter});
			}
		}
	}

	// Init record watchers
	for (var y in record_watchers){
		var watcher = record_watchers[y];
		spUtil.recordWatch($scope, watcher.table, watcher.filter);
	}
}

 

Then just make sure you associate this correctly to your menutemplate and other angular ng-templates (should be at least 3)


Please consider marking my reply as Helpful and/or Accept Solution, if applicable. Thanks!

View solution in original post

22 REPLIES 22

Hi Mario, Did you have any update on this, as i am trying to achieve the same output.

 

For anyone still struggling with this and missing the 'Edit' button on the Angular ng-templates related list, if you right click the related list then go to Configure > List Control there should be a UI Action at the bottom that says 'Enable Edit'. Select that and you should be able to edit the related list and add the templates without having to create new ones and mess around with the IDs. Hope this helps anyone looking for more information! 

YenGar
Mega Sage

Hi Mario, 

This is what I did on my end and it worked for me (I'm on Kingston)

I just cloned the header menu like this - go ahead and replace any MH lables, those are specific to my company.

<ul class="nav navbar-nav" aria-label="${Header menu MH}">
  <div class="header-loader" ng-show="loadingIndicator">
    <div class="hidden-xs sp-loading-indicator la-sm">
      <div></div>
      <div></div>
      <div></div>
    </div>
  </div>
  <li ng-repeat="item in visibleItems" ng-class="{dropdown: item.items.length > 0, 'header-menu-item': true}" ng-include="'mhMenuTemplate'"></li>
<!-- Wishlist menu -->
  <li ng-if="options.enable_wishlist && data.isLoggedIn && data.showWishlist" ng-show="!accessibilityEnabled" class="dropdown hidden-xs">
  	<a role="menuitem" href="javascript:void(0)"
       data-toggle="dropdown"
       id="wishlist-menu"
       title="${Your Wish List currently has} {{wishlistItemCount}} ${items}"
       aria-label="${Wish List}">
      <span ng-bind-html="'${Wish List}'" aria-hidden="true"></span>
      <span ng-if="wishlistItemCount > 0" aria-hidden="true" class="label label-as-badge label-primary sp-navbar-badge-count">{{wishlistItemCount}}</span>
		</a>
    <div class="dropdown-menu wishlist-menu">
      <sp-widget widget="data.wishlistWidget"></sp-widget>
    </div>
  </li>
  <li ng-if="options.enable_wishlist && data.isLoggedIn && data.showWishlist" class="dropdown" ng-class="{'visible-xs': !accessibilityEnabled}"  aria-label="${Your Wish List currently has} {{wishlistItemCount}} ${items}">
  	<a href="?id=sc_wishlist"
       title="${Wish List}"
       class="toggle-dropdown">
      <span ng-bind-html="'${Wish List}'" aria-hidden="true"></span>
      <span ng-if="wishlistItemCount > 0" aria-hidden="true" class="label label-as-badge label-primary sp-navbar-badge-count">{{wishlistItemCount}}</span>
		</a>
  </li>
  <!-- Shopping cart stuff -->
 <li ng-if="::options.enable_cart && data.isLoggedIn" ng-show="::!accessibilityEnabled" class="dropdown hidden-xs header-menu-item">
  	<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}">
    	<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>
  <li ng-if="::options.enable_cart && data.isLoggedIn" class="dropdown" ng-class="::{'visible-xs': !accessibilityEnabled}"  aria-label="${Your shopping cart currently has} {{cartItemCount}} ${items}">
  	<a href="?id=sc_cart"
       title="${Cart}"
       class="toggle-dropdown">
    	<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>
  </li>
</ul>
  

 

This is the cloned template as well template- template name is mhMenuTemplate

 

<a ng-if="item.items.length == 0 && !item.scriptedItems" ng-href="{{::item.href}}" target="{{::item.url_target}}" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span>
</a>
<a role="button" ng-if="item.items.length > 0" href class="dropdown-toggle sp-menu-has-items" data-toggle="dropdown" aria-controls="menu-apply" aria-haspopup="true" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span> <span class="caret"></span>
</a>
<ul ng-if="item.items.length > 0" class="dropdown-menu" role="group" id="menu-apply">
  <li ng-repeat="item in item.items" ng-include="'mhMenuTemplate'" />
</ul>
<a role="button" ng-if="item.scriptedItems.count >= 0" href data-toggle="dropdown" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span>
  <span ng-if="::!item.scriptedItems.omitBadge" class="label label-as-badge label-primary sp-navbar-badge-count">{{item.scriptedItems.count}}</span>
</a>
<sp-dropdown-tree role="menu" aria-label="{{::item.label}}" ng-if="item.scriptedItems.count >= 0" items="item.scriptedItems.items" />



 

I didn't change anything on the spDropdownTreeTemplate or the item-added-tooltip.html, those are still OOB. 

This is the association:

find_real_file.png

 

Let me know if this helps!

 

Yeny

Hi Yeny,

I could not copy the Angular ng-templates with the same names. When I tried, it notified that Invalid Update as below:

find_real_file.png

 

That is the reason why I had to change the name of those Templates. Do you have any suggestions? or is there any wrong from my side?

Thank so much for your prompt reply

Mario

Same.