Added validation to address-lookup

This commit is contained in:
Leah Schumann 2022-03-21 10:39:35 -04:00
parent 8bd0df4917
commit b769f95d56
7 changed files with 162 additions and 41 deletions

View file

@ -8,14 +8,16 @@
:aria-disabled="isDisabled"
:disabled="isDisabled"
:aria-required="isRequired"
:validationRules="validationRules" >
:validationRules="validationRules"
@input="handleChange"
@blur="handleBlur" >
<option v-for="(value, name, index) in options" :value="name" :key="index">
{{ value }}
</option>
</select>
<p class="mt-2 form-test-error" v-if="!suppressError">
There has been an error!
</p>
<div v-show="errorMessage" class="row mt-2 form-test-error">
<span role="alert">{{ errorMessage }}</span>
</div>
</div>
</template>
@ -36,10 +38,30 @@ export default {
disableAutoFill: Boolean,
validationRules: String,
},
setup(props) {
const fieldOptions = {
type: "text",
value: props.modelValue,
};
const {
errorMessage,
handleBlur,
handleChange,
meta,
} = useField(props.inputId, props.validationRules, fieldOptions);
return {
errorMessage,
handleBlur,
handleChange,
meta,
};
},
data() {
return {
labelText: "",
ariaLabelText: "",
labelText: "",
ariaLabelText: "",
}
},
methods: {
@ -65,6 +87,11 @@ export default {
}
},
},
watch: {
selectedOption(newValue) {
this.handleChange(newValue);
}
}
};
</script>

View file

@ -14,15 +14,19 @@
:aria-required="isRequired"
autocomplete="off"
:class="[hasIcon ? 'has-icon' : '', iconRight ? 'icon-right' : '']"
:validationRules="validationRules" />
<p class="mt-2 form-test-error" v-if="!suppressError">
There has been an error!
</p>
:validationRules="validationRules"
@input="handleChange"
@blur="handleBlur" />
<div v-show="errorMessage" class="row mt-2 form-test-error">
<span role="alert">{{ errorMessage }}</span>
</div>
</div>
</template>
<script>
import { useField } from "vee-validate";
export default {
name: "textbox-question",
props: {
@ -48,6 +52,35 @@ export default {
},
validationRules: String,
},
setup(props) {
const fieldOptions = {
type: "text",
value: props.modelValue, // EX: "Single" or "Passenger"
//potentialInitialValue: props.selectedValues,
};
// Set initialValue for validation setup if pre-selected
// NOTE: props.selectedValues could be an array of strings, or an array of integers...
//if (props.selectedValues && (props.selectedValues.includes(props.value) || props.selectedValues.includes(parseInt(props.value)))) {
//fieldOptions['initialValue'] = fieldOptions.potentialInitialValue;
//}
const {
errorMessage,
handleBlur,
handleChange,
meta,
validate
} = useField(props.inputId, props.validationRules, fieldOptions);
return {
errorMessage,
handleBlur,
handleChange,
validate,
meta,
};
},
data() {
return {
labelText: "",
@ -56,27 +89,32 @@ export default {
},
methods: {
initializeComponent(cmsContent){
var labelText = cmsContent;
if (this.disableAutoFill) {
var noBreakChar = "&NoBreak;";
var position = 1;
labelText = [labelText.slice(0, position), noBreakChar, labelText.slice(position)].join('');
}
var labelText = cmsContent;
if (this.disableAutoFill) {
var noBreakChar = "&NoBreak;";
var position = 1;
labelText = [labelText.slice(0, position), noBreakChar, labelText.slice(position)].join('');
}
this.labelText = labelText;
this.ariaLabelText = cmsContent;
}
this.labelText = labelText;
this.ariaLabelText = cmsContent;
},
},
computed: {
value: {
get: function() {
return this.modelValue;
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
get: function() {
return this.modelValue;
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
},
},
watch: {
value(newValue) {
this.handleChange(newValue);
}
}
};
</script>

View file

@ -14,6 +14,7 @@ const errorMessages = {
FIRST_NAME_REQUIRED: "Please enter your first name",
LAST_NAME_REQUIRED: "Please enter your last name",
EMAIL_ADDRESS_REQUIRED: "Please enter your email address",
EMAIL_ADDRESS_FORMAT: "Please enter a valid email address",
};
export { errorMessages };

View file

@ -5,4 +5,21 @@ export function required(errorMessage) {
}
return true;
};
}
export function regex(expression, errorMessage) {
return (value) => {
// Field is empty, should pass
if (!value || !value.length) {
return true;
}
// Check if email
if (!expression.test(value)) {
return errorMessage;
}
return true;
}
}

View file

@ -1,13 +1,21 @@
<template>
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall">
<funnelHeader ref="funnelHeader" />
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
<funnelSubHeader ref="funnelSubHeader" />
<form autocomplete="off">
<Form
@submit="onSubmit"
@invalid-submit="onInvalidSubmit"
ref="theForm"
v-slot="{ meta }"
autocomplete="off" >
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall">
<funnelHeader ref="funnelHeader" />
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
<funnelSubHeader ref="funnelSubHeader" />
<customerQuestions ref="customerQuestions" v-model="customerQuestions" />
<funnelFooter ref="funnelFooter" />
</form>
</div>
<funnel-footer
ref="funnelFooter"
:isDisabled="!meta.valid"
/>
</div>
</Form>
</template>
<script>
@ -18,6 +26,7 @@ import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import customerQuestions from "@/layouts/address-lookup/customer-questions/customer-questions";
import { Form } from "vee-validate";
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
@ -101,6 +110,7 @@ export default {
vehicleBanner,
funnelSubHeader,
customerQuestions,
Form
},
};
</script>

