lavary/laravel-menu

Active Link on Class is Missing

Closed this issue · 3 comments

Same problem here.

My config file looks like :

return array(
    'default' => array(
        'auto_activate' => true,
        'activate_parents' => false,
        'active_class' => 'active',
        'restful' => false,
        'cascade_data' => true,
        'rest_base' => '',      // string|array
        'active_element' => 'link',  // item|link
    ),
);

Ma Menu

$dashboard = $item->add('<i class="flaticon2-protection"></i>', ['route' => 'shopper.dashboard', 'class' => 'aside__nav-item']);
            $dashboard->link->attr([
                'class' => 'aside__nav-link',
                'data-toggle' => 'tooltip',
                'data-title' => __('Dashboard'),
                'data-placement' => 'right',
                'data-container' => 'body',
                'data-boundary' => 'window'
            ]);

            $site = $item->add('<i class="flaticon2-browser-1"></i>', ['url' => url('/'), 'class' => 'aside__nav-item']);
            $site->link->attr([
                'class' => 'aside__nav-link',
                'data-toggle' => 'tooltip',
                'data-title' => __('Open site'),
                'data-placement' => 'right',
                'data-container' => 'body',
                'data-boundary' => 'window',
                'target' => '_blank'
            ]);

But i don't have active class on my link

Originally posted by @mckenziearts in #245 (comment)

@mckenziearts This might be a different problem. Are you on the latest version?

You're manually setting a class on your link "aside__nav-link" if you remove that, does the active link show up?

The issue is caused by how the attr() method works on \Lavary\Menu\Link.
The active class for a Link is set during the Item constructor while also not supporting passing a Link class in the Item constructor.

Whenever an Item is created a Link is also constructed, however in order to pass a custom class to the link, we first need to retrieve the link via ->link() and then call the ->attr() method on it, which via the number of arguments either returns attributes, sets attributes, returns a specific attribute or sets a specific attribute.

This also causes the active class to overwrite, as active class on a Link is set during Item construction and this method overwrites the attribute / attributes.

In order for this to work properly, we need to do a bit of hacking, which seems to be the only way right now:

            $attributes = $m->link->attr(); // return all attributes of the Link
            $attributes['class'] = ($attributes['class'] ?? '') . ' custom-class'; //append custom class & avoid php warning for unset index
            $item->link->attr($attributes); // set all attributes for the link

There seem to be two solutions - either allow passing Link class to the Item constructor, or add a method ->addClass(string $class) on the Link for appending the Link class.

This issue may be resolved with #272