console.log not working when using #submit directive in vuetify - vue.js

When using the #submit directive in Vuetify, console.log is not working in my code. But when I only use #click and then call my function it works. Any idea how to make that work?
This code works:
<v-btn color="primary" text #click="submit">I accept</v-btn>
HTML in template
<v-btn color="primary" text #submit="submit">I accept</v-btn>
Function being called
methods: {
submit() {
console.log.$refs
// Form validation check
if (!this.$refs.invoiceform.validate()) {
console.log("Not good");
} else {
console.log("Data ok");
}
},

Your problem I believe is that v-btn does not have a #submit event so you need to put that on the v-form element if you are using it. Make sure your button is inside the form element and it is of the type submit. Use prevent on the form submit event to prevent it from causing the browser to try to post your form.
<v-form #submit.prevent="submit">
...//some inputs
<v-btn type="submit">I accept</v-btn>
</v-form>

Related

Conditionally add #submit.prevent to a form in Vue.js

I'm trying to conditionally prevent HTML form submission using #submit.prevent. I have a generic form model that looks like this (minimized a bit):
<v-form v-model="valid">
<div>
<div v-for="(field, i) in fieldConfig" :key="`model-form-`+i">
<fe-label v-if="field.label">{{field.label}}</fe-label>
<component
:is="field.component"
v-bind="field.attrs"
v-model="item[field.field]"
/>
</div>
</div>
</v-form>
Called from a parent:
<model-form
idProperty="id"
#done="finishRename"
model="myModel"
:fieldConfig="fieldConfig"
:htmlSubmit="false"
/>
I've seen some similar things in my searching but nothing quite right, and I'm pretty raw when it comes to Vue. Any help is appreciated. Thanks!
Don't use submit.prevent in this scenario. Just use submit, and in your function, conditionally prevent.
onSubmit(e) {
if(condition) e.preventDefault();
}
As Andy pointed out, #submit.prevent should not be used for conditional form submission because the .prevent modifier automatically calls Event.preventDefault().
To conditionally call it, you'd have to remove the .prevent modifier, and evaluate the htmlSubmit flag beforehand within the event handler:
<v-form #submit="onSubmit" action="https://example.com">
export default {
methods: {
onSubmit(e) {
if (!this.htmlSubmit) {
e.preventDefault() // don't perform submit action (i.e., `<form>.action`)
}
}
}
}

How to stop v-click-outside from triggering on internal v-select components

I've been trying to make a card component that closes if you click anywhere on the outside. But the issue is that v-click-outside gets triggered when I click on an item in the v-select dropdown menu inside of that card. How do I prevent child components from triggering v-click-outside?
<v-card v-click-outside="handleClickOutside">
<v-select
:items="items"
v-model="currentItem"
></v-select>
</v-card>
According to v-click-outside documentation, it accepts "A callback or options object.". Object looks like this:
{
handler: (e: Event) => void,
closeConditional ? : (e: Event) => boolean,
include ? : () => HTMLElement[]
}
For handler pass your function and for include you have to specify HTML element (example). To prevent trigger v-click-outside when you are using v-select you need to include .v-select-list.
In your case the solution will look like this:
<v-card v-click-outside="{
handler: handleClickOutside,
include: includeFunction
}">
...
<script>
...
methods: {
includeFunction(){
//visible elements
const tempArray = [document.querySelector('.included')]
if (document.querySelector('.v-select-list')) {
//push the element to array when it is visible
arr.push(document.querySelector('.v-select-list'))
}
return tempArray
}
...
}
</script>

Vuetify open dialog with custom logic

I want to open a dialog on a button click. But i need logic to be executed before and after this event. How can this be done?
What i have tried:
template
<v-dialog v-model="dialog" width="400">
<template v-slot:activator="{ on }">
<v-btn color="primary" #click="openDialog">Dialog</v-btn>
</template>
<v-btn>lol</v-btn>
</v-dialog>
script
data() {
return { dialog: false };
},
methods: {
openDialog() {
this.dialog = true;
}
}
}
This seems like a bad fix because after all the v-slot on is still there.
You don't really need to use v-slot:activator="{on}" in the first example - <v-dialog> tags can be activated without that (as described in the "Without activator" example here).
However, the recommended way for me personally would be the second example you have provided - the one that uses v-on to trigger the dialog, as it handles opening the dialog without writing an extra function to set one of your data variables.

Vue Change icon to click on the button

how can I change the icon when I click on the button in vue.
Here is a portion of the code:
<v-btn flat icon color="white">
<v-icon>star_border</v-icon>
</v-btn>
Thanks
<v-btn #click="show = !show" icon>
<v-icon>{{ !show ? 'mdi-eye' : 'mdi-close' }}</v-icon>
</v-btn>
add to component
{
data(){
return {
show:false
}
}
}
Hi Enzo and congrats on starting your VueJS project.
I would recommend you looking at VueJS documentation about Data and Methods, to give you some start. https://v2.vuejs.org/v2/guide/instance.html#Data-and-Methods
In short Data is where you keep your reactive properties and Methods store your functionality.
Right now the name of the icon is hard-coded. What you want to do is to make it reactive. So to change the icon;.
You need to bind the name of the icon to a property in your data.
Define a method that changes the value of that property.
Make an on-click event to invoke a function.
Something like this:
new Vue({
el: '#app',
data() {
return {
myIcon: 'star_border'
}
},
methods: {
changeIcon() {
this.myIcon = 'home'
}
}
})
Here I've defined a property called myIcon, which is 'star-border' at first. I've also created a method that gets invoked on the click-event of this button. This method changes the value of the myIcon property to 'home'.
You can see a working demo here: https://codepen.io/bergur/pen/MLMxzY

Vue / vuetify focus input after modal is dismissed

On a page I have a Vuetify v-form/v-text-field. Users can type a query in to this form and press Enter to update the page.
Sometimes the query is erroneous and a v-dialog modal pops up to explain the error. It's a complex error and can't just be packed in the rules attribute of the v-text-field.
The problem: when the modal is dismissed, the v-text-field is no longer focused and requires a click before it can be used again. This interrupts the user and requires a shift from keyboard to mouse and back.
What is Vue best practice for re-focusing on the input that triggered the modal?
I can think of one idea it doesn't feel Vue-ish: put a ref on the v-text-field and watch the dialog data property. If dialog becomes false, call this.$refs.input.focus(). However, this seems like the old-fashioned, imperative (not reactive) way to do it. For example:
<template>
<v-form v-model='valid' #submit.prevent='submit'>
<v-text-field
placeholder="Search..."
v-model="query"
:rules="[foo]"
ref='input'
autofocus
></v-text-field>
<v-dialog
v-model="dialog"
#keydown.esc='dialog = false'
>
{{ someErrorMessage }}
</v-dialog>
</v-form>
</template>
// Vue instance
export default {
data: function() {
return {
dialog: false,
query: "",
valid: false
}
},
...
watch: {
// Focus on query after dismissing an error
dialog(newState) {
if (!newState) {
this.$refs.input.focus();
}
}
},
methods: {
foo(value) {
// ... validate value
},
submit(e) {
if (!this.valid) {
this.dialog = true;
return;
}
}
}
}
In the dialog element, I'd probably call a method instead of directly changing dialog to false. Then in that method, I'd add focus to the textarea with some plain old javascript.