user5431121
user5431121

Reputation:

Change body tag class in Angular 1

My problem is I have multiple pages that require a different body class for each page.

So without using $rootScope how can I change this in the DOM depending on which page is being displayed?

<body class="class-that-needs-changing">

Upvotes: 3

Views: 1645

Answers (5)

Shaishab Roy
Shaishab Roy

Reputation: 16805

instead of using $rootScope you can make a listener to detect view change means $routeChangeSuccess (I guess you used $routeProvider to change view) and you should have a parent controller in which you create your listener

like:

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

app.controller('parentController', function($scope, $route) {
    $scope.$on('$routeChangeSuccess', function(newValue, oldValue) {
        if ( newValue !== oldValue ) {
            $scope.bodyClass = $route.current.viewClass;
        }
    });
});

and your provider should like:

app.config(function($routeProvider) {
    $routeProvider.when('/list',{
       controller: 'listController',
       templateUrl: '/list.html',
       viewClass:  'class1'
    }).when('/details', {
       controller: 'detailsController',
       templateUrl: '/details.html',
       viewClass:  'class2'
    }).otherwise({
       redirectTo: '/list'
    });
});

so your HTML should like:

<body ng-controller="parentController" class="commonClasses" ng-class="bodyClass ">

Can visit PLUNKER DEMO

Upvotes: 0

byteC0de
byteC0de

Reputation: 5273

You can configure it on app.js

//app.js

angular.module('myApp', [
   'ngCookies',
   'ngResource',
   'ngSanitize',
   'ngRoute'
])
.constant('config', {
   user1:'class1',
   user2:'class2'
})

// main.js

angular.module('myApp').controller('MainCtrl', [ '$scope', 'config',
   function ($scope, config) {
       console.log(config.user1);
   }
]);

Upvotes: 0

Shashank Agrawal
Shashank Agrawal

Reputation: 25797

Let's make use of a directive like this:

.directive('bodyClasses', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var classes;

            scope.$watch(function(scope) {
                return scope.$eval(attrs.bodyClasses);
            }, function(value) {
                classes = value;
                angular.element(document.body).addClass(value);
            });

            // Remove body class when scope or directive destroyed.
            scope.$on('$destroy', function() {
                angular.element(document.body).removeClass(classes);
            });
        }
    };
});

Now, use this directive in your separate HTML pages like this:

<!-- remember, use single quote for string since we are evaluating it -->
<div body-classes="'new-class another-class'"></div>

or

<span body-classes="'foo' {{someScopeVariable}}"></div>

As a particular page or view will load, those classes will be added to the body tag. In this way, you can keep your class separate in each individual page and your main body tag will not clutter.

Upvotes: 1

MarkoCen
MarkoCen

Reputation: 2324

Based on your posting, I suggest changing the body class in angular.Module.run, this method would register a task which would be executed when angular application fully loaded:

angular.module('myApp', [])
   .run(['$scope', function($scope){

        var className = 'different-classes';
        angular.element(document.body).addClass(className);

   }]);

since your multiple pages are totally different html files, the angular application would be reloaded each time after navigating from one page to another

Upvotes: 0

gnicholas
gnicholas

Reputation: 2077

You have two main options:

  1. Add a variable to the $rootScope and be done with it. If you only have this one global setting for the body class that needs to be changed I would suggest this as it is easy.
  2. Make an angular service that handles global page settings. Inject this service into the controllers that need to have the global page settings and then retrieve the global page settings from the service and bind them to each controller scope. If you have many global settings or need any business logic to happen then use this service approach instead.

Upvotes: 0

Related Questions