I am trying to preselect item from vuetify item-group. It works for string but not for objects. In the vuetify document, they have used string array as the item list for the item-group. It works fine.
If I try to use an object array as the item list it doesn't work
<div id="app">
<v-app id="inspire">
<v-card class="mx-auto" max-width="500">
<v-list shaped>
<v-list-item-group v-model="model" multiple>
<template v-for="(item, i) in items">
<v-divider
v-if="!item"
:key="`divider-${i}`"
></v-divider>
<v-list-item
v-else
:key="`item-${i}`"
:value="item"
active-class="deep-purple--text text--accent-4"
>
<template v-slot:default="{ active, toggle }">
<v-list-item-content>
<v-list-item-title v-text="item.name"></v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-checkbox
:input-value="active"
:true-value="item"
color="deep-purple accent-4"
#click="toggle"
></v-checkbox>
</v-list-item-action>
</template>
</v-list-item>
</template>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [
{ name: "Connect"}
],
model: [{name: "Connect"}]
}),
})
You can implement using unique value from your data, it can be a id or something else. You need to pass you unique value inside of your model in form of Array and then the same unique value should be configure with your <v-list-item>.
Please check code snippet and working Codepen demo.
Code snippet:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [],
model: [1, 3, 6]
}),
methods: {
getValue(item) {
return `${item.id}. - ${item.title.toLocaleUpperCase()}`;
}
},
created: function() {
let self = this;
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json())
.then(json => self.$data.items = json)
}
});
<div id="app">
<v-app id="inspire">
<v-card class="mx-auto" max-width="100%">
<v-list shaped>
<v-toolbar color="indigo" dark>
<v-toolbar-title>List posts :- jsonplaceholder</v-toolbar-title>
</v-toolbar> <br/>
<v-list-item-group v-model="model" multiple>
<template v-for="(item, i) in items">
<v-divider
v-if="!item"
:key="`divider-${i}`"
></v-divider>
<v-list-item
v-else
:key="`item-${i}`"
:value="item.id"
active-class="deep-purple--text text--accent-4"
>
<template v-slot:default="{ active, toggle }" >
<v-list-item-content>
<v-list-item-title v-text="getValue(item)"></v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-checkbox
:input-value="active"
:true-value="item.id"
color="deep-purple accent-4"
#click="toggle"
></v-checkbox>
</v-list-item-action>
</template>
</v-list-item>
</template>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
Related
I start coding in vuetify and want to make Edit button who get the data of selected id, response selected post from axios and transfer it to another components.
I trying props but its not working here, or i do something wronk with it.
There is my List and Edit components:
<template>
<v-container>
<v-row>
<v-col cols="12">
<v-list shaped>
<v-list-item-group color="deep-purple" v-model="selected" multiple>
<v-list-item v-for="item in todoList" :key="item.id">
<v-list-item-icon>
{{ item.id }}
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>
<strong>{{ item.title }}</strong>
</v-list-item-title>
</v-list-item-content>
<v-btn fab dark small color="purple">
<v-icon dark #click="Edit()"> mdi-pencil </v-icon>
</v-btn>
</v-list-item>
</v-list-item-group>
</v-list>
</v-col>
</v-row>
</v-container>
</template>
<script>
import axios from "axios";
export default {
name: "BookList",
data: () => ({
selected: [],
todoList: [],
}),
mounted() {
this.getTodos();
},
methods: {
getTodos() {
axios.get("http://127.0.0.1:8000/api/todo/").then((response) => {
this.todoList = response.data;
});
},
Edit() {
this.$emit("title", this.item.title);
},
},
};
</script>
<template>
<v-container>
<v-row>
<v-col cols="12">
<v-form>
<v-text-field
v-model="this.title"
:counter="64"
label="title"
required
></v-text-field>
</v-form>
</v-col>
<v-btn #click="edit" color="success" class="mr-4"> Edit </v-btn>
</v-row>
</v-container>
</template>
<script>
export default {
data: () => {
return {
title: this.title,
};
},
components: {},
mounted() {},
methods: {},
};
</script>
but i stuck. I think i do somethink wrong with Emit medo but dont know what. Can u give some hint what to do?
I am trying to hide an admin menu using v-show. In the code below the isAdmin value is false, yet the menu still shows. I have also tried v-if but that doesn't work either.
<v-list v-show="isAdmin">
<v-list-item v-for="item in adminItems" :key="item.title" #click="handleNavigtion(item)" router>
<v-list-item-action class="pr-1 pl-2 mr-1">
<v-icon :class="activeMenuItem.includes(item.title) ? 'blue--text' : ''" :title="item.title">
{{ item.icon }}
</v-icon>
</v-list-item-action>
<v-list-item-content :class="activeMenuItem.includes(item.title) ? 'blue--text' : ''">
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
I also tried with the v-show/if inside the v-list-item element.
<v-list-item v-if="isAdmin" v-for="item in adminItems">...</v-list-item>
Additionally, the component uses Typescript's get for making isAdmin a computed property. When I try to access this in the template using
{{ isAdmin }} the value displays either true or false correctly.
get isAdmin() {
return sessionStorage.getItem('isAdmin')
}
Can anyone tell me what I am missing?
Thanks for any help!
You can't really use v-if and v-for on the same element. Best to put the v-if or v-show on a parent element.
Working Demo :
Vue.use(Vuetify);
var vm = new Vue({
el: "#app",
data: {
adminItems: [{
title: 'abc',
icon: 'Icon 1'
}, {
title: 'def',
icon: 'Icon 2'
}],
activeMenuItem: ['abc', 'def']
},
computed: {
isAdmin() {
return true; // Replace `true` with `false` to see the changes.
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<script src="https://unpkg.com/vuetify#0.14.8/dist/vuetify.min.js"></script>
<div id="app">
<v-list v-show="isAdmin">
<v-list-item v-for="item in adminItems" :key="item.title" #click="handleNavigtion(item)" router>
<v-list-item-title v-text="item.title"></v-list-item-title><br>
</v-list-item>
</v-list>
</div>
Yes, it is not possible to use v-for together with v-if or v-show.
But I tried something and it worked.
<v-list dense nav v-for="(item, i) in items" :key="i">
<v-list-item
dense
:to="item.url"
:exact="true"
v-if="mixPermissao($options.name, item.name)"
>
<v-list-item-icon>
<v-icon :color="item.color">{{ 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>
I put the v-for in the v-list and the v-if in the v-list-item and it worked.
When using Vuetify v-autocomplete component and using the prop multiple we can multi select values.
How can I remove other values based on the value I selected?
For example:
When I select the main value, the others will be selected removed.Then, when I select the first value, the main value and other values will be deselected. Then when I select the third and others (the third and below are in the same group) the selected main and first value will be selected removed.
<div id="app">
<v-app>
<v-main>
<v-container>
<template>
<v-card color="blue-grey darken-1" dark>
<v-form>
<v-container>
<v-row>
<v-col cols="5">
<v-autocomplete
v-model="parametres"
:items="people"
filled
chips
color="blue-grey lighten-2"
label="Liste"
item-text="name"
item-value="name"
multiple
>
<template v-slot:selection="data">
<v-chip
v-bind="data.attrs"
:input-value="data.selected"
close
#click="data.select"
#click:close="remove(data.item)"
>
{{ data.item.name }}
</v-chip>
</template>
<template v-slot:item="data">
<template v-if="typeof data.item !== 'object'">
<v-list-group>
<v-list-item-content
v-text="data.item"
></v-list-item-content>
</template>
<template v-else>
<v-list-item-content>
<v-list-item-title
v-html="data.item.name"
></v-list-item-title>
</v-list-item-content>
</v-list-group>
</template>
</template>
</v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-form>
<v-divider></v-divider>
</v-card>
</template>
</v-container>
</v-main>
</v-app>
</div>
<script>
new Vue({
el: "#app",
vuetify: new Vuetify(),
data() {
return {
selected: ["name"],
autoUpdate: true,
parametres: ["Main Select"],
people: [
{ name: "Main Select"},
{ name: "First Select"},
{ name: "Second Select"},
{ name: "Third Select."},
{ name: "Fourth Select."},
{ name: "Fifth Select."},
],
model: 1,
};
},
methods: {
remove(item) {
const index = this.parametreler.indexOf(item.name);/*Chip Remove */
if (index >= 0) this.parametreler.splice(index, 1); /*Chip Remove */
},
},
});
</script>
Hi #sercan you can use the #change events and call method on this event and write your logic within that method.
<div id="app">
<v-app>
<v-main>
<v-container>
<template>
<v-card color="blue-grey darken-1" dark>
<v-form>
<v-container>
<v-row>
<v-col cols="5">
<v-autocomplete v-model="parametres" :items="people" filled chips color="blue-grey lighten-2" label="Liste" item-text="name" item-value="name" multiple :key="index">
<template v-slot:selection="data">
<v-chip v-bind="data.attrs" :input-value="data.selected" close #click="data.select" #click:close="remove(data.item)">
{{ data.item.name }}
</v-chip>
</template>
<template v-slot:item="data">
<template v-if="typeof data.item !== 'object'">
<v-list-group>
<v-list-item-content v-text="data.item">
<span>{{typeof data.item !== 'object'}}</span>
</v-list-item-content>
</template>
<template v-else>
<v-list-item-content #click="updateSelection(data.item.name)">
<v-list-item-title v-html="data.item.name"></v-list-item-title>
</v-list-item-content>
</v-list-group>
</template>
</template>
</v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-form>
<v-divider></v-divider>
</v-card>
</template>
</v-container>
</v-main>
new Vue({
el: "#app",
vuetify: new Vuetify(),
data() {
return {
selected: ["name"],
autoUpdate: true,
parametres: ["Main Select"],
people: [
{ name: "Main Select" },
{ name: "First Select" },
{ name: "Second Select" },
{ name: "Third Select." },
{ name: "Fourth Select." },
{ name: "Fifth Select." }
],
model: 1,
index: 0
};
},
methods: {
updateSelection(name) {
let toRemove = ["Main Select","First Select"];
let temp = event;
console.log(name);
switch (name) {
case "Main Select":
this.parametres = ["Main Select"];
this.index++;
break;
case "First Select":
this.parametres = ["First Select"]
this.index++;
break;
default:
this.parametres = this.parametres.filter( ( el ) => !toRemove.includes( el ) );
}
},
remove(item) {
const index = this.parametreler.indexOf(item.name); /*Chip Remove */
if (index >= 0) this.parametreler.splice(index, 1); /*Chip Remove */
}
}
});
Using Vue and Vuetify Data Tables I built a table in which each row presents an item of an array of objects.
Each row had a button which triggered a dialog which presented a form in which you could edit each row's data.
Here's the problem with instructions: https://codepen.io/gkatsanos-the-bold/pen/VwZzKeq
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: () => ({
gateways: [],
dialog: false,
form: {
title: ""
}
}),
mounted() {
this.getGateways().then(data => {
this.gateways = data;
});
},
methods: {
async getGateways() {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts"
);
const data = response.json();
return data;
},
openDialog(item) {
setTimeout(() => {
this.dialog = true;
this.form.title = this.item.title
});
}
}
});
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-content>
<v-container>
<v-data-table :items="gateways">
<template #item="{ item }">
<tr>
<td>{{ item.id }}</td>
<td>{{ item.title }}</td>
<td>
<v-menu>
<template #activator="{ on }">
<v-btn small class="meter-point-options-menu action-column-item" v-on="on">
open menu
</v-btn>
</template>
<v-list>
<v-list-item>
<v-btn color="red lighten-2" dark #click="openDialog()">
Click Me
</v-btn>
<v-dialog v-model="dialog" width="500">
<v-card>
<v-card-title>
ID: {{ item.id }}
</v-card-title>
<v-card-title>
TEXT: {{ item.title }}
</v-card-title>
<v-card-text>
<br> Issues:
<ol>
<li>Every time you close and open a Dialog / Popup, all of the previous ones open together because they're still in the DOM.</li>
<li>Notice that after navigating the pages, some of the ID and texts shown in the modal dialogs are different from the item opened!</li>
<v-form ref=form>
</v-form>
</v-card-text>
<v-card-actions>
<div class="flex-grow-1"></div>
<v-btn color="primary" text #click="dialog = false">
close this
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-list-item>
</v-list>
</v-menu>
</td>
</tr>
</template>
</v-data-table>
</v-container>
</v-content>
</v-app>
</div>
As you see opening one dialog opens all the previous ones.
How should I tackle the issue of controlling the visibility of the v-dialogs in a unique fashion? I am thinking of moving them outside of the loop and having only one v-dialog and not one for every row of the table.
I created a simple Contact list with an input to add the contact items but after I add a few items it's not resizing.
I used this as an example and there is resizing but not in my code:
https://v2.vuejs.org/v2/guide/list.html
Could anyone help me with that?
Here is the Codepen:
https://codepen.io/fabiozanchi/pen/qoBpgd
Vue.component('contact-item', {
template: '\
<v-list-tile-title>\
<button #click="$emit(\'remove\')"><v-icon class="remove-email-icon" color="red">remove_circle</v-icon></button>\{{ title }}\
</v-list-tile-title>\
',
props: ['title']
})
new Vue({
el: '#contact-list',
data: {
newContact: '',
contacts: [],
nextContactId: 1
},
methods: {
addNewContact: function() {
this.contacts.push({
id: this.nextContactId++,
title: this.newContact
})
this.newContact = ''
}
}
})
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons" />
<link rel="stylesheet" type="text/css" href="https://unpkg.com/vuetify#1.0.5/dist/vuetify.min.css" />
<script src="https://unpkg.com/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#1.0.5/dist/vuetify.min.js"></script>
<div id="contact-list">
<v-app>
<v-layout row>
<v-flex xs12 sm6 offset-sm3>
<v-card>
<v-toolbar color="blue" dark>
<v-toolbar-title class="text-xs-center">Contacts</v-toolbar-title>
</v-toolbar>
<v-container>
<v-text-field v-model="newContact" #keyup.enter="addNewContact" placeholder="Add new email contact email"></v-text-field>
</v-container>
<v-divider></v-divider>
<v-list class="resize-list">
<v-list-tile>
<v-list-tile-content>
<v-list-tile-title is="contact-item" v-for="(contact, index) in contacts" :key="contact.id" :title="contact.title" #remove="contacts.splice(index, 1)">
</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-card>
</v-flex>
</v-layout>
</v-app>
</div>
Thank you!
Use v-for on v-list-tile component (see vuetify examples).
<v-list-tile
v-for="(contact, index) in contacts"
:key="contact.id"
>
That will produce multiple lis that you want from your examples (currently you only have one li element in list because of v-for on title, so that's why it's not working properly)