View file

@ -1,22 +1,22 @@
<template>
<div class="row my-4">
<div class="col">
<textboxQuestion v-model="addressModel.streetAddress" ref="autocomplete" inputId="autocomplete" placeholderText="Search" aria-haspopup="" hasIcon disableAutoFill />
<textboxQuestion v-model="addressModel.streetAddress" ref="autocomplete" inputId="autocomplete" placeholderText="Search" aria-haspopup="" hasIcon disableAutoFill validationRules="street-address-required" />
</div>
</div>
<transition name="fade" mode="out-in">
<div class="address-fields" v-show="showAddressFields" aria-live="polite">
<div class="row my-4">
<div class="col">
<textboxQuestion v-model="addressModel.city" ref="city" inputId="cbf28188fdf2436688fd735915f7ee56" disableAutoFill />
<textboxQuestion v-model="addressModel.city" ref="city" inputId="cbf28188fdf2436688fd735915f7ee56" disableAutoFill validationRules="city-required"/>
</div>
</div>
<div class="row my-4">
<div class="col-6">
<dropdownQuestion v-model="addressModel.state" ref="state" inputId="8fdf9dc2e13e430eb57529499dceb3eb" :options="stateOptions" disableAutoFill />
<dropdownQuestion v-model="addressModel.state" ref="state" inputId="8fdf9dc2e13e430eb57529499dceb3eb" :options="stateOptions" disableAutoFill validationRules="state-required" />
</div>
<div class="col-6">
<textboxQuestion v-model="addressModel.zip" ref="zip" inputId="01a9a1c2de0b4c9da8e023c9ae3be498" mask="#####" disableAutoFill />
<textboxQuestion v-model="addressModel.zip" ref="zip" inputId="01a9a1c2de0b4c9da8e023c9ae3be498" mask="#####" disableAutoFill validationRules="zip-required"/>
</div>
</div>
</div>
@ -36,13 +36,23 @@
</template>
<script>
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
import dropdownQuestion from "@/common-components/dropdown-question/dropdown-question";
import alert from "@/ux-components/alert/alert";
import { applicationConfig } from "@/constants/application-config.js";
import { computed } from 'vue';
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
//import store from "@/store";
// DEFINE VALIDATION RULES
defineRule("street-address-required", required(errorMessages.STREET_ADDRESS_REQUIRED));
defineRule("city-required", required(errorMessages.CITY_REQUIRED));
defineRule("state-required", required(errorMessages.STATE_REQUIRED));
defineRule("zip-required", required(errorMessages.ZIP_REQUIRED));
export default ({
name: "address-questions",
emits: ['update:modelValue'], // The component emits an event
@ -59,12 +69,16 @@ export default ({
validationRules: String,
},
setup(props, { emit }) {
// Please do not modify, this "computed" is used to track and report
// this object's property changes to the parent component
const addressModel = computed({ // Use computed to wrap the object
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value),
});
return { addressModel };
return {
addressModel,
};
},
data() {
return {
@ -236,6 +250,8 @@ export default ({
}
}
self.displayVerificationWarning = false;
self.displayNoMatchWarning = false;
}

View file

@ -2,17 +2,17 @@
<addressQuestions ref="addressQuestions" v-model="customerModel.addressQuestions" />
<div class="row my-4">
<div class="col">
<textboxQuestion v-model="customerModel.firstName" ref="firstName" inputId="08497a2efd9a4a73a70360ab47b4838d" disableAutoFill />
<textboxQuestion v-model="customerModel.firstName" ref="firstName" inputId="08497a2efd9a4a73a70360ab47b4838d" disableAutoFill validationRules="first-name-required" />
</div>
</div>
<div class="row my-4">
<div class="col">
<textboxQuestion v-model="customerModel.lastName" ref="lastName" inputId="0030e56a57e74a4ab92de7fb8e97fec5" disableAutoFill />
<textboxQuestion v-model="customerModel.lastName" ref="lastName" inputId="0030e56a57e74a4ab92de7fb8e97fec5" disableAutoFill validationRules="last-name-required" />
</div>
</div>
<div class="row my-4">
<div class="col">
<textboxQuestion v-model="customerModel.emailAddress" ref="emailAddress" inputId="00450a91b8964a768ce3992e6feb890f" disableAutoFill />
<textboxQuestion v-model="customerModel.emailAddress" ref="emailAddress" inputId="00450a91b8964a768ce3992e6feb890f" disableAutoFill validationRules="email-address-required|email-address-format"/>
</div>
</div>
</template>
@ -21,8 +21,20 @@
import addressQuestions from "@/layouts/address-lookup/customer-questions/address-questions/address-questions";
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
import { computed } from 'vue';
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { regex } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
//import store from "@/store";
// DEFINE VALIDATION RULES
defineRule("first-name-required", required(errorMessages.FIRST_NAME_REQUIRED));
defineRule("last-name-required", required(errorMessages.LAST_NAME_REQUIRED));
defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule("email-address-format", regex(/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+).([a-zA-Z]{2,4})$/, errorMessages.EMAIL_ADDRESS_FORMAT));
//EMAIL_ADDRESS_FORMAT
export default ({
name: "customer-questions",
emits: ['update:modelValue'], // The component emits an event