Move button closer to the expand button - vue.js

In Vuetify, if I want to move my delete button closer to the expand button.
How do I do that ?
<v-expansion-panel-header>
{{ vehicle.VIN }}
<v-icon v-if="type == 'saved'" color="teal"> mdi-check </v-icon>
<v-btn
text
v-if="type == 'saved'"
color="red"
#click="remove(index, type)"
>
DELETE
</v-btn>
</v-expansion-panel-header>

You can reset the flex-grow property on the delete button using a Vuetify helper class.
class="flex-grow-0"
Snippet:
<div id="app">
<v-app>
<v-expansion-panel-header>
{{ vehicle.VIN }}
<v-icon v-if="type == 'saved'" color="teal"> mdi-check </v-icon>
<v-btn
class="flex-grow-0"
text
v-if="type == 'saved'"
color="red"
#click="remove(index, type)"
>
DELETE
</v-btn>
</v-expansion-panel-header>
</v-app>
</div>
Vuetify Docs: https://vuetifyjs.com/en/styles/flex/#flex-grow-and-shrink

It can also be achieved using row and column-
<v-expansion-panel-header>
<v-row no-gutters>
<v-col>
hello
</v-col>
<v-col>
<v-icon color="teal"> mdi-check </v-icon>
</v-col>
<v-col align="right">
<v-btn text color="red">
DELETE
</v-btn>
</v-col>
</v-row>
</v-expansion-panel-header>

Related

Vuetify 3 : v-menu location property not working

i have a v-menu on toolbars right corner. The menu displays as bottom right (end) so half the card is outside the view. I want to change to bottom left (start) however i can't seem to make it work.
<v-menu
location="start"
rounded
>
<template v-slot:activator="{ props }">
<v-btn
icon
v-bind="props"
>
<v-avatar
color="brown"
size="large"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
</v-btn>
</template>
<v-card>
<v-card-text>
<div class="mx-auto text-center">
<v-avatar
color="brown"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
<h3>{{ user.fullName }}</h3>
<p class="text-caption mt-1">
{{ user.email }}
</p>
<v-divider class="my-3"></v-divider>
<v-btn
rounded
variant="text"
#click="() => goSettings() "
>
Settings
</v-btn>
<v-divider class="my-3"></v-divider>
<v-btn
#click="() => logOut()"
>
Disconnect
</v-btn>
</div>
</v-card-text>
</v-card>
</v-menu>
I'm missing somethings? im checking the example in the docs https://next.vuetifyjs.com/en/components/menus/
thanks
edit: added screenshots of current behaviour vs expected
Edit 2: I tried the v-menu on a codepen and works as intended, however for some reason, it does not work inside a v-app-bar
Try using prop "anchor" instead of "location".
<v-menu
anchor="bottom end"
rounded
>
<template v-slot:activator="{ props }">
<v-btn
icon
v-bind="props"
>
<v-avatar
color="brown"
size="large"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
</v-btn>
</template>
<v-card>
<v-card-text>
<div class="mx-auto text-center">
<v-avatar
color="brown"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
<h3>{{ user.fullName }}</h3>
<p class="text-caption mt-1">
{{ user.email }}
</p>
<v-divider class="my-3"></v-divider>
<v-btn
rounded
variant="text"
#click="() => goSettings() "
>
Settings
</v-btn>
<v-divider class="my-3"></v-divider>
<v-btn
#click="() => logOut()"
>
Disconnect
</v-btn>
</div>
</v-card-text>
</v-card>
</v-menu>
I can't even tell you why this could work, because I wasn't able to find it in the Docs or Files, but it is used like that in one of the templates I'm using.
However, this only works for large screens, on mobile the card will be outside the view again.
I had the same problem, the solution is using the activator prop or perhaps, in your case you sould use the internal-activator prop.
<v-menu
location="start"
rounded
internal-activator
>
<template v-slot:activator="{ props }">
<v-btn
icon
v-bind="props"
>
<v-avatar
color="brown"
size="large"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
</v-btn>
</template>
<v-card>
<v-card-text>
<div class="mx-auto text-center">
<v-avatar
color="brown"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
<h3>{{ user.fullName }}</h3>
<p class="text-caption mt-1">
{{ user.email }}
</p>
<v-divider class="my-3"></v-divider>
<v-btn
rounded
variant="text"
#click="() => goSettings() "
>
Settings
</v-btn>
<v-divider class="my-3"></v-divider>
<v-btn
#click="() => logOut()"
>
Disconnect
</v-btn>
</div>
</v-card-text>
</v-card>
</v-menu>

