Vue, Vuetify 2 - How to add buttons to data table footer - vuejs2

The title pretty much says it all - I'd like to add a couple of fab buttons to the table footer (with which I plan to CRUD records in the table). Ideally I'd like to move the Rows per page and pagination to the left, and add my buttons in on the right, but at this point I'm willing to settle for adding my buttons on the left.
I looked at the documentation on data table slots, and I thought that body.append or footer might do it, but couldn't figure out how to translate them into my project, as they don't provide any mark up in the API section (only javascript objects) and none of the examples below the API section has what I'm looking for either.
Here's the code I'm currently using, in case it helps:
<v-data-table
v-model="selected"
item-key="id"
class="elevation-1"
:headers="headers"
:items="items"
:search="search"
:sort-by="['expiry.millis', 'label']"
:sort-desc="[false, true]"
multi-sort
show-select
>
<template v-slot:top>
<v-toolbar flat color="white">
<v-toolbar-title>Inventory</v-toolbar-title>
<div class="flex-grow-1"></div>
<v-text-field v-model="search" append-icon="mdi-magnify" label="Search" hide-details class="half-width"></v-text-field>
<div class="flex-grow-1"></div>
<v-btn color="error" small fab dark v-if="selected.length > 0"><v-icon>mdi-delete-outline</v-icon></v-btn>
<v-btn color="deep-purple accent-4" small fab dark class="ml-1"><v-icon>mdi-plus</v-icon></v-btn>
</v-toolbar>
</template>
<template v-slot:item.expiry="{ item }">
{{ item.expiry.until }}
<v-icon :title="item.expiry.date.format('DD/MM/YYYY')">mdi-information-outline</v-icon>
</template>
</v-data-table>
As you can see I currently have my buttons in the toolbar, along with the table name and a search bar.
I'm using Vuetify: 2.0.0. Let me know if I need to include any other information and I'll gladly update my question.

There is markup for body.append here:
https://codepen.io/pen/?&editable=true&editors=101
taken from the page you linked to, the point is it should look like this:
<template v-slot:body.append>...

I faked the buttons with adding v-card under the data table. check my pen
https://codepen.io/rveruna/pen/jONewxj
<div id="app">
<v-app>
<v-content>
<v-container>
<template>
<v-data-table
:headers="headers"
:items="desserts"
:items-per-page="5"
class="elevation-1"
></v-data-table>
</template>
<v-card style="border-top-left-radius: 0; border-top-right-radius: 0; box-shadow: 0px 5px 1px -2px rgba(0, 0, 0, 0.2), 0px 5px 2px 0px rgba(0, 0, 0, 0.14), 0px 5px 5px 0px rgba(0, 0, 0, 0.12);">
<v-card-text>
<div style="position: absolute; top: -42px" class="body-1 font-weight-bold">
<v-icon class="mdi-18px roundedIcon success" style="color: white">mdi-check</v-icon> Selected domains:
</div>
<template>
<v-chip class="mr-2 mb-2" close>blb</v-chip>
</template>
<template>
<v-chip class="mb-2" close>and bla more</v-chip>
</template>
</v-card-text>
<v-card-actions class="actionsDetails" style="background: rgb(249, 249, 249); border-top-left-radius: 0; border-top-right-radius: 0">
<v-spacer></v-spacer>
<v-btn text normal >Export All</v-btn>
</v-card-actions>
</v-card>
</v-container>
</v-content>
</v-app>
</div>

Using the suggestion of #MarcelusTrojahn, I've used a <v-data-table /> inside a <v-card>. The table would be enclosed in the <v-card-text> and the buttons container at the end
For instance :
<div id="app">
<v-app id="inspire">
<v-content>
<v-card>
<v-card-text class="table-container">
<v-data-table
:headers="headers"
:items="desserts"
:items-per-page="5"
class="elevation-1"
></v-data-table>
</v-card-text>
<div class="buttons-container">
<v-btn color="primary" class="footerBtn">
<v-icon right dark style='margin-right: 5px;'>mdi-chevron-left</v-icon>Prev
</v-btn>
<span class="footerBtn pageCount">{{ `${currentPageFrom} - ${currentPageTo}` }}</span>
<v-btn color="primary" class="footerBtn">Next<v-icon right dark>mdi-chevron-right</v-icon></v-btn>
</div>
</v-card>
</v-content>
</v-app>
</div>
See the codepen attached : https://codepen.io/bertrandmartel/pen/mdJYaBO

