Devon
Devon
1 year ago (56,090 XP)

@rulatir, that's not possible without manual hints, it would need to know what route to hit and what parameters to use to determine the URL. One approach might be to create a view composer that builds the link for you. Pass in the link as normal, and it'd be able to compare what you provide to the current request...

However, and this part is relevant to @kristjan.reinsberg too, you'll need to keep in mind that some people may be using this in a submenu which also require an active class. To do that, you'd likely end up having to add extra logic for those cases too which would leave you with something similar to what others have posted, having to parse the links ahead of time, or building out a class like the paginator to render the entire menu.

reflection_hu

Guys what about component-based solutions?

menuitem.blade.php:

<li class="nav-item" role="tab">
    <a class="nav-link ripple @if (Route::currentRouteName() == $routeName) active @endif"
    href="{{route($routeName)}}" aria-expanded="true" aria-controls="collapse-dashboards">
        <i class="{{$icon}}"></i>
        <span>{{$title}}</span>
    </a>
</li>

view:

<ul class="nav flex-column custom-scrollbar" id="sidenav" data-children=".nav-item">
    @component('ui.components.menuitem', ['routeName' => 'dashboard', 'title' => trans('menu.dashboard'), 'icon' => 'icon s-4 fa fa-dashboard'])
    @endcomponent
</ul>

...and finally add class to parent item to open submenu.

    $('document').ready(function () {
        $('.nav-item ul.collapse').find('a.active').closest('ul').addClass('show');
    });
Mohannad

Hello Guys,

I'm looking for a reviews, corrections, comments or feedback for my first package: mohannadnaj/active-state. I don't know if it fit to be considered as a solution to this problem or not.

Quoting from the Readme:

Installation:

composer require mohannadnaj/active-state

Problem:

$current_page = 'contact'; 

<li class="<?= $current_page == 'home' ? 'active' : '' ?>"><a href="#home">Home</a></li>
<li class="<?= $current_page == 'about' ? 'active' : '' ?>"><a href="#about">About</a></li>
<li class="<?= $current_page == 'contact' ? 'active' : '' ?>"><a href="#contact">Contact</a></li>

Solution:

The package will load the methods set_active, get_active and is_active, set_active will set a given settings to a static variable inside the Mohannadnaj\Active class, this settings answer the questions: what is the active item? what should it return if the check is passed? or should it return boolean? and what is the key you want to attach all this settings to?

The above example can be translated to:

set_active('navbar', 'about');

<li class="<?= is_active('navbar', 'home'); ?>"><a href="#home">Home</a></li>
<li class="<?= is_active('navbar', 'about'); ?>"><a href="#about">About</a></li>
<li class="<?= is_active('navbar', 'contact'); ?>"><a href="#contact">Contact</a></li>

the set_active method will consider the first argument set_active('navbar' , ...) as a setter for the active element we want to catch later, that is 'about'.

usage examples:

    set_active('navbar', 'index');
    set_active('sidebar', 'info');

    is_active('navbar','index'); // return "active"
    is_active('navbar','about'); // return null
    
    is_active('sidebar','info'); // return "active"
    is_active('sidebar','warning'); // return null
    
    get_active('navbar'); // return 'index';
    get_active('sidebar'); // return 'info';
    
    set_active('navbar3', 'register',['true'=>'is-active-css-class', 'false'=> 'not-active']);

    is_active('navbar3', 'register'); // return 'is-active-css-class'
    is_active('navbar3', 'login'); // return 'not-active'
bonifazzy

My solution:

  1. Create app/Http/Helpers/BasicViewHelper.php with this code inside:
namespace App\Http\Helpers;

use Illuminate\Http\Request;

class BasicViewHelper {
    
    public static function navClass($action){
        if (request()->action == $action){
            return 'active';
        }
    }
}
  1. Add this string to aliases array in config/app.php
'BasicViewHelper' => App\Http\Helpers\BasicViewHelper::class
  1. Use this markup in your layout
<ul class="nav navbar-nav">
    <li class="{{ \BasicViewHelper::navClass('') }}">
        <a href="/admin">Dashboard</a>
    </li>
    <li class="{{ \BasicViewHelper::navClass('tags') }}">
        <a href="/admin/tags">Tags</a>
    </li>
    <li>
</ul>

Helper will return class name for nav item depending on current route.

I've created this function in routes/web.php to dispatch my routes. Controller is hardcoded in there, but you can make some changes to make it variable.


Route::any('/admin/{action?}/{arg?}', function ($actionName = 'index', $arg = null, Request $request) {
    $controllerName = 'admin';
    $app = app();
    $cameledController = ucfirst(str_replace(' ', '', ucwords(str_replace('-', ' ', $controllerName))));
    $cameledAction = ucfirst(str_replace(' ', '', ucwords(str_replace('-', ' ', $actionName))));
    
    try{
        $controller = $app->make(sprintf('\App\Http\Controllers\%sController', $cameledController));
        return $controller->callAction($cameledAction, array($arg ?: $request, $request));
    } catch(Exception $e) {
        if ($e instanceof ReflectionException || $e instanceof BadMethodCallException) {
           abort(404);
        } else {
            throw $e;
        }
    }
})->middleware('auth');

johnef_sh

@bonifazzy I don't see where is app/Http/Helpers/ did you created this folder??

consil

@johnef_sh see step 1:

Create app/Http/Helpers/BasicViewHelper.php...

zoispag

My original implementation using blade directives, didn't work because of caching.

Here is my implementation using a helper:

if (! function_exists('active_menu')) {
    function active_menu($routes)
    {
        return in_array(Route::currentRouteName(), explode('|', $routes)) ? 'active' : '';
    }
}

In my views:

<li class="{!! active_menu('cars.edit|cars.index') !!}">
    <a href="#">Cars</a>
</li>
choo737

Here is the way I did for mine..

<ul class="navbar-nav navbar-nav-right">
    <li class="nav-item"><a class="nav-item-child nav-item-hover {{{ (Route::current()->getName() == "home" ? 'active' : '') }}}" href="/">Home</a></li>
    <li class="nav-item"><a class="nav-item-child nav-item-hover {{{ (Route::current()->getName() == "about" ? 'active' : '') }}}" href="/about">About</a></li>
    <li class="nav-item"><a class="nav-item-child nav-item-hover {{{ (Route::current()->getName() == "products.index" ? 'active' : '') }}}" href="/products">Products</a></li>
</ul>
razz
razz
1 month ago (2,930 XP)

You actually had it right, only a little edit would make it work flawlessly.

this will work:

  • Home
  • Explanation:

    1- you used {{{ instead of {{ 2- you had php echo 'class=active' which resulted in this in the html

  • I know my response is late but I hope it helps someone.

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