I am working with vue.js with vuetify framework, i am trying to show/hide column. How can i do that with vue. In Vuetify documentation , there is only expand/collapse for row like this
enter image description here
export default {
data: () => ({
singleExpand: false,
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
sodium: 87,
calcium: '14%',
iron: '1%',
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
sodium: 129,
calcium: '8%',
iron: '1%',
},
],
}),
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<v-container fluid>
<v-switch v-model="singleExpand"
label="Expand Single Item"></v-switch>
<v-data-iterator :items="desserts"
item-key="name"
:items-per-page="4"
:single-expand="singleExpand"
hide-default-footer>
<template v-slot:default="{ items, isExpanded, expand }">
<v-row>
<v-col v-for="item in items"
:key="item.name"
cols="12"
sm="6"
md="4"
lg="3">
<v-card>
<v-card-title>
<h4>{{ item.name }}</h4>
</v-card-title>
<v-switch :input-value="isExpanded(item)"
:label="isExpanded(item) ? 'Expanded' : 'Closed'"
class="pl-4 mt-0"
#change="(v) => expand(item, v)"></v-switch>
<v-divider></v-divider>
<v-list v-if="isExpanded(item)"
dense>
<v-list-item>
<v-list-item-content>Calories:</v-list-item-content>
<v-list-item-content class="align-end">
{{ item.calories }}
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-content>Fat:</v-list-item-content>
<v-list-item-content class="align-end">
{{ item.fat }}
</v-list-item-content>
</v-list-item>
</v-list>
</v-card>
</v-col>
</v-row>
</template>
</v-data-iterator>
</v-container>
</template>
I want to make a dynamic column that can expand/collapse. here is what i expected to do. i really dont know how to make it, can i make it with vuetify or have to do with vue native.
enter image description here
Related
I am creating a simple table with vuetify and it turns out that when adding the v-radio-group component, the elements in the row are not adjusted to the height, so this causes the table to look ugly.
what property could i use to make the cols all fit to the same height.
I have looked in several places, even in the documentation and I do not see anything like it.
component:
<template>
<v-container>
<v-row class="text-center" no-gutters>
<v-col v-for="(item, index) in headers" v-bind:key="index">
<v-card v-if="item" :key="index" class="pa-2" outlined tile>
{{ item.nombre }}
</v-card>
</v-col>
</v-row>
<div v-for="(item, index) in items" v-bind:key="index">
<v-row no-gutters class="text-center"
align="center"
>
<v-col
align-self="center"
>
<v-card class="pa-2" outlined tile>
{{ item.nombre }}
</v-card>
</v-col>
<v-col>
<v-card class="pa-2" outlined tile>
{{ item.cantidad }}
</v-card>
</v-col>
<v-col offset-md="12">
<v-card outlined tile>
<v-radio-group v-model="radioGroup">
<v-radio
v-for="n in 2"
:key="n"
:label="`Radio ${n}`"
:value="n"
></v-radio>
</v-radio-group>
</v-card>
</v-col>
</v-row>
</div>
</v-container>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
optRadio: [
{ nombre: "Bueno", value: 1},
{ nombre: "Malo", value: 2},
],
headers: [
{ nombre: "Descripcion", value: "descripcion" },
{ nombre: "Cantidad", value: "cantidad" },
{ nombre: "estado", value: "state" },
],
items: [
{ nombre: "RADIO", cantidad: 1, state: 1 },
{ nombre: "FRONTAL", cantidad: 10, state: 0 },
{ nombre: "PARLANTES", cantidad: 100, state: 2 },
{ nombre: "ENCENDEDOR", cantidad: 100, state: 2 },
{ nombre: "CENICERO", cantidad: 100, state: 2 },
{ nombre: "TAPETES", cantidad: 100, state: 2 },
],
};
},
};
</script>
Your key here is applying correct flex attributes to your grid system.
First you'd have to instruct your colums to place content vertically, not horizontally: <v-col class="d-flex flex-column"
Then, instruct the cards within to grow in the available vertical height: <v-card class="pa-2 flex-grow-1 d-flex" outlined tile>. To get the content centered within the card, add these two flex helpers to the card as well: align-center justify-center
Documentation HERE
Codepen solution HERE
In my Vue.js project I have a v-data-table.
If cell content is true I would like to replace with the green check_circle icon.
Why this code isn't working?
<template v-for="header in headers" v-slot:item[header.value]="{ item }">
<v-icon v-if="item[header.value]" color="green">check_circle</v-icon>
</template>
Now the table is:
EDIT 1
<v-data-table
:loading="loading"
:headers="headers"
:items="items"
:items-per-page="items_per_page"
:search="search"
no-data-text="Non ci sono elementi"
no-results-text="Non ci sono elementi filtrati"
loading-text="Caricamento in corso..."
:footer-props="footerProps"
class="elevation-1">
<template v-for="header in headers" v-slot:item[header.value]="{ item }">
<v-icon v-if="item[header.value]" color="green">check_circle</v-icon>
<v-icon v-else color="red">cancel</v-icon>
</template>
<template v-slot:item.actions="{ item }">
<v-icon
small
class="mr-2"
#click="editItem(item)"
>mdi-pencil</v-icon>
<v-icon
small
#click="deleteItem(item)"
>mdi-delete</v-icon>
</template>
<template v-slot:top>
<v-toolbar flat color="white">
<v-spacer></v-spacer>
<v-dialog v-model="dialog" max-width="500px">
<template v-slot:activator="{ on }">
<v-btn color="primary" dark class="mb-2" #click="newItem" v-on="on">New Item</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-container>
<!-- modifica elemento -->
<v-row v-if="editedIndex > -1">
<v-col v-for="(key,i) in keys_visible" :key="key" v-show="headers_visible[i].visible == true" cols="12" sm="6" md="4">
<v-text-field v-if="headers_visible[i].type == 'varchar'" v-model="editedItem[key]" :label="headers_visible[i].text" :disabled="!headers_visible[i].editable"></v-text-field>
<v-switch v-else-if="headers_visible[i].type == 'bit'" v-model="editedItem[key]" :label="headers_visible[i].text"></v-switch>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="close">Cancel</v-btn>
<v-btn color="blue darken-1" text #click="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:no-data>
<v-btn color="primary" #click="initialize">Reset</v-btn>
</template>
</v-data-table>
headers is like this:
headers: [
{
text: 'Dessert (100g serving)',
align: 'start',
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 },
]
a item is like this:
item: {
cleaned: true,
name: '',
usable: 0,
...
}
To iterate the headers dynamically for all items you'd need to use the body slot...
<template v-slot:body="{ items }">
<tr v-for="idx in items">
<td v-for="header in headers" class="text-left font-weight-black">
<v-icon v-if="idx[header.value]" color="green">check_circle</v-icon>
</td>
</tr>
</template>
Demo: https://codeply.com/p/W0vKEyRGRO
Also see: Vuetify Datatable - Enable content editing on all columns
I am trying to create a table that allows me to have one v-select for each row of the "available" column and to save whatever the user selects, being either "In stock" or "unavailable" for that column. How exactly do i do that with the following table that contains the following data?
Table:
<template>
<v-data-table
:headers="headers"
:items="desserts"
:items-per-page="5"
class="elevation-1"
>
<template slot="items" slot-scope="props">
<tr #click="props.expanded = !props.expanded">
<td class="text-xs-right">{{ props.item.name}}</td>
<td class="text-xs-right">{{ props.item.calories}}</td>
<td class="text-xs-right">{{ props.item.fat}}</td>
<td class="text-xs-right">{{ props.item.carbs}}</td>
<td class="text-xs-right">{{ props.item.protein}}</td>
<td class="text-xs-right">{{ props.item.available}}</td>
</tr>
</template>
</v-data-table>
</template>
Data:
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
available: '',
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
available: '',
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
available: '',
},
Use v-select and bind it to item.available on the item slot template...
<template v-slot:item="{ item }">
<tr>
<td>{{item.name}}</td>
<td>{{item.calories}}</td>
<td>{{item.fat}}</td>
<td>{{item.carbs}}</td>
<td>{{item.protein}}</td>
<td>
<v-select
v-model="item.available"
:items="['in stock','unavailable']">
</v-select>
</td>
</tr>
</template>
https://codeply.com/p/9zqiPQEl80
I'm learning a Vuetifyjs and try writing a "file explorer".
There is an example:
codepen-snippet
I can’t understand how to make sure that when you click on the right icon, the entry in the "tree" does not become "active".
Probably need to “stop” the events, but I don’t know how to do it.
Tell me.
Thank.
I want to click on this menu: Menu
it became like this: need
not like now: now
Snippet:
<div id="app">
<v-app id="inspire">
<v-content>
<v-container >
<v-layout justify-center>
<v-card min-width=400>
<v-treeview
v-model="tree"
:open="open"
:items="items"
activatable
hoverable
item-key="name"
open-on-click
>
<template v-slot:prepend="{ item, open }">
<v-icon v-if="!item.file">
{{ open ? 'mdi-folder-open' : 'mdi-folder' }}
</v-icon>
<v-icon v-else>
{{ files[item.file] }}
</v-icon>
</template>
<template v-slot:label="{item}">
<v-hover v-slot:default="{ hover }">
<div class="d-flex align-center">
<span>{{item.name}}</span>
<v-menu
class="ml-auto"
style="display: inline"
:nudge-width="200"
offset-y
>
<template v-slot:activator="{ on }">
<!--
-->
<v-btn
v-show="hover"
icon
small
v-on="on"
class="pa-0 ma-0"
>
<v-icon small class="pa-0 ma-0">more_vert</v-icon>
</v-btn>
</template>
<v-card>
<v-list>
<v-list-item #click="() => {}">
<v-list-item-action>
<v-icon>mdi-information-variant</v-icon>
</v-list-item-action>
<v-list-item-title>Info</v-list-item-title>
</v-list-item>
<v-list-item v-if="item.type === 'process' || item.type === 'state'" #click="() => {}">
<v-list-item-action>
<v-icon>power_settings_new</v-icon>
</v-list-item-action>
<v-list-item-title>Status</v-list-item-title>
</v-list-item>
<v-list-item #click="() => {}">
<v-list-item-action>
<v-icon>create</v-icon>
</v-list-item-action>
<v-list-item-title>Rename</v-list-item-title>
</v-list-item>
<v-list-item #click="() => {}">
<v-list-item-action>
<v-icon>file_copy</v-icon>
</v-list-item-action>
<v-list-item-title>Copy</v-list-item-title>
</v-list-item>
<v-list-item #click="() => {}">
<v-list-item-action>
<v-icon>mdi-folder-plus</v-icon>
</v-list-item-action>
<v-list-item-title>Create folder</v-list-item-title>
</v-list-item>
<v-list-item #click="() => {}">
<v-list-item-action>
<v-icon>delete</v-icon>
</v-list-item-action>
<v-list-item-title>Delete</v-list-item-title>
</v-list-item>
</v-list>
</v-card>
</v-menu>
</div>
</v-hover>
</template
</v-treeview>
</v-card
</v-layout justify-center>
</v-container>
</v-content>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
open: ['public'],
files: {
html: 'mdi-language-html5',
js: 'mdi-nodejs',
json: 'mdi-json',
md: 'mdi-markdown',
pdf: 'mdi-file-pdf',
png: 'mdi-file-image',
txt: 'mdi-file-document-outline',
xls: 'mdi-file-excel',
},
tree: [],
items: [
{
name: '.git',
},
{
name: 'node_modules',
},
{
name: 'public',
children: [
{
name: 'static',
children: [{
name: 'logo.png',
file: 'png',
}],
},
{
name: 'favicon.ico',
file: 'png',
},
{
name: 'index.html',
file: 'html',
},
],
},
{
name: '.gitignore',
file: 'txt',
},
{
name: 'babel.config.js',
file: 'js',
},
{
name: 'package.json',
file: 'json',
},
{
name: 'README.md',
file: 'md',
},
{
name: 'vue.config.js',
file: 'js',
},
{
name: 'yarn.lock',
file: 'txt',
},
],
}),
})
What is happening here is that your click event is propagating to its parent element, so when you click on the icon to display the menu it also triggers the click event of your parent element which is the file or folder container.
You can add #click.stop to your v-btn in line 44, like this:
<template v-slot:activator="{ on }">
<!--
-->
<v-btn
v-show="hover"
icon
small
v-on="on"
class="pa-0 ma-0"
#click.stop
>
<v-icon small class="pa-0 ma-0">more_vert</v-icon>
</v-btn>
</template>
This will stop the event from propagating to its parent element, you can try it out here: codepen-snippet
Now when you click the button it will display your menu and won't change the active or inactive state on your files or folders.
To remove the blue highlighting of items when clicked, remove "activatable" from the v-treeview component:
<v-treeview
v-model="tree"
:open="open"
:items="items"
activatable
hoverable
item-key="name"
open-on-click >
I am new to vuetify and vue, I want to create a layout in which the users with sm or smaller screens will use the bottom-navigation component and the users with md or higher will use the navigation drawers.
I am using the v-app component, that according to the docs "help bootstrap your application with the proper sizing around component" and "These (components) can be mixed and matched and only one of each particular component should exist at any time."
<template>
<v-app>
<v-navigation-drawer app>
<v-list rounded>
<v-subheader>REPORTS</v-subheader>
<v-list-item-group v-model="item" color="primary">
<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-navigation-drawer>
<v-app-bar app>
<v-toolbar-title class="headline text-uppercase">
<span>Vuetify</span>
<span class="font-weight-light">MATERIAL DESIGN</span>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn text href="https://github.com/vuetifyjs/vuetify/releases/latest" target="_blank">
<span class="mr-2">Latest Release</span>
</v-btn>
</v-app-bar>
<v-content fluid>
<HelloWorld />
</v-content>
<v-bottom-navigation app>
<v-btn value="recent">
<span>Recent</span>
<v-icon>history</v-icon>
</v-btn>
<v-btn value="favorites">
<span>Favorites</span>
<v-icon>favorite</v-icon>
</v-btn>
<v-btn value="nearby">
<span>Nearby</span>
<v-icon>place</v-icon>
</v-btn>
</v-bottom-navigation>
</v-app>
</template>
<script lang="ts">
import Vue from "vue";
import HelloWorld from "./components/HelloWorld.vue";
export default Vue.extend({
name: "App",
components: {
HelloWorld
},
data: () => ({
item: 1,
items: [
{ text: "Real-Time", icon: "mdi-clock" },
{ text: "Audience", icon: "mdi-account" },
{ text: "Conversions", icon: "mdi-flag" }
]
})
});
</script>
So the documentation it's perhaps a bit unclear from the text.
It's up to you to display them as you see fit. But you should for example not have two v-app-bars visible at the same time.
So here is the solution:
<template>
<v-app>
<v-navigation-drawer app v-model="$vuetify.breakpoint.mdAndUp" stateless class="hidden-sm-and-down">
<v-list rounded>
<v-subheader>REPORTS</v-subheader>
<v-list-item-group v-model="item" color="primary">
<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-navigation-drawer>
<v-app-bar app class="hidden-sm-and-down">
<v-toolbar-title class="headline text-uppercase">
<span>Vuetify</span>
<span class="font-weight-light">MATERIAL DESIGN</span>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn text href="https://github.com/vuetifyjs/vuetify/releases/latest" target="_blank">
<span class="mr-2">Latest Release</span>
</v-btn>
</v-app-bar>
<v-content fluid>
<HelloWorld />
</v-content>
<v-bottom-navigation app class="d-flex d-md-none">
<v-btn value="recent">
<span>Recent</span>
<v-icon>history</v-icon>
</v-btn>
<v-btn value="favorites">
<span>Favorites</span>
<v-icon>favorite</v-icon>
</v-btn>
<v-btn value="nearby">
<span>Nearby</span>
<v-icon>place</v-icon>
</v-btn>
</v-bottom-navigation>
</v-app>
</template>
<script lang="ts">
import Vue from "vue";
import HelloWorld from "./components/HelloWorld.vue";
export default Vue.extend({
name: "App",
components: {
HelloWorld
},
data: () => ({
item: 1,
items: [
{ text: "Real-Time", icon: "mdi-clock" },
{ text: "Audience", icon: "mdi-account" },
{ text: "Conversions", icon: "mdi-flag" }
]
})
});
</script>