Change Body Class Based On URL in Meteor
Asked Answered
D

2

2

I have a template named layout in my app. Inside has:

<body id="body class="{{blue}}>

Basically what I want to achieve is that when you hit a url, for example, www.abc.com/sky, I want to add a body class of blue:

<body id="body class="blue">

In my client folder I have this but seems not to work:

Template.layout.helpers({
  blue: function() {
    var loc = window.location.href; // returns the full URL
    if(/sky/.test(loc)) {
    $('#body').addClass('blue');
    }
  }
});

I am new to the javascript world and I am following a tutorial but the tutorial was not aimed for Meteor.

Dex answered 1/5, 2015 at 20:43 Comment(2)
Are you using iron router?Spiceberry
Hi @DavidWeldon yes I am.Dex
S
5

You shold modify DOM elememts in onRendered like this:

Template.layout.onRendered(function() {
  // get the current route name (better than checking window.location)
  var routeName = Router.current().route.getName();

  // add the class to body if this is the correct route
  if (routeName === 'myRoute')
    $('body').addClass('blue');
});

Template.layout.onDestroyed(function() {
  // remove the class to it does not appear on other routes
  $('body').removeClass('blue');
});

An alternative (and probably easier) solution is just to use a helper on your body template:

Template.body.helpers({
  klass: function() {
    if (Router.current().route.getName() === 'myRoute') {
      return 'blue';
    }
  }
});

Then your body could look like this:

<body class="{{klass}}"></body>
Spiceberry answered 1/5, 2015 at 21:1 Comment(3)
Works perfectly. The last option was best as the top does not like to be reactive.Dex
The {{klass}} in my html seems to only work when it is actually inside the body tag....Johnnie
Router.current().route.path() worked for me. (Router.current().route.getName() didn't)Honna
M
0

I too needed this feature and found the same issue as @phocks in that {{klass}} only works inside and not on the body tag. I'm new at Meteor but here's my approach that just uses some jQuery:

Template.body.onRendered(function(){
    var instance = this;
    instance.autorun(function() {
        FlowRouter.watchPathChange();
        var context = FlowRouter.current();
        // this does the trick, below
        $('body').attr('class', '').addClass(context.route.name);   

        // this is just to do more CSS stuff if they're logged in
        if(Meteor.userId()){
            $('body').addClass('logged-in');   
        } else {
            $('body').removeClass('logged-in');   
        }
    });
});

I use this in a body.js file, and this code relies on FlowRouter. On path changes, I get the name I declared for the route, remove any previous route names from the body tag, then add the current route's name.

As a small side note, I also add a class of logged-in to the body for authenticated users, so that's what the bottom few lines are doing.

Mouton answered 18/1, 2016 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.