I am using vuetifys v-rating component. I am displaying the current average rating using v-model. When a user clicks the rating component I want to update the current rating. This works good, the problem is that there will be no event emitted, when the current rating is equal to the rating the user want to give. This follows the docks, as the rating component does only emit an event when the input is changed. Any ideas how to emit an event when a star is clicked regardless if it is the same as the current one?
<v-rating
:readonly="isGuest"
color="yellow accent-4"
background-color="grey lighten-2"
v-model="averageRating"
hover
size="20"
dense
#input="handleRating"
></v-rating>
You can use item slot for handling rating change:
<v-rating v-model="rating">
<template v-slot:item="props">
<v-icon
:color="props.isFilled ? 'blue' : 'grey lighten-1'"
#click="handleRatingChange(props)"
>mdi-star
</v-icon>
</template>
</v-rating>
data: () => ({
rating: 3
}),
methods: {
handleRatingChange(props) {
console.log(props.index + 1)
this.rating = props.index + 1
}
}
Related
I have a v-date-picker similar to the one in Vuetify documentation. I'm using the one that allows you to type dates on the input, besides allowing to select a date on the picker (see the anchored link I shared).
The problem is, if you are typing a date on the input while the date picker is open, the date on the picker will not be updated. From the user perspective, it will seem as if the old date is still selected.
Note that I'm already subscribing to the #input event on my input field, updating the date picker date whenever a valid date is typed. This seems to be a refresh/redraw problem that the picker has, as the calendar will not update to the correct date. It has to be closed and opened again for it to be updated.
The example in Vuetify documentation also has this problem.
Any idea on how can I force the refresh/redraw of the date picker while it is open?
Thanks!
I was creating a CodePen to better show my problem (as #kissu requested) and found that I had a bug on my implementation. That was why the date picker was not being updated with the typed date.
Here is the working template code:
<v-menu
v-model="menu1"
:close-on-content-click="false"
transition="scale-transition"
offset-y
max-width="290px"
min-width="auto"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
v-model="formattedDate"
label="Date"
prepend-icon="mdi-calendar"
v-bind="attrs"
v-on="on"
#input="dateTyped"
></v-text-field>
</template>
<v-date-picker v-model="date" no-title #input="datePicked"></v-date-picker>
</v-menu>
<p>Date inside the input field is in <strong>DD/MM/YYYY</strong> format</p>
And javascript code:
const App = {
template: "#app-template",
data: () => ({
menu1: false,
date: "2022-10-25",
formattedDate: "25/10/2022"
}),
methods: {
datePicked(date) {
if (!date) return;
this.formattedDate = this.formatDateForInput(date);
this.menu1 = false;
},
formatDateForInput(date) {
const [year, month, day] = date.split("-");
return `${day}/${month}/${year}`;
},
dateTyped(date) {
if (!date || date.length !== 10) return;
console.log(date);
this.date = this.formatDateForPicker(date);
},
formatDateForPicker(date) {
const [day, month, year] = date.split("/");
return `${year}-${month}-${day}`;
}
}
};
CodePen in case someone wants to check it out in action: https://codepen.io/mcarreira/pen/gOKOepQ
Scenario
When clicking an option item, natively, the v-autocomplete (with multiple prop) active its respective checkbox and keeps with the menu open, allowing you to continue selecting other items until you click out of the menu
Objective
What I would like is to change this behavior, when I clicked only in the checkbox, the native behavior is maintained, but when clicked specifically on the line, the menu is closed and trigger a function using the value of the selected item.
I imagine that it is necessary to use the slots but I really don't know how to use it or if this is the best way to obtain this new behavior.
Note
The vertical line is for concept demonstration purposes only, it is not necessary to include this line in the component.
As you said, you can do it using slots. The idea is to override items display to remove the clickable v-list-item underneath. The drawback is that you have to re-implement values selection.
You'll need a checkbox and two methods: isSelected and toggleItem.
Template section:
<v-autocomplete
v-model="values"
:items="items"
outlined
dense
chips
small-chips
label="Outlined"
multiple
>
<template #item="{ item }">
<v-list-item class="d-flex">
<div>
<v-simple-checkbox color="primary" :value="isSelected(item)" #click="toggleItem(item)" />
</div>
<div class="ml-2">{{ item }}</div>
</v-list-item>
</template>
</v-autocomplete>
Script section:
data: () => ({
items: ['foo', 'bar', 'fizz', 'buzz'],
values: ['foo', 'bar'],
}),
methods: {
isSelected(item) {
return this.values.includes(item);
},
toggleItem(item) {
if (this.values.includes(item)) {
this.values = this.values.filter(v => v !== item);
} else {
this.values.push(item);
}
}
}
Please take a look at this working example.
I'm trying to use tiptap. Actually it works, but what I'm trying to do is to access the "isActive" slot from outside the editor component, and I don't know how to do it.
Here is a codesandbox example: https://codesandbox.io/s/v07xnxo807?file=/src/App.vue
You see the Editor component is called from the App.vue. The buttons in the Editor component are activated depending on the "isActive" slot functions.
What I would like is to access this slot to get for example the value of isActive.bold() from the App.vue, in order to update the model of a "multiple button" you can find on Vuetify: https://vuetifyjs.com/fr-FR/components/button-groups/
Here is for example what I could have:
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive }">
<v-btn-toggle
v-model="toggle_multiple"
dense
background-color="primary"
dark
multiple
class="my-2"
>
<v-btn :color="isActive.bold()?'red':'green'" #click="commands.bold">
<v-icon>mdi-format-bold</v-icon>
</v-btn>
<v-btn #click="commands.italic">
<v-icon>mdi-format-italic</v-icon>
</v-btn>
<v-btn #click="commands.strike">
<v-icon>mdi-format-strikethrough</v-icon>
</v-btn>
<v-btn #click="commands.underline">
<v-icon>mdi-format-underline</v-icon>
</v-btn>
<v-btn #click="commands.blockquote">
<v-icon>mdi-format-quote-open</v-icon>
</v-btn>
</v-btn-toggle>
</editor-menu-bar>
And the toggle_multiple would be computed depending on the different "isActive" function values.
I already tried:
computed: {
toggle_multiple: function () {
let t = []
if (editor) {console.log("Bold: "+editor.isActive.bold())}
return t
}
},
But I receive this error: error 'editor' is not defined
I'm open to any suggestion.
Thanks in advance.
Property isActive is stored in the tiptap instance (in your case it's this.editor):
In HTML:
<div>{{editor.isActive.bold()}}</div>
In JS:
<div>{{toggle_multiple}}</div>
computed: {
toggle_multiple () {
// Keep in mind, other properties like ".isActive.heading()" will be undefined
// until you import the extension for it.
// So the function "heading" below exists only if you're using that extension
// console.log(this.editor.isActive.heading({ level: 2 })
return this.editor.isActive.bold()
}
}
How can I trigger the search filter once a button is clicked?
I don't want to filter each type that someone typing in the search bar.
I want to trigger searching once they click a button "Search Now".
<b-table
id="table-transition-example"
:busy.sync="loading"
:items="myProvider"
:fields="fields"
:current-page="currentPage"
:per-page="perPage"
striped
small
primary-key="user_id"
:filter="filter"
:sort-by="sortBy"
:sort-desc="sortDesc"
>
With this code anytime that someone typing in search bar, automatically search the table.
Can somehow to append :filter attribute if I create a custom event? OR any other ideas?
Bind a different data property to your input, and create a method that assigns the value from your input to your filter property.
Rough example:
<input v-model="filterInput">
<button #click="applyFilter">Search now</button>
<b-table :filter="filterTable"></b-table>
<script>
data() {
return {
filterInput: '',
filterTable: ''
}
},
methods: {
applyFilter() {
this.filterTable = this.filterInput
}
}
</script>
now i have 2 Components
1 - is just a drop down list v-select
<v-row align="center" >
<v-col class="d-flex" cols="12" sm="6" v-if="Compounds" >
<v-select :items="Compounds"
v-model="selectedItems"
label="Select"
item-value="id"
item-text="name"
v-on:change="selectedCompound">
</v-select>
{{ selectedItems }}
</v-col>
</v-row>
with method
methods: {
selectedCompound(h2o) {
console.log(h2o);
console.log("This is from Selected Compound");
},
and i call it in another page
<div>
<SelectCompound></SelectCompound>
</div>
now i want to get the method "selectedCompound" and recall it on this page
so i can access the ID of it to reload the page when the user select another name from the v-select
Props are passed down, Events are emited up. If you want to communicate directly between the parent and child, you pass props from parent to child, and the child reacts to the change in value. If you however want the parent to react to changes the child component, you need to emit events.
Here is an example.
Child
methods: {
selectedCompound(h2o) {
this.$emit('valChange', h2o)
},
}
Parent
<div>
<SelectCompound #valChange="handleChange"></SelectCompound>
</div>
methods: {
handleChange(h2o) {
// handle here
console.log('parent noticed change ' + h2o)
},
}
You can also use a bus (like Vuex) to have all components communicate to a separate state manager, but it increases the complexity quite a bit compared to simple even emit.
I made this jsfiddle for you, using the localStorage as persistence if u need to reload the page, and emitting a event when any option of the select is selected, this event triggered is called change on the select tag, then just you have emit to the parent the value selected.
And using the life cycle method created() of Vue to init the value from the persistence.