i am trying to implement vue draggable and it almost seems to work except for when i try to implement it on a button. It gives me an error message whenever i try to move the button.
Here is an example : https://codepen.io/anon/pen/xoQRMV?editors=1111
<div id="app">
<v-app id="inspire">
<v-container>
<v-layout justify-center>
<v-flex>
<draggable v-model="myArray" :options="options" handle=".handle">
<div v-for="element in myArray" :key="element.id" class="title
mb-3">{{element.name}}
<v-icon color="red" class="handle mt-0">drag_handle</v-icon>
</div>
<v-btn class="ml-0">Button</v-btn>
<v-icon color="red" class="handle">drag_handle</v-icon>
</draggable>
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
new Vue({
el: '#app',
data() {
return {
myArray: [
{name: 'Text1!!!!', id: 0},
{name: 'Text2!!!!', id: 1},
],
options: {
handle: '.handle'
}
}
}
})
Any help is appreciated.
It would have to work from a single array I think, e.g.
https://codepen.io/anon/pen/agQVvm?editors=1111
<div id="app">
<v-app id="inspire">
<v-container>
<v-layout justify-center>
<v-flex>
<draggable :list="combinedArray" :options="options" handle=".handle">
<div v-for="element in combinedArray" :key="element.id" class="title mb-3">
<div v-if="element.type !== 'button'" class="title mb-3">
{{ element.name }}
<v-icon color="red" class="handle mt-0">drag_handle</v-icon>
</div>
<div v-else>
<v-btn>{{ element.name }}</v-btn>
<v-icon color="red" class="handle mt-0">drag_handle</v-icon>
</div>
</div>
</draggable>
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
new Vue({
el: '#app',
created () {
this.combinedArray = [...this.myArray, ...this.buttonsArray]
},
data () {
return {
myArray: [
{ name: 'Text1!!!!', id: 0 },
{ name: 'Text2!!!!', id: 1 }
],
buttonsArray: [
{ name: 'Button1', id: 2, type: 'button' },
{ name: 'Button2', id: 3, type: 'button' }
],
combinedArray: [],
options: {
handle: '.handle'
}
}
}
})
I was able to implement the drag on buttons by creating their own array:-
<draggable class="list-group" :list="buttonArray" :options="options"
handle=".handle" group="drags">
<div v-for="item in buttonArray" :key="item.id">
<v-btn class="ml-0">{{item.name}}</v-btn>
<v-icon color="red" class="handle">drag_handle</v-icon>
</div>
</draggable>
buttonArray: [
{name: 'Button1', id: 2},
{name:'Button2', id:3}
],
The updated pen:- https://codepen.io/anon/pen/xoQRMV?editors=1111
However it creates an issue where i am not able to replace the text with the button. :(
Related
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 */
}
}
});
So I am trying to check the checkbox Icon to something more custom, perhaps a different icon, however, I tried a couple different things like pseudo elements with no success. right now what this does is loops through data and displays the name and when checked highlights it based on the css class. What I am trying to do is when check change the checkbox icon.
css
.unchecked{
color: gray;
}
.checked{
background-color: #ffff00;
}
Vuejs Component.
Vue.component('check-list', {
template: `
<v-container>
<v-row >
<v-col >
<v-checkbox
v-for="item in values"
:key="item.id"
:value="item.id"
v-model="selected"
>
<template v-slot:label>
<div :class="selected.includes(item.id) ? 'checked' : 'unchecked'">
{{item.name}}
</div>
</template>
</v-checkbox>
</v-col>
</v-row>
<pre>{{selected}}</pre>
</v-container>
`,
data: function () {
return {
selected: [],
values: [
{id:'1',name:'Name 1'},
{id:'2', name:'Name 2'},
{id:'3', name:'Name 3'},
],
ex4: ['red']
}
},
methods: {
},
})
new Vue({
el: '#components-demo',
vuetify: new Vuetify({
icons: {
iconfont: 'md',
},
}),
data: () => ({
}),
})
#chewie, it is possible to change the checkbox icon in Vuetify, There is a specia prop to handle this
:on-icon="'icon-name'"
:off-icon="'icon-name'"
Please find the full code below
<div id="app">
<v-app id="inspire">
<v-container
class="px-0"
fluid
>
<v-row >
<v-col >
<v-checkbox
:on-icon="'mdi-heart'"
:off-icon="'mdi-home'"
v-for="item in values"
:key="item.id"
:value="item.id"
v-model="selected"
>
<template v-slot:label>
<div :class="selected.includes(item.id) ? 'checked' : 'unchecked'">
{{item.name}}
</div>
</template>
</v-checkbox>
</v-col>
</v-row>
<pre>{{selected}}</pre>
</v-container>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
selected: [],
values: [
{id:'1',name:'Name 1'},
{id:'2', name:'Name 2'},
{id:'3', name:'Name 3'},
],
ex4: ['red']
}
},
})
Please find the working codepen here:
https://codepen.io/chansv/pen/QWdEPvB?editors=1010
I made a component that allows me to add a point for each user only once after button click. I would like to additionally enable the undo of an added point (decreasing the value by 1). When I add a point, I want the button to turn red and change the text to "Delete point".
This should be similar to marking the answers as helpful the stackoverflow (but without a negative point).
I used v-if="user.title !== 'Jason Oner'" to disable adding points for this user.
I have no idea how to solve this problem in this case.
Demo code
HTML:
<div id="app">
<v-app id="inspire">
<v-card
class="mx-auto"
max-width="900"
>
<v-list>
<v-list-item
v-for="user in users"
:key="user.title"
>
<v-list-item-avatar>
<v-img
:alt="`${user.title} avatar`"
:src="user.avatar"
></v-img>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title v-text="user.title"></v-list-item-title>
<div class="points" v-text="user.points"></div>
</v-list-item-content>
<v-list-item-icon>
<v-btn
v-if="user.title !== 'Jason Oner'"
color="primary"
#click.once="user.points++"
>
<v-icon left>
mdi-plus
</v-icon>
Add point
</v-btn>
</v-list-item-icon>
</v-list-item>
</v-list>
</v-card>
</v-app>
</div>
JS:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
users: [
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',
title: 'Jason Oner',
points: 5,
},
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',
title: 'Mike Carlson',
points: 10,
},
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',
title: 'Cindy Baker',
points: 15,
},
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',
title: 'Ali Connors',
points: 20,
},
],
}),
})
Please see if this helps
Codepen Demo
HTML:
<div id="app">
<v-app id="inspire">
<v-card class="mx-auto" max-width="900">
<v-list>
<v-list-item v-for="(user,index) in users" :key="user.title">
<v-list-item-avatar>
<v-img :alt="`${user.title} avatar`" :src="user.avatar"></v-img>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title v-text="user.title"></v-list-item-title>
<div class="points" v-text="user.points"></div>
</v-list-item-content>
<v-list-item-icon>
<div v-if="user.add">
<v-btn v-if="user.title !== 'Jason Oner'" color="primary" #click="aab(index)">
<v-icon left> mdi-plus </v-icon> Add point
</v-btn>
</div>
<div v-else>
<v-btn v-if="user.title !== 'Jason Oner'" color="error" #click="aab(index)">
<v-icon left> mdi-plus </v-icon> Del point
</v-btn>
</div>
</v-list-item-icon>
</v-list-item>
</v-list>
</v-card>
</v-app>
</div>
JS:
new Vue({
el: '#app',
vuetify: new Vuetify(),
methods:{
aab(ii)
{ let uu=this.users[ii];
if(uu.add) { uu.points++;uu.add=false;uu.sub=true }
else{ uu.points--; uu.add=true;uu.sub=false}
}
},
data: () => ({
users: [
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',
title: 'Jason Oner',
points: 5,add:true,sub:false,
},
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',
title: 'Mike Carlson',
points: 10,add:true,sub:false,
},
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',
title: 'Cindy Baker',
points: 15,add:true,sub:false,
},
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',
title: 'Ali Connors',
points: 20,add:true,sub:false,
},
],
}),
})
You would have to store somewhere who the current user (you) have upvoted. Normally this is would be in your case on a user object in the users array. eg
{
avatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',
title: 'Ali Connors',
points: 20,
// alternatives:
haveIGivenPoint: false,
usersGivenPoints: [1, 5, 2] // Represents user ids that has given points
points: [1, 5, 2] // Instead of points above as a number, you could count users ids who has given points
// etc... It's up to you how to save this state
},
When you have chosen a way to store what you have voted for, you need to use this info on the button:
<v-list-item-icon>
<v-btn
v-if="!user.haveIGivenPoint"
color="primary"
#click.once="user.points++"
>
<v-icon left>
mdi-plus
</v-icon>
Add point
</v-btn>
<v-btn
v-else
color="red"
#click.once="user.points--"
>
<v-icon left>
mdi-minus
</v-icon>
Undo point
</v-btn>
</v-list-item-icon>
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>
Hi everyone I'm playing around with Vue JS but for some how I cannot get what I expected. Below are my code.
Template
<div id="app">
<v-app id="inspire">
<div class="text-xs-center" v-for="x in count" :key="x">
<v-menu offset-y>
<v-btn
slot="activator"
color="primary"
dark
>
{{name}}
</v-btn>
<v-list>
<v-list-tile
v-for="(item, index) in items"
:key="index"
#click="test(item.title)"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</v-app>
</div>
Vue
new Vue({
el: '#app',
data: () => ({
name: 'default',
items: [
{ title: 'Click Me 1' },
{ title: 'Click Me 2' },
{ title: 'Click Me 3' },
{ title: 'Click Me 2' }
],
count: 10
}),
methods: {
test(title) {
this.name = title
}
}
})
What I want is that when I change a specific button text the other buttons should not be affected. But it seems my code is doing the opposite. What am I missing here? Any help, explanation would be much appreciated. Thanks
new Vue({
el: '#app',
data: () => ({
name: 'default',
items: [
{ title: 'Click Me 1' },
{ title: 'Click Me 2' },
{ title: 'Click Me 3' },
{ title: 'Click Me 2' }
],
count: 10
}),
methods: {
test(title) {
this.name = title
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.3/dist/vuetify.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.3/dist/vuetify.min.css">
<div id="app">
<v-app id="inspire">
<div class="text-xs-center" v-for="x in count" :key="x">
<v-menu offset-y>
<v-btn
slot="activator"
color="primary"
dark
>
{{name}}
</v-btn>
<v-list>
<v-list-tile
v-for="(item, index) in items"
:key="index"
#click="test(item.title)"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</v-app>
</div>
You are iterating over a normal number, in your example 10, so you are just showing 10 times the same variable name.
If you now change that variable name to something, it will change in all the buttons accordingly.
You need some way to save the different names, e.g. an array of objects like your items with all the titles.
I took your code and changed it a bit. Instead of iterating over a fixed count, I created an array of names and iterate over that array. When you click one of the buttons and change the text, instead of just changing the universal name attribute - you change the name at the position in the array.
new Vue({
el: '#app',
data: () => ({
names: [
{name: 'default 1'}, {name: 'default 2'}, {name: 'default 3'}, {name: 'default 4'}],
items: [
{ title: 'Click Me 1' },
{ title: 'Click Me 2' },
{ title: 'Click Me 3' },
{ title: 'Click Me 4' }
],
}),
methods: {
test(title, index) {
this.names[index].name = title
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.3/vuetify.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.3/vuetify.css.map">
<div id="app">
<v-app id="inspire">
<div class="text-xs-center" v-for="(x, index) in names" :key="'name' + index">
<v-menu offset-y>
<v-btn
slot="activator"
color="primary"
dark
>
{{x.name}}
</v-btn>
<v-list>
<v-list-tile
v-for="(item, i) in items"
:key="'item' + i"
#click="test(item.title, index)"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</v-app>
</div>