Within my application, I have implemented custom validation and validators to ensure the accuracy of various form fields. The submit button functionality is designed to remain disabled until all input fields are filled.
The creation of validators involves defining rules as shown below:
// validator.js
export default function validators() {
const isEmpty = (fieldName, fieldValue) => (!fieldValue ? `The ${fieldName} field cannot be empty` : '');
const minLength = (fieldName, fieldValue, min) => (fieldValue.length < min ? `The ${fieldName} must contain at least ${min} characters` : '');
return {
isEmpty,
minLength,
};
}
These validators are then incorporated into the validation logic for various input types such as text areas and emails, as illustrated in the example below:
// formValidationimport { reactive } from 'vue';
import Validators from './validators';
const errors = reactive({});
const {
minLength, isEmpty
} = Validators();
export default function formValidation() {
const validateInputField = (fieldName, fieldValue) => {
errors[fieldName] = !fieldValue
? isEmpty(fieldName, fieldValue) : minLength(fieldName, fieldValue, 2);
};
return {
errors,
validateInputField,
};
}
Furthermore, a custom button validation state has been created using a computed property:
Button State
import { computed } from 'vue';
export default function submitButtonState(field, errors) {
const isButtonDisabled = computed(() => {
let disabled = true;
for (const prop in field) {
if (Object.hasOwn(field, prop)) {
if (!field[prop] || errors[prop]) {
disabled = true;
break;
}
disabled = false;
}
}
return disabled;
});
return {
isButtonDisabled,
};
}
In my component, I am utilizing pinia store to store all input variables. While input storage functions correctly, the button state always remains disabled and fails to update accordingly.
Below is the code snippet of the component:
<template>
<div>
<span>Form Description</span>
<p>
<my-textarea
:message-type="errors.address ? 'negative' : ''"
:validation-message ="errors.address"
max-length="100"
>
<textarea
v-model="formResponses.txtArea1"
@blur="validate1stInput"
@keypress="validate1stInput"
slot="textarea"
maxlength="100"
></textarea>
<label slot="label" for="textarea">Address</label>
</my-textarea>
</p>
<p>
<my-textarea
:message-type="errors.comments? 'negative' : ''"
:validation-message ="errors.comments"
max-length="100"
>
<textarea
v-model="formResponses.txtArea2"
@blur="validate1stInput2"
@keypress="validate1stInput2"
slot="textarea"
maxlength="100"
></textarea>
<label slot="label" for="textarea">Comments</label>
</my-textarea>
</p>
<p><button class="myButton" @click.prevent="submit" :disabled="isButtonDisabled"></button></p>
</div>
</template>
<script setup>
import UserStore from '@/store/userStore';
import FormValidation from '@/utilities/useFormValidation';
import SubmitButtonState from '@/utilities/SubmitButtonState';
import { ref, reactive, watch } from 'vue';
import { storeToRefs } from 'pinia';
const { form1 } = storeToRefs(UserStore());
const formResponses = reactive({ ...form1.value });
const { validateInputField, errors } = FormValidation();
const { isButtonDisabled } = SubmitButtonState(formResponses, errors);
const validate1stInput = () => {
validateInputField('address', formResponses.txtArea1);
};
const validate1stInput2 = () => {
validateInputField('comments', formResponses.txtArea2);
};
watch(() => errors, { immediate: true });
</script>
The current issue lies in the button state not updating due to the error states not being updated. This poses a challenge when dealing with multiple inputs. To address this, it's essential to debug and identify the root cause of the disabled button state persisting even after correct input values are provided.
For reference, you can access the working codesandbox here: