Vuetify - Don't trigger input on treeview when selection is synced - vuetify.js

On the vuetify treeview component the #input event is triggered when the selected array is initialised, I don't want this behaviour, I need the input event to be triggered only when the user manually selects/deselects an item
<v-treeview
selectable
selected-color="red"
:value="selected"
:items="items"
#input="input"
></v-treeview>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
selected: [],
items: [
{
id: 1,
name: 'Applications :',
children: [
{ id: 2, name: 'Calendar : app' },
{ id: 3, name: 'Chrome : app' },
{ id: 4, name: 'Webstorm : app' },
],
},
{
id: 5,
name: 'Documents :',
children: [
{
id: 6,
name: 'vuetify :',
children: [
{
id: 7,
name: 'src :',
children: [
{ id: 8, name: 'index : ts' },
{ id: 9, name: 'bootstrap : ts' },
],
},
],
},
{
id: 10,
name: 'material2 :',
children: [
{
id: 11,
name: 'src :',
children: [
{ id: 12, name: 'v-btn : ts' },
{ id: 13, name: 'v-card : ts' },
{ id: 14, name: 'v-window : ts' },
],
},
],
},
],
},
{
id: 15,
name: 'Downloads :',
children: [
{ id: 16, name: 'October : pdf' },
{ id: 17, name: 'November : pdf' },
{ id: 18, name: 'Tutorial : html' },
],
},
{
id: 19,
name: 'Videos :',
children: [
{
id: 20,
name: 'Tutorials :',
children: [
{ id: 21, name: 'Basic layouts : mp4' },
{ id: 22, name: 'Advanced techniques : mp4' },
{ id: 23, name: 'All about app : dir' },
],
},
{ id: 24, name: 'Intro : mov' },
{ id: 25, name: 'Conference introduction : avi' },
],
},
],
}),
mounted() {
this.selected = [1]
},
methods: {
input() {
alert("input should not be triggered")// I don't want this to be triggered unless the user explicitly selects/deselects an item
}
}
})
Here is a codepen with the problem - https://codepen.io/amaieras/pen/yLPLyvZ?editors=1011
See that the alert is shown even if I don't trigger any selection, can I avoid this from happening?

Related

Not getting products data from the Array of nested object using react.js. error- products.filter is no a function in categoryPreview component

const SHOP_DATA = [
{
title: 'Hats',
items: [
{
id: 1,
name: 'Brown Brim',
imageUrl: 'https://i.ibb.co/ZYW3VTp/brown-brim.png',
price: 25,
},
{
id: 2,
name: 'Blue Beanie',
imageUrl: 'https://i.ibb.co/ypkgK0X/blue-beanie.png',
price: 18,
},
{
id: 3,
name: 'Brown Cowboy',
imageUrl: 'https://i.ibb.co/QdJwgmp/brown-cowboy.png',
price: 35,
},
{
id: 4,
name: 'Grey Brim',
imageUrl: 'https://i.ibb.co/RjBLWxB/grey-brim.png',
price: 25,
},
{
id: 5,
name: 'Green Beanie',
imageUrl: 'https://i.ibb.co/YTjW3vF/green-beanie.png',
price: 18,
},
{
id: 6,
name: 'Palm Tree Cap',
imageUrl: 'https://i.ibb.co/rKBDvJX/palm-tree-cap.png',
price: 14,
},
{
id: 7,
name: 'Red Beanie',
imageUrl: 'https://i.ibb.co/bLB646Z/red-beanie.png',
price: 18,
},
{
id: 8,
name: 'Wolf Cap',
imageUrl: 'https://i.ibb.co/1f2nWMM/wolf-cap.png',
price: 14,
},
{
id: 9,
name: 'Blue Snapback',
imageUrl: 'https://i.ibb.co/X2VJP2W/blue-snapback.png',
price: 16,
},
],
},
{
title: 'Sneakers',
items: [
{
id: 10,
name: 'Adidas NMD',
imageUrl: 'https://i.ibb.co/0s3pdnc/adidas-nmd.png',
price: 220,
},
{
id: 11,
name: 'Adidas Yeezy',
imageUrl: 'https://i.ibb.co/dJbG1cT/yeezy.png',
price: 280,
},
{
id: 12,
name: 'Black Converse',
imageUrl: 'https://i.ibb.co/bPmVXyP/black-converse.png',
price: 110,
},
{
id: 13,
name: 'Nike White AirForce',
imageUrl: 'https://i.ibb.co/1RcFPk0/white-nike-high-tops.png',
price: 160,
},
{
id: 14,
name: 'Nike Red High Tops',
imageUrl: 'https://i.ibb.co/QcvzydB/nikes-red.png',
price: 160,
},
{
id: 15,
name: 'Nike Brown High Tops',
imageUrl: 'https://i.ibb.co/fMTV342/nike-brown.png',
price: 160,
},
{
id: 16,
name: 'Air Jordan Limited',
imageUrl: 'https://i.ibb.co/w4k6Ws9/nike-funky.png',
price: 190,
},
{
id: 17,
name: 'Timberlands',
imageUrl: 'https://i.ibb.co/Mhh6wBg/timberlands.png',
price: 200,
},
],
},
]
export default SHOP_DATA;
const UiUxCategories = () => {
return (
<div>
{
Object.keys(SHOP_DATA).map((key) => {
const products = SHOP_DATA[key];
return (
<CategoryPreview key={key} title={key} products={products} />
)
})
}
</div>
)
}
error- products.filter is no a function in categoryPreview component
const CategoryPreview = ({ title, products }) => {
return (
<div >
<h2>{title}</h2>
<div>
{products
.filter((_, idx) => idx < 4)
.map((product) => (
<ProductCard key={product.id} product={product} />
))}
</div>
</div>
);
}

Adding uuid to Vuetify datatable crud results in new items ending up with duplicate uuid

I have been using Vuetify CRUD example from https://vuetifyjs.com/en/components/data-tables/#crud-actions.
I want to add a a unique id for each record. I have taken their original code pen and copied it importing uuid library here. A sample of js is below.
https://codepen.io/joomkit/pen/MWExOGK?editors=1011
import * as uuid from "https://cdn.skypack.dev/uuid#8.3.2";
console.log(uuid.v4())
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
dialog: false,
dialogDelete: false,
headers: [
{id: 'ID', value: 'id'},
{
text: 'Dessert (100g serving)',
sortable: false,
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Actions', value: 'actions', sortable: false },
],
desserts: [],
editedIndex: -1,
editedItem: {
id: uuid.v4(),
name: '',
calories: 0,
fat: 0,
carbs: 0,
protein: 0,
},
defaultItem: {
id: uuid.v4(),
name: '',
calories: 0,
fat: 0,
carbs: 0,
protein: 0,
},
}),
computed: {
formTitle () {
return this.editedIndex === -1 ? 'New Item' : 'Edit Item'
},
},
watch: {
dialog (val) {
val || this.close()
},
dialogDelete (val) {
val || this.closeDelete()
},
},
created () {
this.initialize()
},
methods: {
initialize () {
this.desserts = [
{
id: '1',
name: 'SFrozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
},
{
id: '2',
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
},
{
id: '3',
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
},
]
},
editItem (item) {
this.editedIndex = this.desserts.indexOf(item)
this.editedItem = Object.assign({}, item)
this.dialog = true
},
deleteItem (item) {
this.editedIndex = this.desserts.indexOf(item)
this.editedItem = Object.assign({}, item)
this.dialogDelete = true
},
deleteItemConfirm () {
this.desserts.splice(this.editedIndex, 1)
this.closeDelete()
},
close () {
this.dialog = false
this.$nextTick(() => {
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
})
},
closeDelete () {
this.dialogDelete = false
this.$nextTick(() => {
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
})
},
save () {
if (this.editedIndex > -1) {
Object.assign(this.desserts[this.editedIndex], this.editedItem)
} else {
this.desserts.push(this.editedItem)
}
this.close()
},
},
})
When i add new item in the modal dialog a new uuid is created for the added row.
However if you add more than 2 new items then the uuid is duplicated.
Is there something wrong with the inbuilt data table index here?
When start the page, uuid is assigned to "editedItem" and "defaultItem" and is not calling again.
save () {
if (this.editedIndex > -1) {
Object.assign(this.desserts[this.editedIndex], this.editedItem)
} else {
this.desserts.push(this.editedItem)
this.defaultItem.id = uuid.v4();
}
this.close()
},
If modified as above, the uuid of the next item will be newly set when the new item is saved.
And there is one other problem with the code.
When a pop-up is closed without saving by calling "NEW ITEM" for the first time, the uuid of "editedItem" in the close() function is overwritten as uuid of "defaultItem".
Set the uuid of "defaultItem" and "editedItem" to the same value.

Vuetify tree data-table

how can I embed a v-tree-view component in v-data-table ?
I have tried so many times but without any result .
with no vuetify v-tree-table forexample , here comes the question , how to integrate the v-tree-view with v-data-table ?
You can define a slot to customize any column. So there you can insert your treeview. An example:
<template>
<v-data-table
:headers="headers"
:items="cosas"
>
<template v-slot:[`item.description`]>
<td>
<template>
<v-treeview :items="treeItems"></v-treeview>
</template>
</td>
</template>
</v-data-table>
</template>
<script>
export default {
name: 'MyComponent',
data () {
return {
headers:[
{ text: 'Name', value: 'name'},
{ text: 'Description', value: 'description'},
],
cosas:[
{ name: 'Item1', description: 'description1'},
{ name: 'Item2', description: 'description2'},
],
treeItems: [
{
id: 1,
name: 'Applications :',
children: [
{ id: 2, name: 'Calendar : app' },
{ id: 3, name: 'Chrome : app' },
{ id: 4, name: 'Webstorm : app' },
],
},
{
id: 5,
name: 'Documents :',
children: [
{
id: 6,
name: 'vuetify :',
children: [
{
id: 7,
name: 'src :',
children: [
{ id: 8, name: 'index : ts' },
{ id: 9, name: 'bootstrap : ts' },
],
},
],
},
{
id: 10,
name: 'material2 :',
children: [
{
id: 11,
name: 'src :',
children: [
{ id: 12, name: 'v-btn : ts' },
{ id: 13, name: 'v-card : ts' },
{ id: 14, name: 'v-window : ts' },
],
},
],
},
],
},
{
id: 15,
name: 'Downloads :',
children: [
{ id: 16, name: 'October : pdf' },
{ id: 17, name: 'November : pdf' },
{ id: 18, name: 'Tutorial : html' },
],
},
{
id: 19,
name: 'Videos :',
children: [
{
id: 20,
name: 'Tutorials :',
children: [
{ id: 21, name: 'Basic layouts : mp4' },
{ id: 22, name: 'Advanced techniques : mp4' },
{ id: 23, name: 'All about app : dir' },
],
},
{ id: 24, name: 'Intro : mov' },
{ id: 25, name: 'Conference introduction : avi' },
],
},
],
}
}
}
</script>
Set your filters in the template to insert it only in those cells that you need it.
i try with many libraries but i feel very hard dificult, because i want to use crud in nodes child, i created solucion: i used a table of type expanded and this expended area insert other table for child. you can read in official page about expand table:
https://vuetifyjs.com/en/components/data-tables/#expandable-rows
my code:
<v-data-table
item-key="_id"
:headers="headers"
:items="items"
:single-expand="singleExpand"
:expanded.sync="expanded"
show-expand
height="670"
fixed-header
sort-by="_id"
class="elevation-1 mt-sm-5 mt-md-5 mt-lg-5 mt-xl-5"
>
<template v-slot:expanded-item="{ headers, item }">
<td :colspan="headers.length" style="background-color:#C0D0D0">
<v-card class="mx-auto my-1" max-width="900" outlined>
<v-card-text>
<div>
<span><strong> Delivery {{item.name_driver}}</strong></span>
</div>
<v-divider></v-divider>
<div>
<v-data-table
:headers="headersChild"
:items="item.children"
:items-per-page="5"
class="elevation-1"
>
</v-data-table>
</div>
</v-card-text>
</v-card>
</td>
</template>
</v-data-table>

ReferenceField and ReferenceInput

(Sorry for my English. It will be great if you correct my mistakes).
I have a list of products and create product / edit product pages.
Each product has a set of attributes.
Each set of attributes has attributes.
How to do next:
When i choose a set of attributes for product at creating or at editing, in the form (create product / edit product) will be added new TextInputs with labels of attributes.
Here is my products:
products: [
{
id: 1,
title: 'title1',
description: 'description1',
shortDescription: 'shortDescription1',
seo: {
title: 'seotitle1',
description: 'description1',
keywords: ['keywords1'],
},
price: 428,
parentCategories: [1],
images: [
{
id: 123,
url: 'urlImage1',
title: 'urlTitle1',
},
],
isItActive: true,
creationDate: '2008-04-01T14:57:42.105Z',
modificationDate: '2009-04-01T14:57:42.105Z',
setOfAttributes: 1,
}, {
id: 2,
title: 'title2',
description: 'description2',
shortDescription: 'shortDescription2',
seo: {
title: 'seotitle2',
description: 'description2',
keywords: ['keywords2'],
},
price: 418,
parentCategories: [2],
images: [
{
id: 122,
url: 'urlImage2',
title: 'urlTitle2',
},
],
isItActive: false,
creationDate: '2010-04-01T14:57:42.105Z',
modificationDate: '2011-04-01T14:57:42.105Z',
setOfAttributes: 3,
}, {
id: 3,
title: 'title3',
description: 'description3',
shortDescription: 'shortDescription3',
seo: {
title: 'seotitle3',
description: 'description3',
keywords: ['keywords3'],
},
price: 423,
parentCategories: [3],
images: [
{
id: 323,
url: 'urlImage3',
title: 'urlTitle3',
},
],
isItActive: true,
creationDate: '2012-04-01T14:57:42.105Z',
modificationDate: '2013-04-01T14:57:42.105Z',
setOfAttributes: 2,
},
],
Here is my attrubutes:
attributes: [
{
id: 1,
name: 'asdgsd',
title: 'qwed',
type: 'список',
showInFilter: null,
},
{
id: 2,
name: 'zxcv',
title: 'fkf',
type: 'текстовое поле',
showInFilter: null,
},
{
id: 3,
name: 'asdkd',
title: 'rczh',
type: null,
showInFilter: null,
},
],
Here is a set of attributes:
setOfAttributes: [
{
id: 1,
title: 'Набор 1',
attributes: [1, 3],
},
{
id: 2,
title: 'Набор 2',
attributes: [3, 1, 2],
},
{
id: 3,
title: 'Набор 3',
attributes: [2, 3],
},
],
I was able to do just that(productsEdit.jsx):
<ReferenceField source="setOfAttributes" reference="setOfAttributes" linkType={false}>
<ReferenceArrayField source="attributes" reference="attributes">
<SingleFieldList>
<ChipField source="title" />
</SingleFieldList>
</ReferenceArrayField>
</ReferenceField>

Normalizing a nested entity that shares the current schema

My goal is to normalize this object:
{
talks: [
{
id: 1755,
speakers: [
{
id: 1487,
name: 'John Doe',
},
],
related_talks: [{
id: 14,
speakers: [{
id: 125,
name: 'Jane Doe',
}],
event: {
id: 181,
name: 'First Annual',
},
}],
event: {
id: 180,
name: 'July Party',
},
},
],
};
into this result:
{
entities: {
events: {
181: {
id: 181,
name: 'First Annual'
},
180: {
id: 180,
name: 'July Party'
}
},
speakers: {
125: {
id: 125,
name: 'Jane Doe'
},
1487: {
id: 1487,
name: 'John Doe'
}
},
talks: {
1755: {
id: 1755,
event: 181,
speakers: [ 1487 ],
related_talks: [ 14 ],
},
14: {
id: 14,
speakers: [ 125 ],
event: 180,
}
},
},
result: {
talks: [ 1755, 14 ],
},
}
If you'll notice, the items in related_talks are treated the same as a talk.
My schemas follow the examples and are set up like this:
const speaker = new schema.Entity('speakers');
const event = new schema.Entity('events');
export const talk = new schema.Entity('talks', {
speakers: [speaker],
event,
});
talk.define({ related_talks: [talk] });
No matter what I try, I can't get the items in related_talks to be added to the result.talks array. It is, however, in the entities object.
What is my schema configuration missing in order to accommodate this?
Unfortunately, if this is your requirement, Normalizr is not for you. Alternatively, if you're looking for a list of "talks" by ID, you can use Object.keys(data.entities.talks)

Resources