show dialog box on mouseenter vuetify

I am trying to show a edit button and then open a dialog box on cliking using mouseenter and mouseleave. On entering the edit button is displayed but as soon as i click on it it's getting hide.
Can someone tell me what i am doing wrong here. The edit button is inside the DueDateAddM component.
<v-card-title class="mx-5">{{dayjs(key).format('DD MMM YYYY')}}</v-card-title>
<v-col v-for="(item, i) in value" :key="i">
<v-card-text
class="black--text py-0"
#mouseenter="item.isEdit=true"
#mouseleave="item.isEdit=false"
>
<v-row>
<span v-if="!item.isEdit" class="grey--text mr-1">#{{item.id}}</span>
<span
v-show="isLoggedIn"
v-if="item.isEdit"
class="mr-1"
#click="editDuedate"
>
<DuedateAddM :propItem="item" :duedateId="item.id" />
</span>
{{item.descp}}
<v-tooltip top>
<template v-slot:activator="{ on }">
<v-chip class="mx-1 py-0" small label v-on="on" v-if="item.previousdate">
<v-icon color="grey" small class="mr-1">fas fa-info-circle</v-icon>
<span>{{dayjs(item.previousdate).format("DD MMM YYYY")}}</span>
<span v-if="!item.previousdate">No Previous date found</span>
</v-chip>
</template>
<span>Previous Duedate</span>
</v-tooltip>
<v-tooltip top>
<template v-slot:activator="{ on }">
<v-chip small v-on="on" class="mx-1">
<v-icon color="grey" small class="mr-1">fas fa-tag</v-icon>
{{item.category}}
</v-chip>
</template>
<span>Category</span>
</v-tooltip>
<v-tooltip top>
<template v-slot:activator="{ on }">
<v-chip color="red lighten-4" small class="mx-1" v-on="on">
<v-icon color="grey" small class="mr-1">fas fa-map-marker-alt</v-icon>
{{item.region}}
</v-chip>
</template>
<span>Region</span>
</v-tooltip>
</v-row>
<v-row v-if="item.applicableto">
<v-subheader class="ml-1">Applicable To: "{{item.applicableto}}"</v-subheader>
</v-row>
<v-divider class="mt-2"></v-divider>
</v-card-text>
</v-col>
Use v-show instead of v-if
<span v-show="!item.isEdit" class="grey--text mr-1">#{{item.id}}</span>
<span
v-show="isLoggedIn"
v-show="item.isEdit"
class="mr-1"
#click="editDuedate"
>
<DuedateAddM :propItem="item" :duedateId="item.id" />
</span>

How can I call a method if select date in the datepicker vuetify?

