Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS have ng-view display a dynamic footer outside of its div

I'm fairly new to angular.js so I'm seeking advice on how to best implement the functionality described here. I have an html body with header, sidebar and a content area provided by <div class="container-fluid" ng-view></div>. Because this is a standard twitter-bootstrap layout , the ng-view is not a direct descendant of the body element.

I have one view that shall contain an infinitely scrollable list. When at least one element of the list is selected, I want to slide-up a footer that contains contextual actions (the footer shall be position:fixed so that it's always displayed on top of the list). In essence this is similar to what happens on the Windows 8 Metro home-screen when you right click a tile.

The problem I now have is that the footer can't be part of the ng-view partial because it needs to live directly under the body in the DOM. What's a good way to handle this with Angular.js and ng-view when I'd want to keep a single controller for the list and the dynamic footer? If there's a CSS solution to this, I'd be happy to hear about it too.

like image 424
Johannes Rudolph Avatar asked Dec 02 '25 09:12

Johannes Rudolph


1 Answers

It sounds like you need to have the footer outside the ng-view element in order to handle the layout you are wanting. I'll leave the layout/CSS to you but the following example demonstrates a way to communicate with the directive if it were to live outside ng-view.

Here's a plunkr (http://plnkr.co/edit/NpoIrOdfvn9XZiXY9YyV?p=preview).

HTML

<body ng-app="someApp">
    <div ng-view></div>
    <footer-directive></footer-directive>
</body>

JS

angular.module('someApp', []).config(function($routeProvider) {
    $routeProvider.when('/', {
        template: '<p>template</p>',
        controller: 'SomeCtrl'
    }).otherwise({
        redirectTo: '/'
    });
}).service('broadcastService', function($rootScope, $log) {
    this.broadcast = function(eventName, payload) {
        $log.info('broadcasting: ' + eventName + payload);
        $rootScope.$broadcast(eventName, payload);
    };
}).controller('SomeCtrl', function(broadcastService, $log, $timeout) {
    //fire off showfooter message
    broadcastService.broadcast('ShowFooter', {
        some: 'data'
    });

    // wait 3 seconds and hide footer
    $timeout(function() {
        //fire off hide message
        broadcastService.broadcast('HideFooter');
    }, 3000);

}).directive('footerDirective', function(broadcastService, $log) {
    return {
        restrict: 'E',
        link: function(scope, elm, attr) {
            elm.hide();
            scope.$on('ShowFooter', function(payload) {
                $log.info('payload received');
                $log.debug(payload);
                // assuming you have jQuery
                elm.show();
            });
            scope.$on('HideFooter', function() {
                // assuming you have jQuery
                elm.hide();
            });
        }
    }
});
like image 185
Brian Lewis Avatar answered Dec 04 '25 01:12

Brian Lewis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!