diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 66c36158..0281b740 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -27,13 +27,14 @@ import { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; +import BaseFormMixin from '@/mixins/base-form-mixin.js'; // DEFINE VALIDATION RULES defineRule("questions-required", required(errorMessages.OPTION_REQUIRED)); export default { name: "part-questions", - mixins: [vehicleQuestionsMixin], + mixins: [BaseFormMixin, vehicleQuestionsMixin], async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 4988285e..0683869b 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -68,6 +68,7 @@ import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-que import alert from "@/ux-components/alert/alert"; // Supporting files +import BaseFormMixin from '@/mixins/base-form-mixin.js'; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; import { Form, defineRule } from "vee-validate"; @@ -82,6 +83,7 @@ defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_RE export default { name: "vehicle-damage", + mixins: [BaseFormMixin], async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); @@ -129,7 +131,7 @@ export default { selectedRearReplaceOptions: this.getRearReplaceOptionsFromStore(), }; }, - methods: { + methods: { arePagePrerequisitesValid() { if (this.mainStore.order.vehicle.carId) { return true; @@ -297,7 +299,7 @@ export default { return this.navigateForward(); }, - navigateForward() { + navigateForward() { // If vin already exists, navigate directly to vin-lookup if (useMainStore().order.vehicle.vin) { this.$router.navigate( diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index b734f58a..bd5a6be0 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -57,10 +57,11 @@ import { settleAllPromises } from "@/helpers/layout-helper"; import { issPageValues } from "@/router/router-constants/issPage-values"; import { Form } from "vee-validate"; import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; +import BaseFormMixin from '@/mixins/base-form-mixin.js'; export default { name: "vehicle-parts", - mixins: [vehicleQuestionsMixin], + mixins: [BaseFormMixin, vehicleQuestionsMixin], async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); diff --git a/src/mixins/base-form-mixin.js b/src/mixins/base-form-mixin.js new file mode 100644 index 00000000..081183be --- /dev/null +++ b/src/mixins/base-form-mixin.js @@ -0,0 +1,25 @@ +export default { + methods: { + onSubmit() { + /** DO NOT REMOVE; + * Needed to prevent default form submit behavior. + * Cannot use .prevent modifier for vee-validate Form. + */ + }, + onInvalidSubmit({ errors }) { + /** + * Identify the first error field and put focus on it + * get error names array + */ + const errorNames = errors ? Object.keys(errors) : []; + const firstErrorEl = errorNames[0]; + if (firstErrorEl) { + const qsString = `[data-focus-target="${firstErrorEl}"]`; + const el = document.querySelector(qsString); + if (el !== null) { + el.focus(); + } + } + }, + }, +};