Dayspan Vuetify: Add a button inside day cell - vue.js

I'm working on a project based on Dayspan Vuetify library (
https://github.com/ClickerMonkey/dayspan-vuetify ).
I don't know how i can add a button inside each day cell. Someone help will be welcome!
Live Demo

You can put whatever you want in the template (see the button):
https://github.com/ClickerMonkey/dayspan-vuetify-example/blob/master/src/App.vue
<template slot="eventTimeTitle" slot-scope="{calendarEvent, details}">
<div>
<v-icon class="ds-ev-icon"
v-if="details.icon"
size="14"
:style="{color: details.forecolor}">
{{ details.icon }}
</v-icon>
<v-btn outline #click="doSomething" color="indigo">Button</v-btn>
<strong class="ds-ev-title">{{ details.title }}</strong>
</div>
<div class="ds-ev-description">{{ getCalendarTime( calendarEvent ) }}</div>
</template>
Add a method for the click:
doSomething(e) {
console.log(e);
alert('clicked')
}

Related

Is it possible to integrate a clickable cell to vutify v-data-table?

Good morning,
I know that
<v-data-table
:headers="headersfav"
:items="itemsfav"
#click:row="showSaleslead"
>
can start an action when the row is clicked. Is there also the possibility to limit it to one cell?
You will have to use the relevant cell slot:
<v-data-table
:headers="headersfav"
:items="itemsfav"
#click:row="showSaleslead"
>
<template slot="items.cellName" slot-scope="{item}">
<div #click.stop="onSingleCellClick">{{ item.value }}</div>
</template>
</v-data-table>
There's no event to do that here, but you could achieve that using item slot :
<v-data-table :headers="headersfav" :items="itemsfav">
<template v-slot:item.saleslead="{ item }">
<span #click.stop="showSaleslead">{{ item.saleslead}}</span>
</template>
</v-data-table>

vue.js how do I make a v-slot template dynamic?

Hello and thank you for reading my question! I am working with Vue.js, Vuetify and v-data-table and I am working on making my v-slot work with two different strings as the name of the header.
<template>
<v-container fluid>
<v-data-table
:options="data"
:headers="headers"
:items="data
:server-items-length="40"
:loading="loading"
:multi-sort="true"
#update:options="updateThePage"
>
<template v-slot:[`header.overalls`]="{ header }" class="flight-date-header">
<overallDatePicker
:options="data"
/>
{{ header.name }}
</template>
<template v-slot:[`item.name`]="{ item }">
<p class="company-name">
{{ item.companyName }}
</p>
</template>
<template v-slot:[`item.price`]="{ item }">
<p> {{ item.price }} </p>
</template>
<template v-slot:[`item.flightDate`]="{ item }">
<p class="style">
{{ item.startDate }}
</p>
</template>
</v-data-table>
</v-container>
</template>
and I store my headers like below
headers: [
{ text: 'Campaign Name', value: 'overalls' },
],
Ideally I would like the name of this slot
<template v-slot:[`header.overalls`]="{ header }" class="flight-date-header">
<overallDatePicker
:options="data"
/>
</template>
To work with two different data options. right now the name of the header is overalls but I want the name of the header so ['header.overalls'] to be like ['header.('overalls' || 'shoes')] ,
The reason I am doing this is right now when I click on the header the options.sortBy property of the table gets set to 'overalls', but I want the icon on the column to show up if the options.sortBy property of the table is "overalls" and also show up if it is "shoes"
Please help and thank you so much!
To reuse the slot content for multiple headers/columns, use Vue's dynamic slots names feature + v-for
data() {
return {
specialHeaders: ['overalls', 'shoes'],
}
}
<template v-for="column in specialHeaders" v-slot:[`header.${column}`]="{ header }">
Special:{{header.text}}
</template>

how to pass text, button and icon to v-radio elements

<VRadioGroup :multiple="multiple" v-model="radioGroup">
<VRadio
v-for="(item, index) in options"
:key="index"
:label="item.text"
:value="item.value"
>
</VRadio>
</VRadioGroup>
I got something like this.
Question 1) I want user to be able to select all of them or as many as he wants. Looks like :multiple="true" or multiple doesn't work. I can only select one. I should also be able to unselect any of them.
Question 2) beside each v-radio, I want to have its name, button and icon. I tried the following thing(All I could find was v-radio has a label slot. I tried this:
<template slot="label" slot-scope="data">
{{ data.item.text }}
<VBtn #click="removeRadioButton(item.value)" ripple
><BaseIcon name="minus-circle" /> </VBtn
>
</template>
I put this between VRadio tags. Looks like each of them has a button and icon, but it gives me error. (item of undefined). seems like data in slot-scope is undefined.
Answer 1:
It is simple. You can change the type radioGroup to an array.
It will work.
<div id="app">
<v-app id="inspire">
<v-container fluid px-0>
{{radioGroup}}
<v-radio-group
v-model="radioGroup"
multiple=true>
<v-radio
v-for="n in 3"
:key="n"
:label="`Radio ${n}`"
:value="n"
></v-radio>
</v-radio-group>
</v-container>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
radioGroup: []
}
},
})
Note: But For multiple selections, you shouldn't use radio buttons. Go for Checkbox.
Answer 2:
Issue In your code: You're looping on the radio button.
If you want some different text on before all radio buttons then you need to loop on a div which will contain the text and icons.
<div id="app">
<v-app id="inspire">
<v-container fluid px-0>
{{radioGroup}}
<v-radio-group
v-model="radioGroup"
multiple="true">
<div
v-for="n in 3"
:key="n"
>
<span class="d-inline">
{{n}}
</span>
<v-radio
class="d-inline"
:label="`Radio ${n}`"
:value="n"
></v-radio>
<span>
icon here
</span>
</div>
</v-radio-group>
</v-container>
</v-app>
</div>