Related

I cant see index page in nuxt2

I'm having trouble solving one of the problems I've been given.
I can't see my index page in the pages folder, where could the problem come from?
index.vue
<template>
<h1>
Hello world
</h1>
</template>
I made another page with about address but it still had this problem.
Update
default.vue
<template>
<v-app :dark="setTheme" class="d-print-none" :rtl="true">
<v-toolbar
dense
flat
color="#fafafa00"
style="position: fixed; top: 0px; right: 0px; z-index: 5;"
>
<v-menu offset-y transition="slide-y-transition">
<template #activator="{ on }">
<v-btn class="ma-2 d-print-none" small text icon v-on="on">
<v-icon>mdi-apps</v-icon>
</v-btn>
<template>
<my-menu-app/>
</template>
</template>
<menuCard/>
</v-menu>
</v-toolbar>
</v-app>
</template>
Your problem is your layout.
add Nuxt tag for render your page.
<template>
<v-app :dark="setTheme" class="d-print-none" :rtl="true">
<v-toolbar
dense
flat
color="#fafafa00"
style="position: fixed; top: 0px; right: 0px; z-index: 5;"
>
<v-menu offset-y transition="slide-y-transition">
<template #activator="{ on }">
<v-btn class="ma-2 d-print-none" small text icon v-on="on">
<v-icon>mdi-apps</v-icon>
</v-btn>
<template>
<my-menu-app/>
</template>
</template>
<menuCard/>
</v-menu>
</v-toolbar>
<Nuxt/> // add Nuxt tag in your layout
</v-app>
</template>

v-list-item:hover is changing color of all v-list-items in v-list

Have an interesting case where when I hover over a v-list-item in my application, all the items in the v-list's background are changing to a different shade. It is a global application issue as it happens in all areas of my application.
I've inspected other v-list items that are behaving as expected and I don't see any styles that are missing.
Ideally, I'd like my v-list to behave as expected and shade only the one v-list item as it normally does but just do not know where to begin my search.
Any help would be appreciated.
<template>
<v-card elevation="0">
<v-card-text>
<v-row>
<v-col cols="12" class="d-flex gap align-center my-0 py-0">
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" icon>
<v-icon>
{{ mdiDotsVertical }}
</v-icon>
</v-btn>
</template>
<v-list class="py-0 my-0">
<v-list-item #click="showAdvancedEditDialog = true">
<v-icon class="mr-2" color="primary">
{{ mdiPencil }}
</v-icon>
<div color="primary" class="overflowText">
Advanced
</div>
</v-list-item>
<v-list-item #click="showHtmlEditDialog = true">
<v-icon class="mr-2" color="primary">
{{ mdiCodeTags }}
</v-icon>
<div color="primary" class="overflowText">
HTML Edit
</div>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>
<style>
.overflowText {
font-size: 14px;
font-family: Roboto;
text-transform: uppercase;
font-weight: 500;
color: #f2545b;
}
</style>

How to place a button in the same row as v-card title?

