yii2-bootstrap icon indicating copy to clipboard operation
yii2-bootstrap copied to clipboard

Automatically hide parent 'yii\bootstrap\Nav' section if all subitems are hidden

Open arogachev opened this issue 9 years ago • 4 comments

Consider this example.

$menuItems = [
    [
        'label' => 'Miscellaneous',
        'items' => [
            [
                'label' => 'Users',
                'url' => ['/users/index'],
                'visible' => Yii::$app->user->can('users.manage'),
            ],
            [
                'label' => 'Slides',
                'url' => ['/slides/index'],
                'visible' => Yii::$app->user->can('slides.manage'),
            ],          
            [
                'label' => 'News,
                'url' => ['/news/index'],
                'visible' => Yii::$app->user->can('news.manage'),
            ],
        ],        
    ],
];

 echo Nav::widget([
    'options' => ['class' => 'navbar-nav navbar-right'],
    'items' => $menuItems,
]);

If the user doesn't have permissions to manage users, slides and news, Miscellaneous section will be still shown, but it doesn't make sense because it doesn't have a link (click triggers visibility of subitems).

To conditionally hide it we have to add something like this to parent section:

'visible' => Yii::$app->user->can('users.manage') ||
    Yii::$app->user->can('slides.manage') ||
    Yii::$app->user->can('news.manage'),

This is clean violation of DRY principle. Obviously we can have a helper method for checking that, but still we need to list permissions in both places, It's better to be done inside Nav widget itself.

So, if parent section have all subitems with visible property set and visible equals false in all subitems, we can just skip rendering of this whole section.

arogachev avatar Feb 02 '16 08:02 arogachev

Yep, that makes sense.

samdark avatar Feb 02 '16 09:02 samdark

OK, I will try to send a PR in this case.

arogachev avatar Feb 02 '16 09:02 arogachev

Done.

arogachev avatar Feb 02 '16 11:02 arogachev

You all forget that \yii\bootstrap\Dropdown supports items specified as a string:

    /**
     * @var array list of menu items in the dropdown. Each array element can be either an HTML string,
     * or an array representing a single menu with the following structure:
     * ...
     * To insert divider use `<li role="presentation" class="divider"></li>`.
     */
    public $items = [];

Currently such items are considered always visible. So if the OP were to put a divider in his example, the Nav won't be hidden which is not what a user would expect from this additional functionality.

PowerGamer1 avatar Jul 28 '16 07:07 PowerGamer1