Vuetify - Prevent v-list-item-group De-selection - vue.js

I have a v-list and v-list-item-group setup very similar to the one shown here in the Vuetify help:
https://vuetifyjs.com/en/components/lists/#flat
My problem comes if the user clicks on the same v-list-item twice - which then de-selects it without selecting another item.
I've tried mapping the v-model to a computed get(), set() and stopping the set, but this doesn't have any effect.
I really want the selected item to be set programmatically and I control it from an #click event.

Have you tried to use the mandatory property of v-list-item-group? It seems to do something close to what you want - the user cannot de-select an item, but can switch to another one. Something like this:
<v-card class="mx-auto" max-width="300" tile>
<v-list flat>
<v-subheader>REPORTS</v-subheader>
<v-list-item-group v-model="selectedItem" color="primary" mandatory>
<v-list-item v-for="(item, i) in items" :key="i">
<v-list-item-icon>
<v-icon v-text="item.icon"></v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>

First when user select one item value of selected Item Group is changed to new value and when double click still item is selected and active.
Something like this:
<v-list-item-group
v-model="selectedItemGroup"
:mandatory="selectedItemGroup!=-1"
>
</v-list-item-group>
<script>
export default {
data:function(){
selectedItemGroup:-1,
}
}
</script>

Related

vuetify v-list with reactive source collapses upon adding or removing items

not sure if the reactivity part is relevant, but I use vuetify with Meteor.js and my problem is that whenever the number of items in the sub-group changes, it collapses the entire list. That is extremely annoying as the list has two levels and I need to reopen both levels to get back to the group I am editing.
I use exactly the same structure as the official sub-group example:
https://vuetifyjs.com/en/components/lists/#sub-group
Say the number of items in the Admin section in that example above changes (which means reassigning a different array to a local variable in data(){}). Then the whole list will collapse.
Is there anything I can do to keep having opened the current item?
Thanks for any tips!
I tested [https://vuetifyjs.com/en/components/lists/#sub-group][1] in Vue 2 and for me, the menu didn't close when a new item was added.
I pushed a new item into data.admin
I assigned a totally new array to data.admin
In both cases, the menu remained open.
I think the question is, are you updating a component state or props.
Because updating component props would probably cause it to rerender and therefore close the menu.
Here is the code that worked for me:
<template>
<v-app>
<v-main>
<v-card class="mx-auto" width="300">
<v-list>
<v-list-group :value="true" prepend-icon="mdi-account-circle">
<template v-slot:activator>
<v-list-item-title>Users</v-list-item-title>
</template>
<v-list-group :value="true" no-action sub-group>
<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="([title, icon], i) in admins" :key="i" link>
<v-list-item-title v-text="title"></v-list-item-title>
<v-list-item-icon>
<v-icon v-text="icon"></v-icon>
</v-list-item-icon>
</v-list-item>
</v-list-group>
<v-list-group no-action sub-group>
<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="([title, icon], i) in cruds" :key="i" link>
<v-list-item-title v-text="title"></v-list-item-title>
<v-list-item-icon>
<v-icon v-text="icon"></v-icon>
</v-list-item-icon>
</v-list-item>
</v-list-group>
</v-list-group>
</v-list>
</v-card>
<v-btn #click="addElement">Add element</v-btn>
</v-main>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
admins: [
['Management', 'mdi-account-multiple-outline'],
['Settings', 'mdi-cog-outline'],
],
cruds: [
['Create', 'mdi-plus-outline'],
['Read', 'mdi-file-outline'],
['Update', 'mdi-update'],
['Delete', 'mdi-delete'],
],
}),
methods: {
addElement() {
this.admins.push(['New', 'mdi-account-multiple-outline']);
// Completely change the menu
/* this.admins = [
['New', 'mdi-account-multiple-outline'],
['Management', 'mdi-account-multiple-outline'],
['Settings', 'mdi-cog-outline'],
]; */
},
},
};
</script>

Vuetify Autocomplete Links