My codepen like this : https://codepen.io/positivethinking639/pen/mddejJN
my code like this :
<div id="app">
<v-app>
<v-content>
<v-container>
<v-dialog
ref="dialogTest"
v-model="modalTest"
:return-value.sync="dateTest"
persistent
>
<template v-slot:activator="{ on }">
<v-btn color="success" dark v-on="on">call date</v-btn>
</template>
<div class="text-center title">Select a Date & Time</div>
<v-row justify="center">
<v-date-picker v-model="dateTest" scrollable :allowed-dates="allowedDates">
<div class="flex-grow-1"></div>
<v-btn text color="primary" #click="modalTest = false">Cancel</v-btn>
<v-btn text color="primary" #click="saveData">OK</v-btn>
</v-date-picker>
<v-slide-y-transition>
<v-col cols=2 v-show="dateTest !== null">
<template v-for="allowedTime in allowedTimes">
<v-btn
#click="setTime(allowedTime)"
class="my-2"
:outlined="allowedTime !== time"
block
x-large
color="primary"
>{{ allowedTime }}</v-btn>
</template>
</v-col>
</v-slide-y-transition>
</row>
</v-dialog>
{{dateTest}}
</v-container>
</v-content>
</v-app>
</div>
If I click button "call date", it will call datepicker. If I select a date, I want it call a method
How can i do it?
You can use #change="myMethod" or #click:date="myMethod" on v-date-picker.
Read vuetify date-picker documentation (events section) for more information.

How to fix the "this.$refs.[ref_name].save is not a function" in a "v-for" created component?

I'm working on a table list with some crud actions. When I click on the edit icon, I will open a dialog box that includes 3 "v-tabs-items" through a "v-for".
In the last v-tab i have an v-time-picker input in a menu, and use the structure of the Vuetify documentation.
<template>
<v-flex>
<v-data-table>
<!-- some data -->
</v-data-table>
<v-dialog
v-model="dialog"
>
<v-card>
<v-flex>
<v-toolbar color="secondary" light tabs>
<v-card-title>
<span class="headline">{{ formTitle }}</span>
</v-card-title>
<v-spacer />
<template v-slot:extension>
<v-tabs
v-model="tab"
color="secondary"
align-with-title
>
<v-tabs-slider color="accent" />
<v-tab v-for="i in items" :key="i">
{{ i }}
</v-tab>
</v-tabs>
</template>
</v-toolbar>
<v-tabs-items v-model="tab">
<v-tab-item v-for="i in items" :key="i">
<v-card flat>
<v-card-text v-if="i === 'Ad'" class="pa-0">
<!-- Some Content -->
</v-card-text>
<v-card-text v-if="i === 'Content'" class="pa-0">
<!-- Some Content -->
</v-card-text>
<v-card-text v-if="i === 'Target'" class="pa-0">
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12 sm6 md6>
<v-menu
ref="time_picker"
v-model="dailyTimeMenu1"
:close-on-content-click="false"
:nudge-right="-15"
:return-value.sync="editedItem.daily_time_from"
lazy
transition="scale-transition"
offset-y
full-width
max-width="290px"
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
v-model="editedItem.daily_time_from"
label="Time From"
prepend-icon="access_time"
readonly
outline
class="mr-2"
v-on="on"
/>
</template>
<v-time-picker
v-if="dailyTimeMenu1"
v-model="editedItem.daily_time_from"
full-width
#click:minute="$refs.time_picker.save(editedItem.daily_time_from)"
/>
</v-menu>
</v-flex>
<v-flex xs12 sm6 md6>
<v-menu
ref="time_picker"
v-model="dailyTimeMenu2"
:close-on-content-click="false"
:nudge-right="-15"
:return-value.sync="editedItem.daily_time_to"
lazy
transition="scale-transition"
offset-y
full-width
disabled
max-width="290px"
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
v-model="editedItem.daily_time_to"
label="Time to"
prepend-icon="access_time"
readonly
outline
v-on="on"
/>
</template>
<v-time-picker
v-if="dailyTimeMenu2"
v-model="editedItem.daily_time_to"
full-width
#click:minute="$refs.time_picker.save(editedItem.daily_time_to)
/>
</v-menu>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn color="blue darken-1" flat #click="close">
Cancel
</v-btn>
<v-btn color="blue darken-1" flat #click="saved">
Save
</v-btn>
</v-card-actions>
</v-card>
</v-tab-item>
</v-tabs-items>
</v-flex>
</v-card>
</v-dialog>
</v-flex></template>
...
and the script and Data object is.
<script>
export default {
data: vm => ({
dailyTimeMenu1: false,
dailyTimeMenu2: false,
items: [
'Ad', 'Content', 'Target'
],
tab: null,
dialog: false,
editedItem: {
daily_time_from: null,
daily_time_to: null,
}
})
}
The problem happens when I want to save the time when I pick the minutes.
I receive this error:
this.$refs.time_picker.save is not a function
Can you please explain to me what the problem is and how I can fix it?
Since you use ref="time_picker" in a v-for, this.$refs.time_picker will actually be an array. So you will need to keep track of the index in
<v-tab-item v-for="(i, idx) in items" :key="i">
and use idx in your all of your references to $refs.time_picker, like:
#click:minute="$refs.time_picker[idx].save(editedItem.daily_time_to)
EDIT: You also need to rename the second v-menu with the ref time_picker to something else, as it is now ambiguous which element you are referring to.

