Skip to content

Instantly share code, notes, and snippets.

@codfish
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codfish/d5fec94f4a40713aba13 to your computer and use it in GitHub Desktop.
Save codfish/d5fec94f4a40713aba13 to your computer and use it in GitHub Desktop.
AngularJS Breadcrumbs leveraging ui-router's states. Based off http://goo.gl/w0zFou
'use strict';
/**
* App Module
*
* @note
* ui-router setup is def incomplete. this is just to show an
* example of the breadcrumb setup
*
* @ngInject
*/
function config($stateProvider) {
$stateProvider
.state('home', {
url: '^',
breadcrumb: {
title: 'Home',
// example non-angular page, so provide physical url
// otherwise will use the state to link
url: '/'
}
})
.state('home.articles', {
url: '/articles',
breadcrumb: {
title: 'Articles'
}
})
.state('home.articles.view', {
url: '/:slug',
resolve: {
title: function() {
return 'Article title'
}
},
breadcrumb: {
title: '{{ title }}'
}
});
}
angular
.module('app', [
'ui.router',
'app.breadcrumbs'
])
.config(config);
'use strict';
/**
* @ngInject
*/
function BreadcrumbsController($rootScope, $scope, BreadcrumbFactory) {
$scope.BreadcrumbFactory = BreadcrumbFactory;
$rootScope.$on('$stateChangeSuccess', function() {
BreadcrumbFactory.generate();
});
}
/**
* Breadcrumb Directive
*
* EXAMPLE:
* <div cad-breadcrumbs></div>
* <div data-cad-breadcrumbs></div>
*
* @see http://goo.gl/w0zFou (code based of this)
*/
function BreadcrumbsDirective() {
return {
restrict: 'AE',
replace: true,
priority: 100,
controller: BreadcrumbsController,
templateUrl: 'breadcrumbs.tpl.html'
};
}
angular
.module('app.breadcrumbs')
.directive('breadcrumbs', BreadcrumbsDirective);
'use strict';
/**
* Breadcrumb Factory
*
* @see http://goo.gl/w0zFou (code based of this)
* @ngInject
*/
function BreadcrumbFactory($state, $interpolate) {
var list = [];
/**
* Add a breadcrumb
*
* @param {String} title breadcrumb label
* @param {String} state name of the state OR literal url, if isUrl = true
* @param {Boolean} isUrl if true, state is a url, not a state. default is false
*/
function addBreadcrumb(title, href, isUrl) {
isUrl = isUrl || false;
list.push({
title: title,
state: isUrl ? null : href,
url: isUrl ? href : null
});
}
function generateBreadcrumbs(state) {
var isUrl = false,
href = null;
if (angular.isDefined(state.parent)) {
generateBreadcrumbs(state.parent);
}
if (angular.isDefined(state.breadcrumb)) {
if (angular.isDefined(state.breadcrumb.title)) {
isUrl = angular.isDefined(state.breadcrumb.url);
href = isUrl ? state.breadcrumb.url : state.name;
addBreadcrumb($interpolate(state.breadcrumb.title)(state.locals.globals), href, isUrl);
}
}
}
return {
generate: function() {
list = [];
generateBreadcrumbs($state.$current);
},
list: function() {
return list;
}
};
}
angular
.module('app.breadcrumbs')
.factory('BreadcrumbFactory', BreadcrumbFactory);
'use strict';
/**
* Breadcrumb Module
*
* @see http://goo.gl/w0zFou (code based of this)
*/
angular.module('app.breadcrumbs', []);
<ul class="breadcrumbs">
<li ng-repeat="breadcrumb in BreadcrumbFactory.list()">
<div itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="{{ breadcrumb.url }}" target="_self" ng-if="breadcrumb.url && !$last" itemprop="url"><span itemprop="title">{{ breadcrumb.title }}</span></a>
<a ng-if="breadcrumb.state && !$last" ui-sref="{{ breadcrumb.state }}" itemprop="url"><span itemprop="title">{{ breadcrumb.title }}</span></a>
<span class="active" ng-show="$last" itemprop="title">{{ breadcrumb.title }}</span>
</div>
<span ng-hide="$last">&gt;</span>
</li>
</ul>
<div class="AppCtrl">
<div data-breadcrumbs></div>
<!-- OR <div breadcrumbs></div> -->
<!-- OR <breadcrumbs></breadcrumbs> -->
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment