'Enable button when conditions are true in VueJS 3
I am currently working on a form and are having some problems to enable a button when conditions are filled.
Currently i created a form that contains inputs to fill a name, a phonenumber, some options and a message. When the conditions are filled i want to enable the button i already disabled.
Does anyone have some tips on who i can enable the button again to submit the form?
<template>
<div class="contact">
<h1>Vi uppskattar alla frågor som du har angående denna applikation!</h1>
<h2> Vänligen skriv ett meddelande här nedan så ska vi göra allt vi kan för att svara så snart som möjligt!</h2>
</div>
<form @submit.prevent="submitForm">
<div class="form-control" :class="{invalid: fullNameValidation === 'invalid'}">
<label for="name">Namn</label>
<input id="name" name="name" type="text" v-model="fullName" @blur="validateInput">
<p v-if="fullNameValidation === 'invalid'">Vänligen fyll i ett namn</p>
</div>
<div class="form-control" :class="{invalid: phoneValidation === 'invalid'}">
<label for="phone">Telefonnummer</label>
<input id="phone" name="phone" type="number" v-model="phoneNr" @blur="validatePhone" pattern="[0-9]*">
<p v-if="phoneValidation === 'invalid'">Vänligen fyll i ett giltigt telefonnummer</p>
</div>
<div class="form-control">
<label for="referrer">Hur fick du kännedom av denna applikation?</label>
<select id="referrer" name="referrer" v-model="referrer">
<option value="" disabled hidden>Välj ett alternativ</option>
<option value="internet">Internet</option>
<option value="friends">Vänner</option>
<option value="newspaper">Nyhetstidningar</option>
<option value="other">Annat</option>
</select>
</div>
<div class="form-control" :class="{invalid: messageValidation === 'invalid'}">
<label for="message">Meddelande</label>
<textarea name="message" id="message" cols="30" rows="10" v-model="message" @blur="validateMessage"></textarea>
<p v-if="messageValidation === 'invalid'">Vänligen fyll i ditt meddelande</p>
</div>
<div>
<button v-on:click="$router.push('thankyou')" :disabled="!isComplete" id="myBtn">Skicka meddelande</button>
</div>
</form>
</template>
<script>
export default {
data() {
return {
fullName: '',
fullNameValidation: 'pending',
phoneNr: 'null',
phoneValidation: 'pending',
referrer: '',
messageValidation: 'pending'
}
},
methods: {
submitForm() {
this.fullName = '';
},
validateInput() {
if (this.fullName === '') {
this.fullNameValidation = 'valid'
} else {
this.fullNameValidation = 'invalid'
}
},
validatePhone() {
if (this.phoneNr > 10) {
this.phoneValidation = 'valid'
} else {
this.phoneValidation = 'invalid'
}
},
validateMessage() {
if (this.messageValidation > 1) {
this.messageValidation = 'valid'
} else {
this.messageValidation = 'invalid'
}
},
computed: {
isComplete() {
return Object.values(this.fields).every(({valid}) => valid)
}
}
}
}
</script>
Solution 1:[1]
Consolidate your form fields into a single model, along with the errors object.
Then use Object.keys to grab known field keys to do validation on.
export default {
data() {
return {
form: {
errors: {},
values: {
fullName: '',
phoneNr: '',
referrer: '',
}
}
}
},
methods: {
validate(field) {
let fields = []
// single field
if (field) {
delete this.form.errors[field]
fields.push(field)
} else {
this.form.errors = {}
// all fields
fields = Object.keys(this.form.values)
}
if (fields.includes('fullName')) {
if (this.form.values.fullName === '') {
this.form.errors.fullName = 'Enter your full name'
} else if (this.fullName !== some other validation) {
...
}
}
if (fields.includes('phoneNr')) {
if (this.form.values.phoneNr === '') {
this.form.errors.phoneNr = 'Enter your phone number'
}
}
if (fields.includes('referrer')) {
if (this.form.values.referrer === '') {
this.form.errors.referrer = 'Enter referrer'
}
}
// if errors is empty return true
return !Object.keys(this.form.errors).length
},
submit() {
// validate all
if (this.validate()) {
// do some thing, form is valid, if native form handler, return true/false
}
}
}
}
<div class="form-control" :class="{invalid: form.errors.fullName}">
<label for="name">Namn</label>
<input id="name" type="text" v-model="fullName" @blur="validate('fullName')">
<p v-if="form.errors.fullName">{{ form.errors.fullName }}</p>
</div>
If you don't specifically need the @blur validation, it simplifies things quite abit and its pretty standard to do validation on submit rather then on blur of individual fields.
export default {
data() {
return {
form: {
errors: {},
values: {
fullName: '',
phoneNr: '',
referrer: '',
}
}
}
},
methods: {
validate() {
this.form.errors = {}
if (this.form.values.fullName === '') {
this.form.errors.fullName = 'Enter your full name'
} else if (this.form.values.fullName !== some other validation) {
...
}
if (this.form.values.phoneNr === '') {
this.form.errors.phoneNr = 'Enter your phone number'
}
if (this.form.values.referrer === '') {
this.form.errors.referrer = 'Enter referrer'
}
// if errors is empty return true
return !Object.keys(this.form.errors).length
},
submit() {
if (this.validate()) {
// do something, form is valid, if native form handler, return true/false
}
}
}
}
<div class="form-control" :class="{invalid: form.errors.fullName}">
<label for="name">Namn</label>
<input id="name" type="text" v-model="fullName">
<p v-if="form.errors.fullName">{{ form.errors.fullName }}</p>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Lawrence Cherone |
