I have a Vuetify combobox that on save does an api call to store the selected or entered value. However, when updating this value, if the save button is clicked directly without deselecting the combobox, the previously stored value is stored again, instead of the new value. Only when I manually unselect the box or press enter does the correct value store. I have looked around and found certain fixes that have worked for others, such as .blur() and .$nextTick, but they haven't seemed to work for me (I could be implementing them incorrectly). Here's what I have:
Combobox:
<v-combobox
:items="suggestions"
v-model="editedItem.field_label"
label="Label"
outlined
dense
ref = "comboBox"
></v-combobox>
Save button:
<v-btn color="blue darken-1" text #click="save"> Save</v-btn>
Save function:
save() {
this.$refs.comboBox.$emit("blur")
this.$nextTick(() => {
const device_field = {
...this.editedItem,
};
device_field_api
.updateDeviceField(device_field, this.device_id)
.then((r) => {
//Various logging items
);
})
.finally(this.initialize())
.catch((e) => {
//Error catching
);
});
});
}
Change
this.$refs.comboBox.$emit("blur")
to this:
this.$refs.comboBox.blur().
Codepen example
Result:
Related
While it's working in example, I have problem in my production code. So, combobox in vuetify provide autocomplete results and functionality to add new custom variant, but when pressing Enter menu is popup. How to disable this? No code examples in google helps with it.
<template>
<v-combobox
v-model="locationType"
:items="locationTypes"
label="Тип локации"
:loading="locationTypesIsLoading"
:menu-props="{ closeOnContentClick:true }"
></v-combobox>
</template>
OMG I spent hours upon hours trying to figure this out too and just got it:
Add to your v-combobox/autocomplete:
<v-autocomplete>
...
#change="onChange()"
refs="mytable"
</v-autocomplete>
Then add a new method:
onChange() {
this.$nextTick(() => {
this.$refs.mytable.isMenuActive = false
})
}
and that's it!!
How to get Vuetify checkbox event.target.checked and event.target.value?
I'm using Vuetify's checkbox in my app. When the user checks/unchecks it, I want to get the checked and the value properties.
I realize that it is not a native checkbox element, so I don't have access to event.target.checked or event.target.value, but surely there must be a way to do that. I tried the following:
<p v-for="(linkType, index) in linkTypes" v-if='linksLoaded'>
<v-checkbox
color="info"
:label="linkType"
:value="linkType"
v-model="checkedLinks"
#click="onCheckboxClicked($event)"></v-checkbox>
</p>
...
onCheckboxClicked: function(e) {
console.log(e);
},
For some reason it printed a mouse event TWICE and the checkbox itself didn't change (the check mark wasn't unchecked).
#click.native printed the same mouse event, but once.
I tried #change="onCheckboxClicked" - that printed the v-model.
So is there a way to do that?
I see that you are looping without binding a key, and inside you have v-model which is hooked to a single variable. So, whenever some checkbox is changed all others will update simultaneously. So you need new v-model for each checkbox. Why not add another property in linkTypes so you can v-model="linkType.checked".
change is the name of the event which gets triggered whenever checkbox value is changed and value is passed as a parameter.
<v-checkbox
#change="checkboxUpdated"
color="info"
:label="linkType"
:value="linkType"
v-model="checkedLinks"
#click="onCheckboxClicked($event)"></v-checkbox>
and in methods you need
checkboxUpdated(newValue){
console.log(newValue)
}
The easy way to access whether the checkbox is checked or not after clicking is to check it value. If it is null or empty array, then you can assume that its not checked. It depends on how you initialised the variable. This is the safest way to get what you want.
<v-checkbox
v-for="(el, index) in checkboxes"
:key="index"
v-model="checkbox[index]"
:value="el"
:label="`Checkbox ${index}`"
#change="valueChanged($event, index)"
></v-checkbox>
new Vue({
el: '#app',
data () {
return {
checkboxes: ['Opt 1', 'Opt 2', 'Opt 3', 'Opt 4'],
checkbox: [],
}
},
methods: {
onChange(val, i) {
console.log(val, i, this.checkbox)
if (val === null || val.length === 0) { // Custom checks in this
console.log('Unchecked')
} else {
console.log('Checked')
}
}
}
})
If you really need access to the element, then you can use ref to get the component. Then try to find the input element inside the component. And then find the checked value of that input element. But depending on how the library is implemented, you might not get the right value for $refs.checkbox.$el.target.checked.
You are lookin for a event. If you want to know if your checkbox is checked or not, you should use this:
onCheckboxClicked: function(e) {
console.log(e.target.checked)
},
As you've already noticed, Vuetify checkbox is not a native checkbox element. Therefore, event.target.checked and event.target.value do not exist. To fix this, one needs to do 2 things:
Disable the ripple effect of the v-checkbox. Otherwise, there will be a div on top of the input checkbox tag. Then, event.target is the one we expected.
However, when the user clicks on the label, it also affects the checkbox. In this case, we need to access the checkbox via event.target.control.
The checkbox in your question should like this:
<v-checkbox
color="info"
:ripple="false"
:label="linkType"
:value="linkType"
v-model="checkedLinks"
#click.native="onCheckboxClicked"
/>
Then, in the onCheckboxClicked method:
const onCheckboxClicked = (event) => {
const target = event.target.control ?? event.target;
const isChecked = target.checked;
const value = target.value;
// Do something here...
};
Notice that we use .native modifier for the click event. Otherwise, the event.target.control.checked will give opposite values (false when the checkbox is checked and vice versa).
And small note: you should always bind the key value when using v-for.
Im trying to show the dialog when I click the Dashboard link.
The problem is I can't change the dialog value to true since its inside the data method. What's the correct way to do it?
export default {
data: () => ({
drawer: true,
dialog: false
}),
props: {
source: String
},
methods: {
me: () => {
alert('me')
},
showDialog: () => {
this.dialog = true
}
},
computed: {
months: () => (
this.months = ['na', 'asd', 'asd']
)
}
}
Here is the layout in jsfiddle https://jsfiddle.net/vfztk8ve/
I noticed following code in your layout.
<v-btn color="blue darken-1" flat #click.native="dialog = false">Close</v-btn>
<v-btn color="blue darken-1" flat #click.native="dialog = false">Save</v-btn>
I'd like to say you are in the perfect way to close the dialog and set the component's dialog value as false.
Actually data method performs like a variable rather than a method in component, because we won't share a value in the component across all component instance. Following are official document.
When defining a component, data must be declared as a function that returns the initial data object, because there will be many instances created using the same definition. If we use a plain object for data, that same object will be shared by reference across all instances created! By providing a data function, every time a new instance is created we can call it to return a fresh copy of the initial data.
I've got a Vuetify select, with the following syntax.
<v-select label="..." autocomplete
append-icon="search" :items="plots" item-value="id" item-text="plotHeader"
v-model="selectedPlot" v-on:change="loadPlotInformation();">
</v-select>
So when the page loads, the dropdown initializes with an Ajax request. But when the user changes the value, the model reflects the old value, not the current selection.
Inside the function.
loadPlotInformation() {
console.log(this.selectedPlot);
}
Update:
I was able to fix the issue by transitioning to blur event. But why would change event not resolve?
If you want to take new value instead of the old value, you should use nextTick method.
eg:
loadPlotInformation() {
this.$nextTick(() => {
console.log(this.selectedPlot);
})
};
Try to change your function to read the parameter of your function.
loadPlotInformation(e) {
console.log(e);
}
But this way you need to check if you want to update your model variable
How can i close a vuetify's dialog opened without an activator, when the user press the ESC key on the keyboard?
Add #keydown.esc="dialog = false" to v-dialog component
<v-dialog v-model="dialog" #keydown.esc="dialog = false"></v-dialog>
data: () => ({
dialog: false
}),
Working example:
https://codepen.io/anon/pen/BJOOOQ
Additionally, if using dialog as custom component then possibly we need to emit input event:
<template>
<v-dialog :value="value" #keydown.esc="$emit('input')">
...
This is the only way I was able to get it to work
mounted() {
// Close modal with 'esc' key
document.addEventListener("keydown", (e) => {
if (e.keyCode == 27) {
this.$emit('close');
}
});
},
this code maybe can help you
mounted() {
let self = this;
window.addEventListener('keyup', function(event) {
// If ESC key was pressed...
if (event.keyCode === 27) {
// try close your dialog
self.advanced_search = false;
}
});
},
the same principle as adding keypress binding to any vue component should work - add the following code to the v-dialog component :
#keydown.esc="dialog = false"
working example ( note the close button click event handler as well )
https://codepen.io/yordangeorgiev/pen/WBeMGq
While the solutions others have mentioned work, there still are conflicts with the bounce animation, making it not work after playing it by clicking outside the dialog, etc.
Setting the no-click-animation property also fixes the animation when closing as otherwise it plays both the close and bounce animation:
<v-dialog v-model="dialog" #keydown.esc="dialog=false" no-click-animation></v-dialog>
#keydown.esc not working with my project. As far as I see it's good for Vue2 projects.
Working script:
mounted() {
document.addEventListener("keydown", (e) => {
if (e.key === 'Escape') {
this.$emit('close');
// Or any other way you want to close your modal
}
})
}
What you want to use is a Key Modifier. You can use v-on:keyup.esc directive on your dialog to detect if the escape key is detected.
Read this for more information about Key Modifiers