I have a header, sub-header, icon and button on my v-card. My goal is to place my create button the right, but I can't seem to do that.
<template>
<v-row class="pl-5">
<v-card class="pl-5" elevation="0">
<v-card-title>
<v-icon left x-large color="primary">{{ icon }}</v-icon>
<span class="font-weight-bold">{{ title }}</span>
</v-card-title>
<v-card-subtitle> Subheader </v-card-subtitle>
<v-spacer></v-spacer>
<router-link v-if="type == 'index'" :to="`/${name.toLowerCase().replace(' ', '-')}/create`">
<v-btn outlined class="blue--text mt-5 mr-8">
<span>Create</span>
</v-btn>
</router-link>
</v-card>
</v-row>
</template>
<script>
export default {
props: {
icon: String,
name: String,
title: String,
subtitle: String,
type: String
},
components: {}
}
</script>
<style scoped></style>
If I move my <router-link> in <v-card-subtitle>
I get this
If I move my <router-link> in <v-card-title>
I get this
Can someone give me a push here ?
Fiddle
https://jsfiddle.net/bheng/h2u870dv/
If I do this:
<v-row class="pl-5">
<v-card-title>
<span class="material-icons">
favorite_border
</span>
<p class="font-weight-bold">TITLE</p>
<p class="caption">ST</p>
</v-card-title>
<v-spacer></v-spacer>
<v-btn>Create</v-btn>
</v-row>
I get
Button seems to locate at the place I wanted it to be, but the title and subtitle misalign very badly. I'm stuck now.
You can add div or v-col in v-row and use css to align items the way you want:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
icon: 'favorite_border',
name: 'link',
title: 'TITLE',
subtitle: 'https://fonts.google.com/icons?selected=Material+Icons',
type: 'index'
}
}
})
.myclass {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: flex-start;
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Material+Icons" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-container>
<v-row class="pl-5">
<div class="myclass">
<v-card class="pl-5 mycard" elevation="0">
<v-card-title>
<v-icon left x-large color="primary">{{ icon }}</v-icon>
<span class="font-weight-bold">{{ title }}</span>
</v-card-title>
<v-card-subtitle> Subheader </v-card-subtitle>
<v-spacer></v-spacer>
</v-card>
<a v-if="type == 'index'" :href="`/${name.toLowerCase().replace(' ', '-')}/create`">
<v-btn outlined class="blue--text mt-5 mr-8">
<span>Create</span>
</v-btn>
</a>
</div>
</v-row>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
Your problem is that you're placing your button inside the v-card you declared to set the style of the title. And this card is just a square box since you haven't specified any width. If you set the elevation="1" you can see this clearly.
Just place your button outside the v-card and the v-spacer will work. Alternatively, you could also set the v-card width to 100%. Btw, you can also use the to prop in your v-btn, so there's no need to have a v-router-link.
Check this codesandbox I made: https://codesandbox.io/s/stack-71444864-v-spacer-example-0tx24n?file=/src/components/Example.vue
<v-row class="pl-5">
<v-card class="pl-5" elevation="0">
<v-card-title>
<v-icon left x-large color="primary"> mdi-home </v-icon>
<span class="font-weight-bold">Testing</span>
</v-card-title>
<v-card-subtitle class="pb-0"> Subheader </v-card-subtitle>
</v-card>
<v-spacer></v-spacer>
<v-btn to="/about" outlined class="blue--text mt-5 mr-8">
<span>Create</span>
</v-btn>
</v-row>
Update: v-cols and custom CSS with breakpoints conditionals
I saw you were interested to learn how to make this design using vuetify's grid. The advantage to use v-cols and breakpoint conditionals is that you'll have more control of your design over different viewports. Like on a mobile view. This is how I'd do it.
I start by splitting the grid in 2 columns, one for the title and one for the button, in cols view (previously known as xs (extra small)) I set the size of them to 12 columns and on sm (small) and up I set the size to 6 columns each. This way they are shown half and half.
The title column has no changes, on the buttom column I use the classes d-flex justify-end to move the button all to the right and align-center to center the button vertically at the middle of the v-row.
Then I use the breakpoint conditionals to activate the block property of the button and to apply paddings to the whole v-row, depending on the current viewport.
<v-row :class="$vuetify.breakpoint.smAndUp ? 'px-4' : ''">
<v-col cols="12" sm="6">
<v-card elevation="0">
<v-card-title>
<v-icon left x-large color="primary"> mdi-home </v-icon>
<span class="font-weight-bold">Testing</span>
</v-card-title>
<v-card-subtitle class="pb-0"> Subheader </v-card-subtitle>
</v-card>
</v-col>
<v-col cols="12" sm="6" class="d-flex justify-end align-center">
<v-btn to="/about" :block="$vuetify.breakpoint.xsOnly ? true : false" outlined class="blue--text">
<span>Create</span>
</v-btn>
</v-col>
</v-row>

Jumping Buttons on Vuetify V-Window

When using Vuetifies V-Window component I recognized that the left and right buttons are jumping when moving left or right.
Even on their examples it is the case: https://vuetifyjs.com/en/components/windows/#customized-arrows
Can anyone say how it can be fixed the best way for the "customized arrows" example?
You can set a height in v-windows component to solve it.
https://codepen.io/vinisalves/pen/yLVGVjZ?editors=1010
<div id="app">
<v-app id="inspire">
<v-card
color="black"
dark
flat
tile
>
<v-window v-model="onboarding" style="height: 200px"> <!-- here -->
<v-window-item
v-for="n in length"
:key="`card-${n}`"
>
<v-card
color="transparent"
height="200"
>
<v-row
class="fill-height"
align="center"
justify="center"
>
<v-card-text>
Transparent themed, for background-imaged slides. Background color black added for demonstration purposes.
</v-card-text>
</v-row>
</v-card>
</v-window-item>
</v-window>
<v-card-actions class="justify-space-between">
<v-btn
text
#click="prev"
>
<v-icon>mdi-chevron-left</v-icon>
</v-btn>
<v-item-group
v-model="onboarding"
class="text-center"
mandatory
>
<v-item
v-for="n in length"
:key="`btn-${n}`"
v-slot="{ active, toggle }"
>
<v-btn
:input-value="active"
icon
#click="toggle"
>
<v-icon>mdi-record</v-icon>
</v-btn>
</v-item>
</v-item-group>
<v-btn
text
#click="next"
>
<v-icon>mdi-chevron-right</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-app>
</div>

Container sitting behind navigation

My toolbar and sidenav sit on top of my container obstructing view of the contents.
I can easily put a top margin on the container to rectify the issue with the toolbar but because the sidenav retracts when screen width is reduced trying to do the same with the sidenav results in display issues.
App.vue
<template>
<v-app>
<Navs/>
<div class="div" style="margin-top: 64px;">
<router-view/>
</div>
<Footer/>
</v-app>
</template>
Navs.vue
<template>
<div class="content">
<!-- Sidenav draw -->
<v-navigation-drawer
class = "NavDark"
persistent
:mini-variant="true"
:clipped="clipped"
v-model="drawer"
enable-resize-watcher
mobile-break-point="1000"
app
>
<v-layout align-center justify-space-between fill-height column>
<v-layout align-center justify-start fill-height column>
<!-- Logo square -->
<div style = "height: 64px; width: 82px; position: absolute; z-index: -1;">
<Granim/>
</div>
<div style = "height: 64px;">
<v-container pa-0 bg fill-height grid-list-md text-xs-center>
<v-layout row wrap align-center>
<v-flex pa-0>
<v-list-tile-avatar>
<img src="#/assets/layout/sidebar/whitelogo.png" class="logo">
</v-list-tile-avatar>
</v-flex>
</v-layout>
</v-container>
</div>
<!-- </v-toolbar> -->
<!-- Items at the top of the sidenav -->
<v-list dark>
<v-list-tile
v-for="item in topMenuItems"
:key="item.title"
:to="item.path"
style="padding: 10px, 0px, 10px , 0px"
>
<v-tooltip right>
<v-list-tile-action
slot="activator"
>
<v-icon>{{ item.icon }}</v-icon>
</v-list-tile-action>
<v-list-tile-content>{{ item.title }}</v-list-tile-content>
</v-tooltip>
</v-list-tile>
</v-list>
</v-layout>
<v-list dark>
<!-- </v-layout> -->
<v-layout align-center justify-end column fill-height>
<v-menu
v-model="menu"
:close-on-content-click="false"
:nudge-width="200"
offset-x
>
<v-btn
slot="activator"
dark
icon
>
<v-icon>person</v-icon>
</v-btn>
<v-card>
<v-list>
<v-list-tile>
<v-list-tile-content>
<v-list-tile-title>{{ user.email }}</v-list-tile-title>
<v-list-tile-sub-title>{{ user.token }}</v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn flat #click="menu = false">Cancel</v-btn>
<v-btn color="primary" flat #click="menu = false">Settings</v-btn>
<v-btn color="error" flat #click="userSignOut">Logout</v-btn>
</v-card-actions>
</v-card>
</v-menu>
</v-layout>
</v-list>
</v-layout>
</v-navigation-drawer>
<v-toolbar
app
class ="elevation-0"
color="#eee"
:clipped-left="clipped"
>
<v-toolbar-side-icon
class="hidden-md-and-up"
#click="drawer = !drawer">
</v-toolbar-side-icon>
<v-toolbar-title v-text="title" class="toolbar-text"></v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-title v-if="user" v-text="user.email" class="toolbar-text"></v-toolbar-title>
</v-toolbar>
</div>
</template>
<style>
.NavDark {
height: 100vh;
box-shadow: 0 16px 38px -12px rgba(0,0,0,.56), 0 4px 25px 0 rgba(0,0,0,.12), 0 8px 10px -5px rgba(0,0,0,.2);
}
</style>
Ideally I'm trying to find a solution in which the <router-view/> will not overlap with <Navs/> and fill all available space on the screen not taken by the toolbar and sidenav.
Resolved by using v-content
<template>
<v-app>
<Navs/>
<v-content class="light">
<router-view/>
</v-content>
<Footer/>
</v-app>
</template>