Vuetify: show tooltip with a condition

I'm new to Vue.js and I hope with your help to understand scoped slots...
I would like to optimize my code, the tooltip must be visible on hover only if the label has more than 10 characters (or any other condition).
This works, but it is not optimized:
<v-btn>
<v-tooltip right v-if="slot.label.length > 20">
<template v-slot:activator="{on}">
<span class="text-truncate ml-1 mr-1" v-on="on">
{{slot.label}}
</span>
</template>
<span>{{slot.label}}</span>
</v-tooltip>
<span v-else class="text-truncate ml-1 mr-1">
{{slot.label}}
</span>
</v-btn>
I think the easiest way to achieve the desired effect without duplication is to use the disabled prop of v-tooltip.
new Vue({
el: '#app',
data () {
return {
slot: {
label: 'Label'
}
}
}
})
<link rel="stylesheet" href="https://unpkg.com/vuetify#1.5.16/dist/vuetify.css">
<script src="https://unpkg.com/vue#2.6.10/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#1.5.16/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-btn>
<v-tooltip right :disabled="slot.label.length < 10">
<template v-slot:activator="{on}">
<span class="text-truncate ml-1 mr-1" v-on="on">
Button: {{ slot.label }}
</span>
</template>
<span>Tooltip: {{ slot.label }}</span>
</v-tooltip>
</v-btn>
<v-btn #click="slot.label = 'Label'">Short</v-btn>
<v-btn #click="slot.label = 'Label label'">Long</v-btn>
</v-app>
</div>
The downside of this approach is that it still creates the tooltip even if it's disabled. The overhead isn't significant but if there are going to be a lot of tooltips then that might be a consideration.
There are various other ways to approach this but I can't think of any that are particularly simple. You could use a render function. That would allow you to write exactly what you want without any duplication but at the expense of needing to maintain a render function.
Sometimes you may want to show the tooltip when the underlying element is disabled. For eg: If a user has used all the resources in his account and then we need to ask the user to buy more resources. In such time insert an extra div and then add v-on onto to it.
<v-tooltip bottom :disabled="!noCandies">
<template v-slot:activator="{ on, attrs }">
<div v-on="on"> <!-- CREATE A DIV AND ADD V-ON HERE-->
<v-btn :disabled="noCandies" small class="mt-1" #click="useCandy">
Use candy
</v-btn>
</div>
</template>
<span>Buy more candies</span>
</v-tooltip>

Using Vuetify tooltip (v-tooltip) component with an external activator (i.e. not wrapped)

I understand how to use Vuetify's v-tooltip with the tooltip wrapping the component. However, I'm not quite sure how to have the activator button outside.
e.g. I have this (non-working code):
<v-tooltip bottom
:activator="$refs.filterBtn"
>
Filter displayed items
</v-tooltip>
<v-btn
ref="filterBtn"
icon
#click="isFilter = !isFilter"
>
<v-icon>fa-filter</v-icon>
</v-btn>
I also tried using prop activator without the v-bind:, same result
Idea: I want the button to be placed separately from tooltip in order to run unit tests. When testing, shallowMount strips anything inside <v-tooltip> so I can't test the button. The problem is I don't know how to make tooltip show up on hover (just like it does when wrapped), I do not want to trigger it with #click.
EDIT: here's codepen
How about using the v-hover UI Component. Wrap it around your button. Bind a boolean variable to the v-hover using v-model, call it buttonHovering. Then bind a boolean variable to the v-tooltip using v-model, call it showToolTip. Then use a watcher to toggle showToolTip true and false based on the value of buttonHovering. Or you can make showToolTip a computed property that always returns the value of buttonHovering. Lastly, bind the disabled attribute of the v-tooltip to the !buttonHovering property to ensure that the tooltip only displays when hovering over the button and not the tooltip's activator.
new Vue({
el: '#app',
data () {
return {
buttonHovering: false,
showToolTip: false
}
},
watch: {
buttonHovering (newVal) {
this.showToolTip = newVal
}
}
})
<link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons' rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.16/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-card>
<v-card-title>
<v-hover v-model="buttonHovering">
<v-btn large>
Hello
</v-btn>
</v-hover>
<v-spacer></v-spacer>
<v-tooltip left v-model="showToolTip" :disabled="!buttonHovering">
<span>Hi from over here!</span>
</v-tooltip>
</v-card-title>
</v-card>
</v-app>
</div>
Try this:
<v-tooltip bottom
v-model="filterBtnTTip"
>
Filter displayed items
</v-tooltip>
<v-btn
icon
#click="isFilter = !isFilter"
#mouseover="filterBtnTTip = true"
#mouseleave="filterBtnTTip = false"
>
<v-icon>fa-filter</v-icon>
</v-btn>
...
data () {
return {
...
filterBtnTTip: false
}
}
<v-app>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
>
Your button
</v-btn>
</template>
<span> Your hover message </span>
</v-tooltip>
</v-app>
In my case, it was necessary to place the tooltip together with the button in one component (a custom button with a tooltip function). Therefore, I used a prop activator and added the tooltip itself directly to the button:
<template>
<v-btn
:id="id"
>
<span>
<slot></slot>
<v-tooltip
v-if="tooltipText"
:activator="`#${id}`"
top
>
{{ tooltipText }}
</v-tooltip>
</span>
</v-btn>
</template>
<script>
let id = 0;
export default {
data() {
return {
id: `custom-button-${id++}`, //This is how we get a unique id for each created button
}
}
}
</script>
According to the same scheme, you can place v-tooltip anywhere, the main thing is that at the time of mounting the "activator" already exists.