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
Administrator
Administrator

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

I was freaking out too lol and thank you so much! Luckily, I only had to update the SP Header menu one but I'll keep this in mind if we decide to expand out and create additional portals. 

 

Thank you again!

Yeny

Hi Yeny,

I am experiencing the same issue you got before although I have moved 3 Angular ng-templates after cloned Header Menu. I cannot find out where the template named "spDropdownTreeTemplate" is associated. can you please help, my appreciate!

Hi Mario, 

The template should be in the Angular ng-templates list. You should be able to add it by clicking the edit button on that related list from the cloned Header widget you added. 

the related list should look like this. If you don't see it, you'll have to add it from the related lists. 

find_real_file.png

 

Hope this helps!

Yeny

Hi Allen,

Thanks for the above solutions!

It worked for me partially, as my requirement is to show "My Approvals" menu always, but "Request" menu should be visible only if there is atleast one request available for the logged-in user.

Both are Scripted List type, so when i changed the condition for item.scriptedItems.count, it reflected for both header menu.

Could you please suggest what to do in the above code for achieving this.

 

Thanks in advance,

Ravi

Vinh Tuong
Kilo Contributor

Hi Yeny,

I'm Mario again. The issue is still happens.

Sorry for my late response. I have to login by another account to reply.

 

I've added 3 Angular ng-templates into cloned widget as you mentioned:

 

find_real_file.png

Since we cannot add the same ID in there, so I had to create with my prefix (hvc) and I also update them into HTML body template:

 - for hvc_menuTemplate

find_real_file.png

 

 - for hvc_item-added-tooltip.html:

find_real_file.png

But I cannot find the place to update the last one "hvc_spDropdownTreeTemplate"

It seems that is the root cause of my problem. Can you please advise that where Angular ng-template should be updated ? or how can fix this issue please?