v-list close group when list-item is clicked - vue.js

I've this v-navigation drawer in my project. It contains both v-list-items and a v-list-group. When clicking an v-list-item, and the v-list-group is expanded, I want the group to be collapsed. How can this be done?
<v-app id="t">
<v-navigation-drawer dark v-model="sidebar" app>
<v-list>
<v-list-item router-link to='/Test'>
<v-list-item-title>Test</v-list-item-title>
</v-list-item>
<v-list-item router-link to='/Test2'>
<v-list-item-title>Test2</v-list-item-title>
</v-list-item>
<v-list-group :value="true">
<template v-slot:activator>
<v-list-item-title>Title</v-list-item-title>
</template>
<v-list-item
v-for="item in mobAdminItems"
:key="item.title"
:to="item.linkTo"
>
<v-list-item-content>
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-group>
<v-list-item router-link to='/Test3'>
<v-list-item-title>Test3</v-list-item-title>
</v-list-item>
<v-list-item router-link to='/Test4'>
<v-list-item-title>Test4</v-list-item-title>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>

You can just add v-model into v-list-group component and assign it to some variable. Changing this variable will lead to expand / collapse actions.
<v-list-group v-model="groupOpened">
<template v-slot:activator>
<v-list-item-title>Title</v-list-item-title>
</template>
<v-list-item
v-for="item in mobAdminItems"
...
#click="groupOpened = false"
>
<v-list-item-content>
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-group>
...
data () {
return {
...
groupOpened: false,
}
}
Test this at CodePen.

Related

Vuetify list subgroup auto collapse when clicked

I have the following 2-level vuetify list . However, when I tried clicking on a child of the subgroup, the subgroup just collapsed like in the second half of this video.
I notice that when clicking on the child item, the sub list (Stock Statistics)'s isActive property is set to false.
How do I fix so that the subgroup remain open when I click on its child? Thanks in advance!
<template>
<v-list nav expand>
<template v-for="({ label, icon, group, subItems }, index) in items">
<v-list-group
v-if="subItems && subItems.length"
:key="index"
:group="group"
class="v-list--dense"
color="default"
append-icon="mdi-menu-down"
active-class="v-list-group--active"
>
<template #activator>
<v-list-item-icon class="mr-1">
<v-icon color="grey" v-text="icon"></v-icon>
</v-list-item-icon>
<v-list-item-content class="overflow-visible">
<v-list-item-title
class="subtitle-2"
v-text="$t(label)"
></v-list-item-title>
</v-list-item-content>
</template>
<template v-for="(child, idx) in subItems">
<v-tooltip v-if="!child.subChildItems" :key="idx" right>
<template #activator="{ on, attrs }">
<v-list-item
nuxt
:to="{ name: child.routeName }"
v-bind="attrs"
v-on="on"
>
<v-list-item-icon class="ml-4 mr-0">
<v-icon >mdi-circle-small</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title
v-text="$t(child.label)"
></v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
<span>{{ $t(child.label) }}</span>
</v-tooltip>
<v-list-group
v-else
:key="idx"
:group="child.subGroup"
sub-group
class="v-list--dense"
color="default"
prepend-icon="mdi-circle-small"
active-class="v-list-group--active"
>
<template #activator>
<v-list-item-content class="overflow-visible" style="margin-left: -16px;">
<v-list-item-title
class="subtitle-3"
v-text="$t(child.label)"
></v-list-item-title>
</v-list-item-content>
<v-list-item-icon class="ml-0 mr-0">
<v-icon>mdi-menu-down</v-icon>
</v-list-item-icon>
</template>
<template
v-for="(
{ label, routeName }, idxChild
) in child.subChildItems"
>
<v-tooltip :key="idxChild" right>
<template #activator="{ on, attrs }">
<v-list-item
nuxt
subheader
:to="{ name: routeName }"
v-bind="attrs"
v-on="on"
>
<v-list-item-icon class="ml-4 mr-0">
-
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title
v-text="$t(label)"
></v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
<span>{{ $t(label) }}</span>
</v-tooltip>
</template>
</v-list-group>
</template>
</v-list-group>
</template>
</v-list>
</template>

Vuetify Set Toolbar and navigation drawer simultaneously

