Angular History Based BreadCrumbs

Posted: 2014-12-12 01:20:00

Originally I was going to go with one of the more well known packages but then I realized I wanted to show the history of the users states not the children of the state they are on. For example when the user lands on the website at say the path projects and then goes to projects/foo their breadcrumbs will look like this

Projects  / Project Foo

And if they then go to project/foo/reports then it would be

Projects  / Project Foo / Reports

So no matter where they go it just keeps saving the from state to the history object and loads that.

Ideally like many of the other modules this would be a good mix of a directive and a service. Right now it is setup like this but I will move it later into a package. (unless there already is one out there that I just could not google well enough?)

Config

This is where I look at the "from state" to see if it has what I want and then save it to history. I also take a moment to keep history down to 5 items.

    angular
        .module('app')
        .config(config)
        .constant('ENV', constants())
        .run(function ($rootScope, $state, editableOptions, $location, $stateParams) {
            editableOptions.theme = 'bs3';
            $rootScope.$state = $state;
            $rootScope.history = [];

            $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
                if($state.href(fromState, fromParams) && fromState.data && fromState.data.pageTitle)
                {
                    if($rootScope.history.length > 5)
                    {
                        $rootScope.history = $rootScope.history.slice(1, $rootScope.history.length);
                    }
                    $rootScope.history.push({ label: fromState.data.pageTitle, url: $state.href(fromState, fromParams)});
                }
            });
        });

PageTitle

This happen to be a data object I had set on all my routes to begin with

      $stateProvider
            .state('profile', {
                url: "/profile",
                templateUrl: "/assets/js/profiles/templates/profile.html",
                controller: 'ProfileEditCtrl',
                controllerAs: 'vm',
                resolve: {
                    profile: ['ProfilesService', function (ProfilesService) {
                        return ProfilesService.getFull();
                    }]
                },
                data: {pageTitle: 'Profile'}
            });
    }

The Directive

The directive is doing two things. I need to make it into two directives but for style reasons and timing I can not do that right now.

Just taking the history and pageTitle and putting it into html

(function(){
    'use strict';
    function appHeader() {
           var directive = {
                restrict: 'E',
                replace: true,
                transclude: true,
                scope: {
                    pageTitle: '=',
                    history: '='
                },
                templateUrl:   "/assets/js/directives/templates/_header.directive.html"
            };

            return directive;
    }
    angular.module('app')
        .directive('appHeader', appHeader)
})();

The directives template file you see above

directive

The HTML / Page showing the breadcrumbs

After all the above is in place you just need to add this to the pages you want this to be seen, or on some main page (ideally)

<app-header page-title="vm.pageTitle" history="history"></app-header>

You end up with something like this bc

Next step is to inject the title into the pageTitle so it would be the Project name. But right now I rather have the above so as a user I can easily go back to say "Batches" from where I am in the state.


Tags:

angularjs