Whats the cleanest way to add the active class to bootstrap link components?

Published 3 years ago by cullymason

Every method I have ever come up with always seems like a hack. Id like to be able to do something like, if the url matches this pattern then this element is active.

Best Answer (As Selected By cullymason)
psyao
christopher
<li {{ Request::is('/url') ? ' class="active"' : null }}>...</li>
muffycompoqm

Really looks simple...but does it work well with dynamic urls since it depends on what url one is currently in.

mabasic

I have a file called Helpers.php:

<?php

/*
|--------------------------------------------------------------------------
| Detect Active Route
|--------------------------------------------------------------------------
|
| Compare given route with current route and return output if they match.
| Very useful for navigation, marking if the link is active.
|
*/
function isActiveRoute($route, $output = "active")
{
    if (Route::currentRouteName() == $route) return $output;
}

/*
|--------------------------------------------------------------------------
| Detect Active Routes
|--------------------------------------------------------------------------
|
| Compare given routes with current route and return output if they match.
| Very useful for navigation, marking if the link is active.
|
*/
function areActiveRoutes(Array $routes, $output = "active")
{
    foreach ($routes as $route)
    {
        if (Route::currentRouteName() == $route) return $output;
    }

}

And then you can use in your navbar:

<li class="{{ isActiveRoute('home') }}"><a href="{{ route('home') }}">Home</a></li>

or

<li class="{{ areActiveRoutes(['client.index', 'client.create', 'client.show']) }}"><a href="{{ route('client.index') }}"><i class="fa fa-users"></i> Clients</a></li>

This is very handy, because you can use route names and handle multiple route names.

I think that you can find a video on Laracasts on how to do this, because that is where I have found this solution.

psyao
psyao
3 years ago (103,300 XP)
bashy
bashy
3 years ago (1,001,160 XP)

I use this in my projects

app/helpers/menu.php

class Menu {

 public static function activeMenu($uri='')
 {
  $active = '';

  if (Request::is(Request::segment(1) . '/' . $uri . '/*') || Request::is(Request::segment(1) . '/' . $uri) || Request::is($uri))
  {
   $active = 'active';
  }

  return $active;
 }

}

In view

<a href="{{ route('blog.index') }}" class="{{ Menu::activeMenu('blog') }}">Blog</a>
claudiu_pelmus

@bashy Hey. Not sure if I'm doing a good thing by posting to this thread, however because I am in the same situation and because I adopted your way of going with the help, I must ask you why don't I get something when using your code although my URI looks like this http://www.example.xyz/categorii/muzica

claudiu_pelmus

@bashy Sorry, it was my mistake. I dd in the custom helper class itself and I've managed to see what I was doing wrong. I passed in the argument same as what segment(1) returned. Therefore it was something like "categorii/categorii" instead of "categorii/muzica". Sorry for the trouble.

bashy
bashy
2 years ago (1,001,160 XP)

@claudiu_pelmus No problem. Quite old code so may not be the best way in the newer versions :P that was back in 4.2 days.

claudiu_pelmus

@bashy Well, I'm new to Laravel, however from my point of view Service Providers would be the way to go with this. And I would appreciate if you can prove me wrong or right, because I can't understand IoC and Service Providers although I read the docs like 10 times. But that how I see Service Provider put to great use.

claudiu_pelmus

@bashy By the way, I'm using Laravel 5.2

bashy
bashy
2 years ago (1,001,160 XP)

@claudiu_pelmus Well that snippet only does one level so I normally do this now

/*
    |--------------------------------------------------------------------------
    | Detect Active Route
    |--------------------------------------------------------------------------
    |
    | Compare given route with current route and return output if they match.
    | Very useful for navigation, marking if the link is active.
    |
    */
    public static function isActiveRoute($route, $output = 'active')
    {
        if (Route::currentRouteName() == $route) {
            return $output;
        }
    }

    /*
    |--------------------------------------------------------------------------
    | Detect Active Routes
    |--------------------------------------------------------------------------
    |
    | Compare given routes with current route and return output if they match.
    | Very useful for navigation, marking if the link is active.
    |
    */
    public static function areActiveRoutes(Array $routes, $output = 'active')
    {
        foreach ($routes as $route) {
            if (Route::currentRouteName() == $route) {
                return $output;
            }
        }
    }
mabasic

I've written a package for this: https://github.com/laravelista/Ekko

cheycron

bashy solution is fine in most of the cases, but fail when you have pagination or use params. So, a little help with preg_replace:

function isActiveRoute( $route, $params = [], $output = "active" ) {
    if ( route( $route, $params ) == preg_replace( '/&page=(\d+)/', '', url()->full() ) ) {
        return $output;
    }
}
richwilliamson

What about tabs where you want to set the first tab as being "active"?

<?php $i = 0 ?>
@foreach ($blahs as $blah)
    
    @if ($i == 0)
        <li class="active">
        <?php $i = 1 ?>
    @else
        <li>
    @endif
        <a href="#tab_{{ $blah->id }}" data-toggle="tab">{{ $blah->name }}</a>
    </li>
@endforeach
bashy
bashy
2 years ago (1,001,160 XP)

@richwilliamson Like so?

<ul>
    @foreach($blahs as $blah_key => $blah)
        <li class="{{ ($blah_key == 0 ? 'active' : '') }}">
            <a href="#tab_{{ $blah->id }}" data-toggle="tab">{{ $blah->name }}</a>
        </li>
    @endforeach
</ul>

Please sign in or create an account to participate in this conversation.