I want to set navigation drawer alone with toolbar and toggle drawer from toolbar.
Code:
<v-navigation-drawer absolute temporary left v-model="drawer">
<v-list-item-title class="text-h6"> </v-list-item-title>
<v-list nav dense>
<div v-for="(link, i) in links" :key="i">
<v-list-item v-if="!link.subLinks" :to="link.to" class="v-list-item">
<v-list-item-icon>
<v-icon>{{ link.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-title v-text="link.text" class="subtitle-2" />
</v-list-item>
<v-list-group
v-else
:key="link.text"
no-action
:prepend-icon="link.icon"
:value="false"
>
<template v-slot:activator>
<v-list-item-title>{{ link.text }}</v-list-item-title>
</template>
<v-list-item
v-for="sublink in link.subLinks"
:to="sublink.to"
:key="sublink.text"
>
<v-list-item-icon>
<v-icon>{{ sublink.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-title class="subtitle-2">{{ sublink.text }}</v-list-item-title>
</v-list-item>
</v-list-group>
</div>
</v-list>
</v-navigation-drawer>
<v-toolbar color="primary" right #click.stop="drawer = !drawer">
<v-app-bar-nav-icon #click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-spacer></v-spacer>
</v-toolbar>
As you can see I have set both navigation-drawer and toolbar.
Currently:
Expected:
Replace the v-toolbar with v-app-bar
Add app clipped-left props to v-app-bar
Remove absolute temporary props from the drawer
Add app clipped fixed props to the drawer

Collapse all list and expand only the selected list in vuetify

I have a v-list-group with 2 sub-group inside it like in the image shown below. Whenever I click the parent list-group other groups are getting collapsed, but when I click a sub-group inside a list-group, other sub-group inside the list-group are not getting collapsed. Ex: when I click Admin, the Actions sub-group is not getting collapsed.
codepen: https://codepen.io/eajithkumar128/pen/BaoEeqW?editable=true&editors=101%3Dhttps%3A%2F%2Fvuetifyjs.com%2Fen%2Fcomponents%2Flists%2F
<div id="app">
<v-app id="inspire">
<v-card
class="mx-auto"
width="300"
>
<v-list>
<v-list-group
prepend-icon="account_circle"
value="false"
>
<template v-slot:activator>
<v-list-item-title>Users</v-list-item-title>
</template>
<v-list-group
no-action
sub-group
value="true"
>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>Admin</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
v-for="(admin, i) in admins"
:key="i"
link
>
<v-list-item-title v-text="admin[0]"></v-list-item-title>
<v-list-item-icon>
<v-icon v-text="admin[1]"></v-icon>
</v-list-item-icon>
</v-list-item>
</v-list-group>
<v-list-group
sub-group
no-action
>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>Actions</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
v-for="(crud, i) in cruds"
:key="i"
#click=""
>
<v-list-item-title v-text="crud[0]"></v-list-item-title>
<v-list-item-action>
<v-icon v-text="crud[1]"></v-icon>
</v-list-item-action>
</v-list-item>
</v-list-group>
</v-list-group>
<v-list-group
prepend-icon="account_circle"
value="false"
>
<template v-slot:activator>
<v-list-item-title>Users</v-list-item-title>
</template>
</v-list-group>
</v-list>
</v-card>
</v-app>
</div>
this can be simply done by using a v-model with every v-list-group. Something like this:
<v-list-group v-model="SubActive[header+subheader]" no-action sub-group v-for="(subheader, sIndex) in header.SubHeaderList" :key="sIndex" >
<template v-slot:activator>
<v-list-item-content v-on:click="subToggle(header,subheader)">
<v-list-item-title>
<span>{{subheader.Title}}</span>
</v-list-item-title>
</v-list-item-content>
</template>
SubActive is a Vue data object with keys as header+subheader (to uniquely identify each subheader) and its initial value will be set to false for all subheaders.
The subToggle function will simply switch the rest of the values to false(to collapse them all except the one which is clicked):
subToggle(brand, category) {
for (let i = 0; i < Object.keys(this.SubActive).length; i++) {
if (brand + category != Object.keys(this.SubActive)[i]) {
this.SubActive[Object.keys(this.SubActive)[i]] = false;
}
}
},

How to pass properties from grandchild menu object to grandparent?

my employer decided to expand the menu bar with another sub-pages, and things that works completely fine previously (simple one sub-menu) now don't want to work, because it has sub-menu, under another sub-menu.
Here is the pics:
As you can see when I hover "Acts" the sub menu with External and Internal documents works perfectly fine
but when I would like to move cursor on another sub-menu with "Director's Orders", whole menu is hiding. I think it's because second sub-menu (grandchild) don't pass info to main menu element (grandparent) to keep menu active, but I have no idea how to fix it.
Here is the code:
<v-menu open-on-hover bottom offset-x transition="slide-x-transition">
<template v-slot:activator="{ on }">
<v-list-item link v-on="on">
<v-list-item-content>
<v-list-item-title class="subtitle-1">Acts <v-icon class="menu-icon">keyboard_arrow_right</v-icon></v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
<v-list color="#F0FAFE">
<router-link to="/External"><v-list-item link>
<v-list-item-content>
<v-list-item-title class="subtitle-1 font-weight-medium">External</v-list-item-title>
</v-list-item-content>
</v-list-item></router-link>
<v-menu open-on-hover bottom offset-x transition="slide-x-transition">
<template v-slot:activator="{ on }">
<v-list-item link v-on="on">
<v-list-item-content>
<v-list-item-title class="subtitle-1 font-weight-medium">Internal <v-icon class="menu-icon">keyboard_arrow_right</v-icon></v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
<v-list color="#F0FAFE">
<v-menu open-on-hover bottom offset-x transition="slide-x-transition">
<template v-slot:activator="{ on }">
<v-list-item link v-on="on">
<v-list-item-content>
<v-list-item-title class="subtitle-1 font-weight-medium">Director's Orders <v-icon class="menu-icon">keyboard_arrow_right</v-icon></v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
<v-list
color="#F0FAFE"
v-for="(item, index) in Orders"
:key="index"
>
<router-link :to="'/' + item.title"><v-list-item link>
<v-list-item-content>
<v-list-item-title class="subtitle-1 font-weight-medium">{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item></router-link>
</v-list>
</v-menu>
<router-link to="/Other"><v-list-item link>
<v-list-item-content>
<v-list-item-title class="subtitle-1 font-weight-medium">Other</v-list-item-title>
</v-list-item-content>
</v-list-item></router-link>
</v-list>
</v-menu>
</v-list>
</v-menu>
And little disclaimer. Yes I know this type of menu isn't a Material Design menu, which is the base for vuetify
I don't think v-menu supports nested menus (at least not when opening them with mouseover).
You'd have to make one yourself with nested v-hover. You can create a recursive component building the menu from a nested array of items.
Something like this:
<template>
<v-list color="#F0FAFE" class="menu">
<v-hover v-for="item in items" :key="item.title" v-slot="{ hover }">
<router-link v-if="item.route" :to="item.route" class="item">
<v-list-item link>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</router-link>
<v-list-item v-else class="item">
<v-list-item-content>
<v-list-item-title>{{ item.title }} -></v-list-item-title>
</v-list-item-content>
<NestedMenu v-if="item.children && hover" :items="item.children"/>
</v-list-item>
</v-hover>
</v-list>
</template>
<script>
export default {
name: "NestedMenu",
props: {
items: { type: Array, default: () => [] }
}
};
</script>
Here is a working example (which need some styling tho): https://codesandbox.io/s/nestedmenu-u8tk1?file=/src/components/NestedMenu.vue
Add more items and levels on menuItems in App.vue.

How to add content to Vuetify (v-navigation-drawer)

I found this codepen: https://codepen.io/carl_/pen/QWwgqBa, which closely does as I want.
But there is no content/text on the right side.
And I cant figure out how to add content on the right side.
I have tried to google the problem and found solutions like "add v-content", "it needs to be inside v-app". But none of these actually got the content on the right side. It ended below the card or inside the navigation-drawer.
How can I manage to get content on the right side of the menu?
<div id="app">
<v-app id="inspire">
<v-card style="width:800px;margin:40px auto">
<v-navigation-drawer
expand-on-hover
permanent
>
<template v-slot:prepend>
<v-list>
<v-list-item>
<v-list-item-avatar>
<v-img src="https://randomuser.me/api/portraits/women/85.jpg"></v-img>
</v-list-item-avatar>
</v-list-item>
<v-list-item
link
two-line
>
<v-list-item-content>
<v-list-item-title class="title">Sandra Adams</v-list-item-title>
<v-list-item-subtitle>sandra_a88#gmail.com</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-icon>mdi-menu-down</v-icon>
</v-list-item-action>
</v-list-item>
</v-list>
</template>
<v-divider></v-divider>
<v-list
nav
dense
>
<v-list-item link>
<v-list-item-icon>
<v-icon>mdi-folder</v-icon>
</v-list-item-icon>
<v-list-item-title>My Files</v-list-item-title>
</v-list-item>
<v-list-item link>
<v-list-item-icon>
<v-icon>mdi-account-multiple</v-icon>
</v-list-item-icon>
<v-list-item-title>Shared with me</v-list-item-title>
</v-list-item>
<v-list-item link>
<v-list-item-icon>
<v-icon>mdi-star</v-icon>
</v-list-item-icon>
<v-list-item-title>Starred</v-list-item-title>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-card>
</v-app>
</div>
<v-layout> was the attribute I needed to add.