How to add right click event for v-treeview to open menu in vuetify?

I want to add right click event for v-treeview to open menu but I fail. I created a version that can open menu when left click and the main code is
<v-treeview v-model="tree" :open="open" :items="items" activatable item-key="name" >
<template v-slot:label="{item, open, selected}">
<v-menu
:value="showMenu"
>
<template v-slot:activator="{ on }">
<v-btn
flat
:ripple="false"
class="ma-0 pa-0"
v-on="on"
>
<!--button icon-->
<v-icon v-if="!item.file">
{{ open ? 'mdi-folder-open' : 'mdi-folder' }}
</v-icon>
<v-icon v-else>
{{ files[item.file] }}
</v-icon>
<!--button text-->
{{item.name}}
</v-btn>
</template>
<v-list>
<v-list-tile v-for="menuItem in menuItems" :key="menuItem">
<v-list-tile-title>{{menuItem}}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</template>
</v-treeview>
Note: the source code can be run at https://codepen.io/lhuangjs/pen/axMpYJ
And I am confused with v-on="on" in activator slot so much and I get some info from https://github.com/vuetifyjs/vuetify/issues/6866. However I still cannot understand it. Is there any more clear explanation?
thanks!
You have to use #contextmenu on the tree nodes.
I have tried to achieve what you tried. https://codepen.io/anon/pen/QPoYOQ?editors=1010#anon-login
But to make the tree look good, you have to do some CSS adjustments. I'm not sure any element other than v-btn or v-card accepts the #contextmenu event handler.
<div id="app">
<v-app id="inspire">
<v-treeview v-model="tree" :open="open" :items="items" activatable item-key="name">
<template v-slot:label="{item, open, selected}">
<v-btn flat #contextmenu="show">
<!--button icon-->
<v-icon v-if="!item.file">
{{ open ? 'mdi-folder-open' : 'mdi-folder' }}
</v-icon>
<v-icon v-else>
{{ files[item.file] }}
</v-icon>
<!--button text-->
{{item.name}}
</v-btn>
</template>
</v-treeview>
<v-menu v-model="showMenu" :position-x="x" :position-y="y" absolute offset-y>
<v-list>
<v-list-tile v-for="menuItem in menuItems" :key="menuItem" #click="clickAction">
<v-list-tile-title>{{menuItem}}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</v-app>
</div>
you can popup a context menu by adding #contextmenu event in a label slot:
<v-treeview :items="files" dense open-on-click transition hoverable>
<template v-slot:prepend="{ item, open }">
<v-icon v-if="item.children">{{ open ? 'mdi-folder-open' : 'mdi-folder' }}</v-icon>
<v-icon v-else>{{ icon(item.basename) }}</v-icon>
</template>
<template v-slot:label="{ item }">
<div #contextmenu.prevent="right($event, item)">{{ item.basename }}</div>
</template>
</v-treeview>