<!DOCTYPE html>
<html ng-app="App">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<title>Angular Breadcrumb</title>
<link data-require="bootstrap-css@3.1.*" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="site.css" />
</head>
<body>
<div class="navbar navbar-default brg_olive_3d">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#/home">Angular Bread Crumb</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-left">
<li>
<a ui-sref="home">
<i class="glyphicon glyphicon-home"></i> Home</a>
</li>
<li>
<a ui-sref="home.about">
<i class="glyphicon glyphicon-info-sign"></i> About
</a>
</li>
</ul>
</div>
</div>
<div class="breadcrumb" >
<div style="float:left">
<i class="glyphicon glyphicon-home"></i>
</div>
<div>
<ui-breadcrumbs displayname-property="data.displayName" abstract-proxy-property="data.proxy" template-url="ngBreadCrumbTemplate.html"></ui-breadcrumbs>
</div>
</div>
<div class="container body-content">
<div ui-view="main"></div>
</div>
<footer class="brg_olive_3d"></footer>
<script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script data-require="bootstrap@3.1.1" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script data-require="angular.js@1.2.15" data-semver="1.2.15" src="http://code.angularjs.org/1.2.15/angular.js"></script>
<script data-require="ui-router@*" data-semver="0.2.8" src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
/*<script data-require="ui-bootstrap@0.12.0" data-semver="0.12.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.min.js"></script> */
<script src="ngbreadcrumb.js"></script>
<script src="App.js"></script>
</body>
</html>
var App = angular.module('App', ['ui.bootstrap', 'ui.router', 'ngBreadCrumb']);
App.config(function ($stateProvider) {
$stateProvider
.state('home', {
url: '/home',
views: {
'main@': {
templateUrl: 'home.html',
}
},
data: {
displayName: 'Home',
}
})
.state('home.about', {
url: '/about',
views: {
'main@': {
templateUrl: 'about.html',
}
},
data: {
displayName: 'About'
}
})
.state('home.detail', {
url: '/:id',
views: {
'main@': {
templateUrl: 'detail.html'
//Sample controller declaration
//controller: function ($scope, userId) {
// $scope.userId = userId;
//}
}
},
data: {
displayName: '{{ id }}'
},
resolve: {
id: function ($stateParams) {
return $stateParams.id
}
}
})
})
App.run(function ($state) {
$state.go('home');
});
/*Nav-bar
===================================================
*/
.navbar {
margin-bottom: 0;
border: 0px
}
@media (min-width: 768px) {
.navbar {
border-radius: 0px;
}
}
.navbar-default .navbar-nav > li > a {
color: #D0E7EA;
}
.navbar-default .navbar-nav > .active{
color: #f8f0f0;
background:#52753f;
}
.navbar-default .navbar-nav > li > a:hover {
color: #37DFD8;
}
.navbar-default .navbar-nav > li > a:visited {
color: #e5f6f5;
}
.navbar-brand {
float: left;
height: 50px;
font-size: 18px;
line-height: 20px;
}
.navbar-brand img {
height: 99%;
}
/*Nav-bar - End Here
===================================================
*/
hr {
margin-top: 10px;
margin-bottom: 10px;
/*border: 0;
border-top: 1px solid #eee;*/
}
.container {
/*padding-right: 5px;
padding-left: 5px;*/
margin-right: auto;
margin-left: auto;
}
.form-group .help-block {
display: none;
}
.form-group.has-error .help-block {
display: block;
}
.form-group {
margin-bottom: 5px;
}
.breadcrumbback {
background:#a18c29;
}
.breadcrumb {
padding: 1px 3px 1px 4px;
margin-bottom: 0px;
list-style: none;
background-color: #5dc40d;
border-radius: 0px;
font-size:13px;
}
.breadcrumb > li {
display: inline-block;
}
.breadcrumb > li a {
color:#fff;
}
.breadcrumb > li + li:before {
padding: 0 5px;
color: #cccccc;
content: "/\00a0";
}
.breadcrumb > .active {
color:#000;
}
.brg_olive_3d {
background: rgb(98,125,77); /* Old browsers */
background: -moz-linear-gradient(top, rgba(98,125,77,1) 0%, rgba(31,59,8,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(98,125,77,1)), color-stop(100%,rgba(31,59,8,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(98,125,77,1) 0%,rgba(31,59,8,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(98,125,77,1) 0%,rgba(31,59,8,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(98,125,77,1) 0%,rgba(31,59,8,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(98,125,77,1) 0%,rgba(31,59,8,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#627d4d', endColorstr='#1f3b08',GradientType=0 ); /* IE6-9 */
}
footer {
padding-top:15px;
min-height:60px;
color:#fff;
}
footer p{
margin-top:8px;
margin-left:5px;
}
.body-content {
min-height:500px;
}
/*For Table Bordered*/
.navbar-default {
background-color:#fff;
border-color: #fff;
}
.footer_centered{
padding: 25px 10px;
text-align: center;
font-size: 12px;
line-height: 25px;
margin-top:10px !important;
}
.footer_centered footer_img{
width:10%;
}
footer ul {
padding-left:0px;
}
footer a:link {
color: #E1EDEB;
}
/* visited link */
footer a:visited {
color: #E1EDEB;
}
/* mouse over link */
footer a:hover {
color: #54F0D6;
}
/* selected link */
footer a:active {
color: #0000FF;
}
/*Navigation sub menu*/
.navbar-default .navbar-nav>.open>a, .navbar-default .navbar-nav>.open>a:focus,
.navbar-default .navbar-nav>.open>a:hover {
color: #fff;
background-color: #536E3E;
}
.dropdown-menu {
background-color: #536E3D;
}
.dropdown-menu .divider {
background-color: #335C35;
}
.dropdown-menu li a:link,dropdown-menu li a:visited {
color:#fff;
}
.dropdown-menu li a:hover {
color: #54F0D6;
}
.dropdown-menu li a:active {
color: #0000FF;
}
.selectAttrib {
height: auto;
min-height:35px;
max-height: 200px;
overflow-x: hidden;
}
.note_panel {
margin-bottom:5px;
}
.note_panel_yellow{
background-color:rgba(255,146,10,1);
}
.note_panel_red{
background-color:#e41d1d;
}
.note_panel_solid_border{
border:1px solid #fff;
}
.note_panel_dashed_border{
border:1px dashed #fff;
}
.note_panel_dashed_big_border{
border:1px dotted #fff;
}
.note_panel .note_body {
margin:2%;
color:#fff;
padding:5px;
width:96%;
display:inline-block;
}
.note_panel .note_body a:link, .note_panel .note_body a:visited {
color:#fff;
}
.note_panel .note_body a:hover {
color:#000;
}
<h1>Home</h1>
<p>AngularJS that implements Breadcrumb</p>
<div class="note_panel note_panel_yellow">
<div class="note_body note_panel_solid_border">
<h4>Breadcrumb With Route Parameter</h4>
<a ui-sref="home.detail({id: 1})">Detail</a> | <a ui-sref="home.detail({id: 2})">Detail 2</a>
</div>
</div>
<div class="note_panel note_panel_red">
<div class="note_body note_panel_dashed_border">
<h4>Bread Crumb</h4>
<p>Just a Display</p>
</div>
</div>
<h1>Details</h1>
<div class="note_panel note_panel_yellow">
<div class="note_body note_panel_solid_border">
<h3>Detail Page</h3>
</div>
</div>
<ol class="breadcrumb">
<li ng-repeat="crumb in breadcrumbs"
ng-class="{ active: $last }"><a ui-sref="{{ crumb.route }}" ng-if="!$last">{{ crumb.displayName }} </a><span ng-show="$last">{{ crumb.displayName }}</span>
</li>
</ol>
/**
* uiBreadcrumbs automatic breadcrumbs directive for AngularJS & Angular ui-router.
*
* https://github.com/michaelbromley/angularUtils/tree/master/src/directives/uiBreadcrumbs
*
* Copyright 2014 Michael Bromley <michael@michaelbromley.co.uk>
*/
(function () {
/**
* Config
*/
var moduleName = 'ngBreadCrumb';
var templateUrl = 'ngBreadCrumbTemplate.html';
/**
* Module
*/
var module;
try {
module = angular.module(moduleName);
} catch (err) {
// named module does not exist, so create one
module = angular.module(moduleName, ['ui.router']);
}
module.directive('uiBreadcrumbs', function ($interpolate, $state) {
return {
restrict: 'E',
templateUrl: function (elem, attrs) {
return attrs.templateUrl || templateUrl;
},
scope: {
displaynameProperty: '@',
abstractProxyProperty: '@?'
},
link: function (scope) {
scope.breadcrumbs = [];
if ($state.$current.name !== '') {
updateBreadcrumbsArray();
}
scope.$on('$stateChangeSuccess', function () {
updateBreadcrumbsArray();
});
/**
* Start with the current state and traverse up the path to build the
* array of breadcrumbs that can be used in an ng-repeat in the template.
*/
function updateBreadcrumbsArray() {
var workingState;
var displayName;
var breadcrumbs = [];
var currentState = $state.$current;
while (currentState && currentState.name !== '') {
workingState = getWorkingState(currentState);
if (workingState) {
displayName = getDisplayName(workingState);
if (displayName !== false && !stateAlreadyInBreadcrumbs(workingState, breadcrumbs)) {
breadcrumbs.push({
displayName: displayName,
route: workingState.name
});
}
}
currentState = currentState.parent;
}
breadcrumbs.reverse();
scope.breadcrumbs = breadcrumbs;
}
/**
* Get the state to put in the breadcrumbs array, taking into account that if the current state is abstract,
* we need to either substitute it with the state named in the `scope.abstractProxyProperty` property, or
* set it to `false` which means this breadcrumb level will be skipped entirely.
* @param currentState
* @returns {*}
*/
function getWorkingState(currentState) {
var proxyStateName;
var workingState = currentState;
if (currentState.abstract === true) {
if (typeof scope.abstractProxyProperty !== 'undefined') {
proxyStateName = getObjectValue(scope.abstractProxyProperty, currentState);
if (proxyStateName) {
workingState = $state.get(proxyStateName);
} else {
workingState = false;
}
} else {
workingState = false;
}
}
return workingState;
}
/**
* Resolve the displayName of the specified state. Take the property specified by the `displayname-property`
* attribute and look up the corresponding property on the state's config object. The specified string can be interpolated against any resolved
* properties on the state config object, by using the usual {{ }} syntax.
* @param currentState
* @returns {*}
*/
function getDisplayName(currentState) {
var interpolationContext;
var propertyReference;
var displayName;
if (!scope.displaynameProperty) {
// if the displayname-property attribute was not specified, default to the state's name
return currentState.name;
}
propertyReference = getObjectValue(scope.displaynameProperty, currentState);
if (propertyReference === false) {
return false;
} else if (typeof propertyReference === 'undefined') {
return currentState.name;
} else {
// use the $interpolate service to handle any bindings in the propertyReference string.
interpolationContext = (typeof currentState.locals !== 'undefined') ? currentState.locals.globals : currentState;
displayName = $interpolate(propertyReference)(interpolationContext);
return displayName;
}
}
/**
* Given a string of the type 'object.property.property', traverse the given context (eg the current $state object) and return the
* value found at that path.
*
* @param objectPath
* @param context
* @returns {*}
*/
function getObjectValue(objectPath, context) {
var i;
var propertyArray = objectPath.split('.');
var propertyReference = context;
for (i = 0; i < propertyArray.length; i++) {
if (angular.isDefined(propertyReference[propertyArray[i]])) {
propertyReference = propertyReference[propertyArray[i]];
} else {
// if the specified property was not found, default to the state's name
return undefined;
}
}
return propertyReference;
}
/**
* Check whether the current `state` has already appeared in the current breadcrumbs array. This check is necessary
* when using abstract states that might specify a proxy that is already there in the breadcrumbs.
* @param state
* @param breadcrumbs
* @returns {boolean}
*/
function stateAlreadyInBreadcrumbs(state, breadcrumbs) {
var i;
var alreadyUsed = false;
for (i = 0; i < breadcrumbs.length; i++) {
if (breadcrumbs[i].route === state.name) {
alreadyUsed = true;
}
}
return alreadyUsed;
}
}
};
});
})();
<h1>About</h1>
<div class="note_panel note_panel_yellow">
<div class="note_body note_panel_solid_border">
<h4>About Page</h4>
<p>Sample Angular Breadcrumb</p>
</div>
</div>