Is there a way to show the badge counter on the header menu for non-scripted menu items?

YenGar
Mega Sage

Hi all, 

Is there a way to show the badge counter on menu items that are not scripted in the portal header? I have a request to show the counter but do not want the drop down of items when clicking on the menu. They just want to be able to click on the menu item and be taken to the corresponding page. Right now, I know that the badge counter can only be displayed when the type of meny item is a scripted list, not just a page. Cna this be changed for page menu items? 

See here, the counter is there but this is a scripted list. Would like for the counter to still show but when the menu is clicked, just take the user to the page. 

find_real_file.png

 

Any ideas/suggestions are welcomed!

 

Thank you!

1 ACCEPTED SOLUTION

Tony DiRienzo
Giga Guru

The display of badges is controlled by setting "data.count" on a Scripted Item.  The Scripted Item's count value is rendered by an angular template called menuTemplate which is associated with the Header Menu widget.  The easiest way to accomplish what you are wanting would be to update the menuTemplate to render Scripted Items without a dropdown and attach a page link in situations where the Scripted Item has no items attached (the dropdown is populated from the "data.items" set in the Scripted Item).

You can update the menuTemplate without needing to clone the Header Menu widget.  Just navigate to Portal > Widgets in the filter navigator, then search for Header Menu in the list and open the record.  In the ng-templates related list, find menuTemplate and open that record.  At the bottom of the template you will find this code:

<a role="menuitem" aria-haspopup="true" ng-if="item.scriptedItems.count > 0" href data-toggle="dropdown" aria-label="{{::item.label}} : {{item.scriptedItems.count}}" 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" />

You will need to make two changes.  In the first line, find href and replace it with ng-href="item.scriptedItems.href".  This will allow the Scripted Item to link to a page if you specify a value for "data.href".  Then in the last line, replace ng-if="item.scriptedItems.count > 0" with ng-if="item.scriptedItems.count > 0 && item.scriptedItems.items.length > 0".  This will cause the template to only render a dropdown when there are items to populate the dropdown.  Your updated code should look like this:

<a role="menuitem" aria-haspopup="true" ng-if="item.scriptedItems.count > 0" ng-href="{{::item.scriptedItems.href}}" data-toggle="dropdown" aria-label="{{::item.label}} : {{item.scriptedItems.count}}" 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 && item.scriptedItems.items.length > 0" items="item.scriptedItems.items" />

Now create a Scripted Item in your menu and give it values for data.count and data.href.  For example:

data.count = 42;
data.href = "/sp?id=404";

This example will display a menu item with a badge showing 42 and when clicked will link to the 404 page.

I hope this helps you.

View solution in original post

5 REPLIES 5

Tony DiRienzo
Giga Guru

The display of badges is controlled by setting "data.count" on a Scripted Item.  The Scripted Item's count value is rendered by an angular template called menuTemplate which is associated with the Header Menu widget.  The easiest way to accomplish what you are wanting would be to update the menuTemplate to render Scripted Items without a dropdown and attach a page link in situations where the Scripted Item has no items attached (the dropdown is populated from the "data.items" set in the Scripted Item).

You can update the menuTemplate without needing to clone the Header Menu widget.  Just navigate to Portal > Widgets in the filter navigator, then search for Header Menu in the list and open the record.  In the ng-templates related list, find menuTemplate and open that record.  At the bottom of the template you will find this code:

<a role="menuitem" aria-haspopup="true" ng-if="item.scriptedItems.count > 0" href data-toggle="dropdown" aria-label="{{::item.label}} : {{item.scriptedItems.count}}" 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" />

You will need to make two changes.  In the first line, find href and replace it with ng-href="item.scriptedItems.href".  This will allow the Scripted Item to link to a page if you specify a value for "data.href".  Then in the last line, replace ng-if="item.scriptedItems.count > 0" with ng-if="item.scriptedItems.count > 0 && item.scriptedItems.items.length > 0".  This will cause the template to only render a dropdown when there are items to populate the dropdown.  Your updated code should look like this:

<a role="menuitem" aria-haspopup="true" ng-if="item.scriptedItems.count > 0" ng-href="{{::item.scriptedItems.href}}" data-toggle="dropdown" aria-label="{{::item.label}} : {{item.scriptedItems.count}}" 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 && item.scriptedItems.items.length > 0" items="item.scriptedItems.items" />

Now create a Scripted Item in your menu and give it values for data.count and data.href.  For example:

data.count = 42;
data.href = "/sp?id=404";

This example will display a menu item with a badge showing 42 and when clicked will link to the 404 page.

I hope this helps you.

Thank you Tony! The menuTemplate I have is slightly different because I am displaying the menu even if there are no items brought back through the script. I changed the lines you said and it is working very well! I also removed the data-toggle="dropdown" though because I don't want to have any dropdown, just want it to go directly to the page but still want to show the counter.

Here's my updated code - This one displays the menu and counter even if there are no items and takes the user to the page when clicking on the menu item

<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"  ng-href="{{::item.scriptedItems.href}}" 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-warning sp-navbar-badge-count">{{item.scriptedItems.count}}</span>
</a>

<sp-dropdown-tree role="menu" aria-label="{{::item.label}}" ng-if="item.scriptedItems.count > 0 && item.scriptedItems.items.length > 0" items="item.scriptedItems.items" />

 

Thank you so much for your help with this! Works great! 

 

Glad to hear you got it working!

If you end up having a situation where you might still want the data-toggle="dropdown" to show up in certain cases, you could replace it with a conditional ng-attr so the attribute only gets added if the condition is true.  For example, this should add the data-toggle="dropdown" if there are any items to display, but leave it out if there are none:

ng-attr-data-toggle="{{item.scriptedItems.items.length > 0 ? 'dropdown' : undefined}}"

Hi Tony, thank you for the clear response. Can I ask where you are writing this code? I have a similar request and your solution looks like my best bet at the moment.