Validation reset after form submission - validation

I've got the form with checkboxes and I want the user to select at least one of them. Everything works fine, but after resetting the form I can't hide the validation message.
This case is described exactly in the docs, but the provided solution seems to be invalid because after submitting the form validation errors show up.
<template>
<v-app>
<v-content>
<playground></playground>
<v-card class="mx-auto" outlined>
<ValidationObserver ref="obs" v-slot="{ invalid, valid, validated, passes, reset }">
<v-card-title class="pb-0">Meal types</v-card-title>
<v-row justify="center">
<v-col cols="11">
<v-form ref="form">
<ValidationProvider rules="required" v-slot="{ errors, failedRules }">
<v-container row pa-0>
<v-row justify="space-around">
<v-checkbox
v-model="mealType"
value="BREAKFAST"
label="Breakfast"
hide-details
></v-checkbox>
<v-checkbox v-model="mealType" value="DINNER" label="Dinner" hide-details></v-checkbox>
<v-checkbox v-model="mealType" value="SUPPER" label="Supper" hide-details></v-checkbox>
<v-checkbox v-model="mealType" value="SNACK" label="Snack" hide-details></v-checkbox>
</v-row>
</v-container>
<v-row justify="center">
<v-alert
v-if="failedRules.required"
type="error"
dense
outlined
class="mt-4 mb-0"
>Select at least one meal type</v-alert>
</v-row>
</ValidationProvider>
</v-form>
</v-col>
</v-row>
<v-card-actions>
<v-row justify="center">
<v-btn text color="deep-purple accent-4" #click="passes(addRecipe)">Save</v-btn>
<v-btn #click="reset">Reset</v-btn>
</v-row>
</v-card-actions>
</ValidationObserver>
</v-card>
</v-content>
</v-app>
</template>
<script>
import Playground from "./components/Playground";
export default {
name: "App",
components: {
Playground
},
data() {
return {
recipeName: "",
mealType: []
};
},
methods: {
addRecipe() {
console.log("add recipe");
// after save or reset alerts should disappear..
this.$refs.form.reset();
requestAnimationFrame(() => {
this.$refs.obs.reset();
});
}
}
};
</script>
Code Sandbox with reproduced use case: https://codesandbox.io/s/vee-validate-3-reset-checkbox-validation-qr8uw
Please select some meal types and click save. After clicking the save button, the form is reset and the validation message shows up, but it shouldn't. How to solve this?

Found a workaround, which will help you solving the issue (the original with this.$refs.form.reset()), has to be a bug, and should be reported to VeeValidate for solving.
I found out making the method async, and resetting the variable manually made it all work out.
methods: {
async addRecipe() {
console.log("add recipe");
console.log(this.mealType);
this.mealType = [];
this.$refs.obs.reset();
}
}

Related

Vuetify v-app-bar doesn't shrink smoothly

I faced following problem with v-app-var.
When I scroll down, I expect app bar to shrink smoothly and evenly, but instead it behaves laggy
Here is an example to see it yourself , but screen size must be set to 1440х900 in order to reproduce a problem
https://qx5v2.csb.app/
Here's a video how it looks like
Please help me out.
Just run these commands :
<template>
<v-app>
<v-app-bar
app
class="light-blue"
dark
height="400"
shrink-on-scroll
fade-img-on-scroll
src="https://picsum.photos/1920/1080?random"
>
<template v-slot:img="{ props }">
<v-img
v-bind="props"
gradient="to top right, rgba(100,115,201,.7), rgba(25,32,72,.7)"
></v-img>
</template>
</v-app-bar>
<v-main>
<v-container fluid>
<div>Lorem ipsum.</div>
<div>Officia, quos!</div>
<div>Modi, quas!</div>
<div>Sapiente, fugiat!</div>
<div>Facere, ex.</div>
<div>Alias, quaerat!</div>
<div>Exercitationem, vel.</div>
<div>Eligendi, architecto.</div>
<div>Minima, animi.</div>
<div>Nulla, aspernatur.</div>
<div>Consectetur, aliquid!</div>
<div>Tempore, commodi.</div>
<div>Odit, voluptas!</div>
<div>Excepturi, iste.</div>
<div>Optio, amet.</div>
<div>Eos, laudantium.</div>
<div>Facere, veritatis!</div>
<div>A, architecto!</div>
<div>Ad, tempora.</div>
<div>Optio, expedita.</div>
<div>Quasi, quas.</div>
<div>A, consequatur.</div>
<div>Aperiam, debitis.</div>
<div>Quod, modi.</div>
<div>A, consequatur.</div>
</v-container>
</v-main>
<v-footer app absolute>
<v-container>
<v-row justify="center">
<div class="ma-4">
<v-btn icon>
<v-icon>mdi-magnify</v-icon>
</v-btn>
<v-btn icon>
<v-icon>mdi-facebook</v-icon>
</v-btn>
<v-btn icon>
<v-icon>mdi-instagram</v-icon>
</v-btn>
</div>
</v-row>
</v-container>
</v-footer>
</v-app>
</template>
<script>
export default {
name: 'layout',
components: {}
}
</script>

Why isn't the v-icon displayed inside the v-text-field?

Can you tell me why the icon to the right of the v-text-field is not displayed?
I want to make the calendar open when you click on the icon.
codepen
<div id="app">
<v-app id="inspire">
<v-menu>
<template v-slot:activator="{ on }">
<v-text-field label="Hello world" style="max-width: 200px">
<!--The icon is not displayed-->
<v-icon v-on="on" color="primary" dark>event</v-icon>
</v-text-field>
</template>
<v-date-picker>
</v-date-picker>
</v-menu>
</v-app>
</div>
P.S.
Here is a good example. It's not mine.
Codepen
The HTML input field is empty https://www.w3schools.com/tags/tag_input.asp
There's an attribute to prepend and append icons in textfields in Vuetify: https://vuetifyjs.com/en/components/text-fields/#icons
You simply need to add it:
<v-text-field label="Hello world" style="max-width: 200px" append-icon="event">
I managed to do it. I did this without the activator template.
codepen vuetify
<div id="app">
<v-app id="inspire">
<v-text-field
label="Hello world"
style="max-width: 200px"
append-icon="event"
#click:append="show">
</v-text-field>
<v-menu
v-model="menu"
:position-x="x"
:position-y="y"
absolute >
<v-date-picker />
</v-menu>
</v-app>
</div>
show (e) {
console.log(123);
e.preventDefault();
this.menu = false;
this.x = e.clientX;
this.y = e.clientY;
this.$nextTick(() => {
this.menu = true
})
},

v-combobox can't listed the items

Currently have 2 v-combobox within this vue component, but one is working properly but the second one doesn't. Here's the code,
CreateProd.vue:
<Template>
<v-app>
<v-row>
<v-col cols="6">
<v-combobox :items="items"></v-combobox>
</v-col>
</v-row>
<v-row>
<v-col cols="6">
<v-combobox :operatingSystem="operatingSystem"></v-combobox>
</v-col>
</v-row>
</v-app>
</Template>
<script>
export default {
data() {
return {
items: [
'Mobiles & Tablets > Smartphones',
'Mobiles & Tablets > Tablets',
'Mobiles & Tablets > Landline Phones',
'Mobiles & Tablets > Feature Phones'
],
operatingSystem: [
'Windows',
'Linux',
'Windows XP Professional'
],
}
},
}
</script>
The problem is when I click the second combobox, it won't list down the items that created inside the operatingSystems. Plz Help, Thanks.
You have used the wrong props in your second Combobox. It should be :items and not :operatingSystem.
WRONG
<v-combobox :operatingSystem="operatingSystem"></v-combobox>
RIGHT
<v-combobox :items="operatingSystem"></v-combobox>

How can you use a v-text-field inside of a v-tooltip?

I want to have a v-text-field inside of a v-tooltip so when a user is shown a tooltip they can enter information inside of the tooltip, but no clicks or input seem to register for the elements inside of the tooltip
<v-tooltip top :open-on-click="true" :open-on-hover="false">
<template v-slot:activator="{ on }">
<v-list-item-content v-on="on">
<v-list-item-title>Title</v-list-item-title>
<v-list-item-subtitle>Subtitle</v-list-item-subtitle>
</v-list-item-content>
</template>
<v-text-field></v-text-field>
</v-tooltip>
Actually tool-tips are used only for show some tips, so the all pointer events will be blocked by css pointer-events: none;, We need to override this style with our CSS.
see my working example here
Template
<v-tooltip v-model="show" top>
<template v-slot:activator="{ on }">
<v-btn icon v-on="on">
<v-icon color="grey lighten-1">mdi-cart</v-icon>
</v-btn>
</template>
<span>Programmatic tooltip</span>
<v-text-field
label="Regular"
></v-text-field>
</v-tooltip>
CSS
.v-tooltip__content{
pointer-events: all;
}
The v-tooltip shows a disabled item when you hover, and the addition of events to this item will not work. You can achieve a similar effect v-menu.
<v-menu bottom right
:close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-list-item-content v-on="on">
<v-list-item-title>Title</v-list-item-title>
<v-list-item-subtitle>Subtitle</v-list-item-subtitle>
</v-list-item-content>
</template>
<v-card class="pa-3">
<v-text-field hide-details v-model="textVal" #change="update"></v-text-field>
</v-card>
</v-menu>
methods: {
update(){
console.log(this.textVal)
}
}

Handsontable not immediately shown when inside Vuetify Stepper

When placing the Handsontable HotTable component inside of a Vuetify Stepper the Handsontable is only visible after you click somewhere on the page. But if I place the HotTable component outside of the Stepper it would be shown immediately. It should be visible inside step 1 immediately.
To demonstrate this unexpected behavior I forked the Vuetify Stepper example on CodePen and added "handsontable" and "#handsontable/vue".
Vuetify Stepper with Handsontable on CodePen
<div id="app">
<v-app id="inspire">
<v-stepper v-model="e1">
<v-stepper-header>
<v-stepper-step :complete="e1 > 1" step="1">Name of step 1</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step :complete="e1 > 2" step="2">Name of step 2</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step step="3">Name of step 3</v-stepper-step>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<v-card
class="mb-5"
color="grey lighten-1"
height="200px"
>
<div id="hot-preview">
<hot-table :settings="hotSettings"></hot-table>
</div>
</v-card>
<v-btn
color="primary"
#click="e1 = 2"
>
Continue
</v-btn>
<v-btn flat>Cancel</v-btn>
</v-stepper-content>
<v-stepper-content step="2">
<v-card
class="mb-5"
color="grey lighten-1"
height="200px"
></v-card>
<v-btn
color="primary"
#click="e1 = 3"
>
Continue
</v-btn>
<v-btn flat>Cancel</v-btn>
</v-stepper-content>
<v-stepper-content step="3">
<v-card
class="mb-5"
color="grey lighten-1"
height="200px"
></v-card>
<v-btn
color="primary"
#click="e1 = 1"
>
Continue
</v-btn>
<v-btn flat>Cancel</v-btn>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
</v-app>
</div>
new Vue({
el: '#app',
data () {
return {
e1: 0,
hotSettings: {
data: Handsontable.helper.createEmptySpreadsheetData(1, 8),
colHeaders: true,
rowHeaders: true
}
}
},
components: {
HotTable
}
});
I think the problem is because you initialize it before component is mounted.
Try to initialize it in mounted hook:
hotSettings: {
data: null,
//...
mounted() {
this.hotSettings.data = Handsontable.helper.createEmptySpreadsheetData(1, 8)
}

Resources