rpocklin / ui-router-tabs

Idiot-proof tab panes with route support using Angular.js + Bootstrap 3 + UI Router
Other
244 stars 57 forks source link

Allow custom function for checking if tab is active #71

Open ollyollyollyltd opened 8 years ago

ollyollyollyltd commented 8 years ago

Sometimes $state.include is not enough for checking whether a parent tab is active, for example when the parent tab links to a default child tab.

In this case when navigating to another child tab would cause the parent to become deselected.

This commit allows a custom function to be defined in the tabs object which will be called to determine whether a tab is selected. If the function is note present the default (current) function will be used.

eg:

// Routes.js
"use strict";
angular.module("myApp")
    .config(["$stateProvider", "$urlRouterProvider",
        function($stateProvider, $urlRouterProvider) {
            $stateProvider
                .state("main", {
                    abstract: true,
                    url: "/",
                    views: {
                        main: {
                            controller: "MainCtrl",
                            templateUrl: "views/main.html"
                        }
                    }
                })
                    // HOME
                    .state("main.home", {
                        url: ""
                    })

                    // USERS
                    .state("main.users", {
                        abstract: true,
                        url: "users",
                        views: {
                            content: {
                                controller: "UsersCtrl",
                                templateUrl: "views/users.html"
                            }
                        }
                    })
                        .state("main.users.list", {
                            url: "",
                            views: {
                                users: {
                                    controller: "UsersListCtrl",
                                    templateUrl: "views/users/list.html"
                                }
                            }
                        })
                        .state("main.users.add", {
                            url: "/add",
                            views: {
                                users: {
                                    controller: "UsersAddCtrl",
                                    templateUrl: "views/users/edit.html"
                                }
                            }
                        })
                        .state("main.users.edit", {
                            url: "/edit/{email}",
                            views: {
                                users: {
                                    controller: "UsersEditCtrl",
                                    templateUrl: "views/users/edit.html"
                                }
                            }
                        })

                    // LIBRARY
                    .state("main.library", {
                            abstract: true,
                            url: "library",
                            views: {
                                content: {
                                    controller: "LibraryCtrl",
                                    templateUrl: "views/library.html"
                                }
                            }
                        })

                            .state("main.library.behaviours", {
                                abstract: true,
                                url: "/behaviours",
                                views: {
                                    library: {
                                        templateUrl: "views/library/behaviours.html"
                                    }
                                }
                            })

                                .state("main.library.behaviours.list", {
                                    url: "",
                                    views: {
                                        behaviours: {
                                            controller: "LibraryBehavioursListCtrl",
                                            templateUrl: "views/library/behaviours/list.html"
                                        }
                                    }
                                })
                                .state("main.library.behaviours.add", {
                                    url: "/add",
                                    views: {
                                        behaviours: {
                                            controller: "LibraryBehavioursAddCtrl",
                                            templateUrl: "views/library/behaviours/add.html"
                                        }
                                    }
                                })

                            .state("main.library.sections", {
                                abstract: true,
                                url: "/sections",
                                views: {
                                    library: {
                                        templateUrl: "views/library/behaviours.html"
                                    }
                                }
                            })

                                .state("main.library.sections.list", {
                                    url: "",
                                    views: {
                                        behaviours: {
                                            controller: "LibraryBehavioursListCtrl",
                                            templateUrl: "views/library/behaviours/list.html"
                                        }
                                    }
                                })
                                .state("main.library.sections.add", {
                                    url: "/add",
                                    views: {
                                        behaviours: {
                                            controller: "LibraryBehavioursAddCtrl",
                                            templateUrl: "views/library/behaviours/add.html"
                                        }
                                    }
                                })

            ;
            $urlRouterProvider.otherwise("/");
        }
    ]);
// Main.js
"use strict";
angular.module("myApp")
    .controller("MainCtrl", ["$scope", "$state", function($scope, $state) {
        $scope.mainNav = [{
                heading: "Home",
                route: "main.home",
            }, {
                heading: "Users",
                route: "main.users.list",
            }, {
                heading: "Library",
                route: "main.library.behaviours.list",
            },
        ];
    }]);

With this routing setup navigating to main.users.add will cause the 'Users' tab to lose it's active state as the $state.include will return false.

With this commit we can add as isActive function to the tab declaration:

...
{
    heading: "Users",
    route: "main.users.list",
    isActive: $state.includes.bind($state, "main.users")
}
...

This will allow the tab to set the state as expected.

coveralls commented 8 years ago

Coverage Status

Coverage remained the same at 94.872% when pulling 5b8f526bfd736f106de53f1e7a7a0cb395d99099 on ollycross:custom-active-state-checker into 563fa9c98d81c5b86169a25327c784be1280e4b5 on rpocklin:master.

rpocklin commented 8 years ago

This is a problem in the current versions, so thank for the PR.

I can't help but think, rather than making it customisable, can we just fix the actual issue? See #55.

Open to accepting but want to rule this possibility out first.

rpocklin commented 8 years ago

Bump. ?

ollyollyollyltd commented 8 years ago

Hi mate, this is still on my to-do list I am just swamped with work at the moment.

I see what you mean by #55 being a similar problem, though I'm not sure if it is 100% the same. I will look into when I get the chance.

pkishino commented 8 years ago

any update on this?

rpocklin commented 7 years ago

If anyone wants to breathe life into this PR or has an alternative, let me know.