ServicePortal breadcrumb widget
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-28-2018 09:53 AM
There are a few posts on the community about getting the breadcrumb widget to work with custom pages. Many of them suggest cloning the widget and then building recursive logic to build the breadcrumbs to your custom pages. I just took the 2-day service portal advance course at K18 and in the guide it says:
Built-in functionality exists baseline that allows you to overwrite Portal breadcrumbs. Notice the breadcrumbs Widget is always listening for the sp.update.breadcrumbs event with the statement. If it hears It, the callback function executes.
var deregister = $rootscope.$on("sp.update.breadcrumbs", function(e, list) {
c.breadcrumbs = list;
});
In this example, the KB Article Page Widget transmits the event using the $broadcast() method. And the the SC Order Guide Widget transmits the event using the $emit method.
// KB Article Page client controller
function ($scope, spUtil, $sce, $rootScope, $timeout) {
spUtil.setSearchPage('kb');
$scope.data.text = $sce.trustAsHtml($scope.data.text);
$timeout(function() {
$rootScope.$broadcast('sp.update.breadcrumbs', $scope.data.breadcrumbs);
});
}
// KB Article Server Script
var t = data;
data.kb_knowledge_page = $sp.getDisplayValue("kb_knowledge_page") || "kb_view";
var articleGR = GlideRecord("kb_knowledge");
articleGR.get($sp.getParameter('sys_id'));
var recordIsValid = articleGR.isValidRecord();
var canReadArticle = articleGR.canRead();
t.isvalid = recordIsValid && canReadArticle;
if (canReadArticle) {
articleGR.incrementViewCount(); // update sys_view_count immediately on kb_knowledge record
var art = new GlideRecord("kb_use");
if (art.isValid()) {
art.article = articleGR.getUniqueValue();
art.user = gs.getUserID();
art.viewed = true;
art.insert(); // kb_use records are aggregated to update sys_view_count nightly
$sp.logStat('KB Article View', "kb_knowledge", articleGR.getUniqueValue(), articleGR.short_description);
}
t.category = articleGR.getValue('kb_category');
t.sys_id = $sp.getParameter('sys_id');
t.showAttachments = false;
if (articleGR.display_attachments)
t.showAttachments = true;
t.categoryDisplay = articleGR.getDisplayValue('kb_category');
t.short_description = articleGR.getValue('short_description');
if (articleGR.getValue('article_type') == 'wiki')
t.text = GlideWikiModel().render(articleGR.getValue('wiki'));
else
t.text = articleGR.getValue('text');
t.sys_view_count = articleGR.getDisplayValue('sys_view_count');
t.author = articleGR.getDisplayValue('author');
t.publishedUtc = articleGR.getValue('published');
t.number = articleGR.getValue('number');
if (showStarRating())
t.rating = articleGR.getValue('rating');
t.direct = false;
if (articleGR.direct)
t.direct = true;
t.breadcrumbs = [{label: t.short_description, url: '#'}];
if (!articleGR.kb_category.nil()) {
var rec = articleGR.kb_category.getRefRecord();
while (rec.getRecordClassName() == "kb_category") {
t.breadcrumbs.unshift({label: rec.getDisplayValue(), url: '?id=kb_category&kb_category=' + rec.getUniqueValue()});
rec = rec.parent_id.getRefRecord();
}
}
t.breadcrumbs.unshift({label: gs.getMessage("Knowledge Base"), url: '?id=' + t.kb_knowledge_page});
}
function showStarRating() {
if (options.show_star_rating == "Yes")
return true;
if (options.show_star_rating == "No")
return false;
if (gs.getProperty("glide.knowman.show_star_rating", "true") != "true")
return false;
return gs.hasRole(gs.getProperty("glide.knowman.show_star_rating.roles"));
}
Can someone help me with building the core logic for a very simple case?
TestPortal
- page1 - OOB Bread crumb widget and a single page widget (wg_page1)
- page2 - OOB Bread crumb widget and a single page widget (wg_page2)
- page3 - OOB Bread crumb widget and a single page widget (wg_page1)
the html template on each page has an href to point to the next html page 1 -> 2 -> 3
When I am on page1 and then click page2 and then page3
Bread crumb should be Home > page1 > page2 > page3
when I click page2, page three should disappear and home all should disappear.
Question: Am I correctly understanding that the baseline functionality of the breadcrumb widget should support this without having to clone it and then write custom logic? It is just a matter of making sure the page specific widget is getting the correct data in the server script and then letting the client script $broadcast > $rootScope.$broadcast('sp.update.breadcrumbs', $scope.data.breadcrumbs);
Here is my current page1 widget (wg_page1):
// Server Script
(function() {
var t = data;
t.page_id = $sp.getParameter('id');
//t.breadcrumbs = [{label: "default-lable", url: '#'}];
t.breadcrumbs.unshift({label: "Erik-page-lable-1", url: '?id=' + t.page_id});
})();
// Client Script
function ($scope, spUtil, $sce, $rootScope, $timeout) {
/* widget controller */
var c = this;
spUtil.setSearchPage('kb');
$scope.data.text = $sce.trustAsHtml($scope.data.text);
$timeout(function() {
$rootScope.$broadcast('sp.update.breadcrumbs', $scope.data.breadcrumbs);
});
}
<div>
<pre>Output: I am on {{data.page_id}}</pre>
</div>
<div><a href="?id=page2">${page2}</a></div>
- Labels:
-
Service Portal
- 7,791 Views

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-29-2018 06:48 AM
Hi,
Actually I too have same requirement. So, what I did is
I clone the breadcrumb widget. Then I created option schema.
Label - string type (comma seperated labels)
URL - string type (comma seperated urls)
In cloned breadcrumbs widget I made few changes.
server side:
var page = $sp.getParameter('id');
label = options.label||page;
page_id = options.url||page;
labels =label.split(',');
page_ids = page_id.split(',');
for(var i=0;i<labels.length && i<page_ids.length;i++)
{
data.breadcrumbs.push({label:labels[i],url:"?id="+page_ids[i]});
}
client:
$timeout(function()
{
console.log(c.data.breadcrumbs);
$rootScope.$broadcast("sp.update.breadcrumbs",c.data.breadcrumbs);
//console.log(c.data.breadcrumbs);
})
$rootScope.$on("sp.update.breadcrumbs", function(e, list) {
console.log(list.url);
c.breadcrumbs = list;
});
I tried like this. I don't know this is best way or not. If you have any ideas please share your thoughts.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-29-2018 07:52 AM
ok, let me try this....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-29-2018 07:59 AM
what about the existing client script stuff, did you remove it or just add to it?
function($scope, $rootScope, spUtil) {
var c = this;
c.expanded = !spUtil.isMobile();
c.expand = function() {
c.expanded = true;
};
var deregister = $rootScope.$on("sp.update.breadcrumbs", function(e, list) {
c.breadcrumbs = list;
});
$scope.$on('$destroy', function() {
deregister();
});
}

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-29-2018 08:05 AM
If you broadcast the event then only breadcrumb widget will work. So that both broadcast and listening to that event are with in same client script.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-29-2018 08:19 AM
I'm not following what you just said. Let me restate my question.
You said you cloned the breadcrumb widget. When you clone something it makes a copy of the existing item. The existing breadcrumb has code (what I pasted above). The server and client script examples you provided for dynamic did not show any of the existing OOB breadcrumb code.
My question is: Did you add your code into the existing bread crumb client script or did you overwrite/replace the OOB code with what you wrote?
And to be clear, I understand we are talking about a new breadcrumb widget, whether you cloned and overwrote, or just clicked new and created a brand new one.