angularjs: breadcrumbs

Angularjs: a breadcrumbs implementation with routing

by Stephane de Luca

HTML

<script src="https://code.angularjs.org/1.2.7/angular.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0-beta.3/angular-sanitize.min.js"></script>
<div ng-controller="myCtrl">
    <div ng-init="popovers = [	
		{	name: 'Popover1',	
            displayName: 'Pop over with two tabs',
			tabs: [
				{	name: 'Tab1',		
                    displayName: 'First tab',
					description: ['First tab description']
				},
				{	name: 'Tab2',		
                    displayName: 'Second tab',
					description: ['Second tab description']
				}
            ]
        }
    ]"/>
    <div>
        <a href="" ng-click="breadcrumbs.back()">&lt; BACK</a> | Showing <em>'{{currentTab}}'</em>
    </div>
    <div
        class="popover"
        ng-repeat="p in popovers">
        <div>
            Popover name: {{p.displayName}}
        </div>
        <div ng-repeat="t in p.tabs" 
            class="tab"
            ng-class="$parent.currentTab==t.name?'selected':''"
            ng-click="$parent.$parent.currentTab=openTab(t.name)">
            {{t.name}}
        </div>
        <div  ng-repeat="t in p.tabs" 
            class="tabContent" 
            ng-class="currentTab==t.name?'selected':''">
            <p>{{t.displayName}}</p>
        </div>
    </div>
    <hr>
    <p>currentTab={{currentTab}}</p>
    <p>Breadcrumbs : {{breadcrumbs.urls.length}} levels</p>
    <ol>
        <li ng-repeat="url in breadcrumbs.urls">
            — {{$index}}: {{url.url}} | {{url.tab}}
        </li>
    </ol>
</div>

CSS

body {
    font-family:"AvenirNextCondensed-Regular" sans-serif;
}

p em {
    color: red;
    font-weight: bold;
}

figure, div {
    padding: 4px;
}

.popover {
    width:  400px;
    height: 200px;
    background-color: brown;
    color: white;
}    
.popover .tab {
    display: inline-block; 
    border: solid 1px gray;
    border-bottom: none;
    width:auto;
    background-color: gray;
    color: lightgray;
}
.popover .tab.selected {
    background-color: white;
    color: gray;
}

.popover .tab:hover {
    cursor: pointer;
    background-color: rgba(255,255,255,.9);
}

.popover .tabContent {
    background-color: white;
    display: none;
    color: gray;
    height: 100px;
}

.popover .tabContent.selected {
    display: block;
}

JavaScript

var openPopupOnLoad=null;
var openTabOnLoad=null;

var app = angular.module('myApp', ['ngSanitize']);


app.controller('myCtrl', function ($scope, $location, $http) {

    $scope.currentTab = $scope.currentTab||'Tab2';
    
    console.log("========= controller started =========");
    console.log("currentTab is '"+$scope.currenTab+"'");
    
    $scope.openTab = function(tab) {
        $scope.breadcrumbs.openUrl($scope.getPage()+"?openTab="+tab);
        return tab;
    };
    
    $scope.getPage = function() {
		//console.log("getPage() returns "+$location.path());
		return $location.path();
	};

    	//-- Breadcrumb management
	
	$scope.breadcrumbs = {
		urls:[],
		push: function(url){
			this.urls.push(url);
		},
		back: function(){
			if (this.urls.length<1) {
				console.log("Breadcrumb: *** error back() requested but no URLs stored. Ignoring…");
				return;
			}
		
			var current =  this.urls[this.urls.length-1];
			
			// pull the current url out of the breadcrumbs stack
			this.urls.splice(-1);
			
			var target =  this.urls.length?this.urls[this.urls.length-1]:{url:'home', popup:null};
			openPopupOnLoad	= target.popup;

			console.log("Breadcrumb: back from url "+current.url+" is asked");
			this.log("back(url "+target.url+", popup "+target.popup+", tab "+target.tab+")");
			
			if (current.url==target.url) {
				//$timeout(function(){
					$scope.currentTab = target.tab;
					//$scope.$apply($scope.currentTab);
					console.log("Breadcrumb: stay on the url "+target.url+" but set currentTab to "+$scope.currentTab);
					//},300);
			}
			else {
				openTabOnLoad	= target.tab;
				console.log("Breadcrumb: back to url "+target.url+" (set openTabOnLoad to "+openTabOnLoad);
				$location.url(target.url);
			}
		},
		home: function(){
			this.urls=[];
			this.log("home()");
			$location.url('home');
		},
		registerOpenPopup: function(popup) {
			if (openPopupOnLoad) {
				console.log("::::: Breadcrumbs --- registerOpenPopup dont add popup...