I am wondering how I can attach links to items within a Vuetify autocomplete. I would like to do this so that it would act as a search bar. As of right now, I can attach links to the v-list-item but the link won't cover the entire width of the container. It appears to just form a link around the text instead of the entire item. I've tried to wrap the entire component but that doesn't seem to work either. I've also tried looking at the docs (https://vuetifyjs.com/en/components/autocompletes/) but I can't seem to find anything on making items links there either. Thanks for any help in advance.
<v-autocomplete
v-model="model"
:items="users"
:loading="isLoading"
:search-input.sync="search"
clearable
hide-details
hide-selected
item-text="username"
item-value="symbol"
placeholder="Search"
flat
solo
dense
>
<template v-slot:item="{ item }">
<v-list>
<v-list-item-group v-model="item">
<v-list-item-content>
<v-list-item link :to="'users/' + item.id">
{{item.username}}
</v-list-item>
</v-list-item-content>
</v-list-item-group>
</v-list>
</template>
</v-autocomplete>
The item slot should be <v-list-item/> only since the wrapping element of those item slots are <v-list/> already by default.
<v-autocomplete
...
>
<template v-slot:item="{ item }">
<v-list-item link :to="'users/' + item.id">{{item.username}}</v-list-item>
</template>
</v-autocomplete>
Here's a demo.

v-list in v-list not working with vuetify

I am trying to implement list in list using vuetify. But I didnt manage to make it work. Below is the code and sample data. Please help me make it work. I am using vuetify 2.3.10. If I comment out the part for the second list then the first list works
<template>
<div>
<v-toolbar id="filter">
<v-layout row wrap>
<v-flex xs12 md1>
<v-menu attach="#filter-users" offset-y>
<template v-slot:activator="{ on, attrs }">
<div class="dropdown" v-bind="attrs" v-on="on">User</div>
</template>
<v-list id="filter-users">
<v-list-item
v-for="search_user in search_users"
#click="filterUser({user: search_user})">
<v-list-item-title>{{ search_user.name }}</v-list-item-title>
</v-list-item>
<v-list v-if="search_user.sub_users.length">
<v-list-item v-for="(search_sub_users, index) in search_user.sub_users"
:key="`sub_user_${index}`"
#click="filterUsers({user: search_sub_user})">
<v-list-item-title>{{ search_sub_user.name }}</v-list-item-title>
</v-list-item>
</v-list>
</v-list>
</v-menu>
</v-flex>
</v-layout>
</v-toolbar>
</div>
</template>
search_users demo data
search_users:[{
name: 'James',
sub_users: [
{
name: 'Willy'
},
{
name: 'Jack'
},
}]
},
name: 'Rock',
sub_users: [
{
name: 'Randy'
},
{
name: 'Amy'
},
}]
],
There's a lot of things going on in your code so let me enumerate them for you:
On your second sub-list, it can't find the search_user variable since that variable is only accessible inside the <v-list-item/>, which is outside of the <v-list/>.
What you can do is to create a <template/> that will wrap both <v-list-item/> and <v-list/> then put the v-for there. Something like this:
<v-list ...>
<template v-for="(search_user, index) in search_users">
<v-list-item :key="`user_${index}`">...</v-list-item> <!-- User List -->
<v-list :key="`sub_user_${index}`">...</v-list> <!-- Sub User List -->
</template>
</v-list>
Also, don't forget the v-bind:key, or simply :key, to the v-for's child elements.
You attempt to attach the <v-menu/> to its default slot. The attach prop of <v-menu/> should be somewhere outside the <v-menu/> or inside the its activator slot. However, it should attach directly to the element in your activator slot by default so you can just omit the attach prop.
<v-menu offset-y> <!-- remove the `attach` prop -->
<template v-slot:activator="{ on, attrs }">
<div class="dropdown" v-bind="attrs" v-on="on">User</div>
</template>
<v-list>...</v-list>
</v-menu>
On your second sub-list, you mistakenly typed search_sub_user instead of search_sub_users:
v-for="(search_sub_users, index) in search_user.sub_users"` // wrong
v-for="(search_sub_user, index) in search_user.sub_users"` // right
Here is a refactored version of your code at codesandbox.

How to close v-select menu on click with prepend-items

Inside my v-select menu, I added a template with 2 v-list-items :
<v-select
:items=clients
dense
item-text="full_name"
item-value="id"
label="Search by client"
outlined
v-model="clientSearch"
>
<template v-slot:prepend-item>
<v-list-item
ripple
#click="selectNone()">
<v-list-item-content>
<v-list-item-title>None</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item
ripple
#click="selectAll">
<v-list-item-content>
<v-list-item-title>All</v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
</v-select>
Items within the v-select values react with the close-on-click property set by default, but not the the 2 others v-list-item.
How can I add the property close-on-click to the items inside the template so the v-menu closes no mater which item is selected ?
<v-select
.
.
:menu-props="{
closeOnClick: true,
closeOnContentClick: true,
}"
>
</vselect>
"closeOnContentClick: true" make the list as wish you are wish:)
So far I didn't see yet vuetify had this in their docs. What I did on it last time is to just push a new item in your current data and assigned an id just for an indicator. Maybe not the good way but will solve your problem as of now. Like this one
this.clients.push(
{id:0, full_name:'All'},
{id: -1, full_name:'None'}
)

Highlighting the child in a item list on a navigation drawer (sidebar) vue.js

there are similar questinos out there but none of them address this problem using vuetify/vue.
i have a list in my navigation drawer. it has a couple options and i when you click on an option it will change the page. i was hoping to have the option highlighted when you change the page (so you can see which page you are on).
i've tried messing with the css classes, using
.v-application a {
color: #1976d2;
}
and a few others; and while it will change the color of the tab, I want it to be transparent color until clicked upon
<v-navigation-drawer>
<v-list nav>
<v-list-item v-for="(link, i) in links" :key="i" :to="link.to">
<v-list-item-action>
<v-icon class="list">{{ link.icon }}</v-icon>
</v-list-item-action>
<v-list-item-title v-text="link.text" class="list" />
</v-list-item>
</v-list>
</v-navigation-drawer>
as you can see from this image, the active page that i am on (Dashboard) is not highlighted...