Merged from CSR-1088 and made changes needed to support validation within the modal
This commit is contained in:
commit
d606bb6b72
7 changed files with 134 additions and 42 deletions
|
|
@ -32,7 +32,8 @@
|
||||||
ref="buttonMain"
|
ref="buttonMain"
|
||||||
loaderColor="white"
|
loaderColor="white"
|
||||||
:buttonText="footerButtonText"
|
:buttonText="footerButtonText"
|
||||||
@click-event="validateAndEmit" />
|
@click-event="validateAndEmit"
|
||||||
|
:class="isFooterButtonDisabled && 'form-test-invalid'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -42,16 +43,13 @@
|
||||||
<script>
|
<script>
|
||||||
import buttonMain from "@/ux-components/button-main/button-main";
|
import buttonMain from "@/ux-components/button-main/button-main";
|
||||||
import { Modal } from "bootstrap";
|
import { Modal } from "bootstrap";
|
||||||
import { checkPropertyChange } from "json-schema";
|
import { useIsFormTouched, useIsFormDirty, useIsFormValid } from "vee-validate";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "modal",
|
name: "modal",
|
||||||
props: {
|
props: {
|
||||||
headerText: String,
|
headerText: String,
|
||||||
footerButtonText: String,
|
footerButtonText: String,
|
||||||
modalForm: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
onModalOpenedCallback: {
|
onModalOpenedCallback: {
|
||||||
type: Function,
|
type: Function,
|
||||||
},
|
},
|
||||||
|
|
@ -59,21 +57,22 @@ export default {
|
||||||
setup() {
|
setup() {
|
||||||
const modalId = `modal-${crypto.randomUUID()}`;
|
const modalId = `modal-${crypto.randomUUID()}`;
|
||||||
|
|
||||||
|
const isTouched = useIsFormTouched();
|
||||||
|
const isDirty = useIsFormDirty();
|
||||||
|
const isValid = useIsFormValid();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
modalId,
|
modalId,
|
||||||
|
isTouched,
|
||||||
|
isDirty,
|
||||||
|
isValid,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async validateAndEmit() {
|
async validateAndEmit() {
|
||||||
if (this.modalForm) {
|
if (!this.isFooterButtonDisabled) {
|
||||||
const validationResult = await this.modalForm.validate();
|
|
||||||
if (validationResult.valid) {
|
|
||||||
this.$emit("footer-button-event");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.$emit("footer-button-event");
|
this.$emit("footer-button-event");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.resetButtonStyle();
|
this.resetButtonStyle();
|
||||||
},
|
},
|
||||||
resetButtonStyle() {
|
resetButtonStyle() {
|
||||||
|
|
@ -88,6 +87,14 @@ export default {
|
||||||
modal.hide();
|
modal.hide();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
isFooterButtonDisabled() {
|
||||||
|
if (!this.isTouched) {
|
||||||
|
return !this.isValid;
|
||||||
|
}
|
||||||
|
return !this.isDirty || !this.isValid;
|
||||||
|
},
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
buttonMain,
|
buttonMain,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
cornerStyle === 'rounded' ? 'rounded-pill' : '',
|
cornerStyle === 'rounded' ? 'rounded-pill' : '',
|
||||||
]"
|
]"
|
||||||
:validationRules="validationRules"
|
:validationRules="validationRules"
|
||||||
|
@input="handleChange"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
@blur="handleChange"
|
@blur="handleChange"
|
||||||
:maxlength="maxLength ? maxLength : '999'"
|
:maxlength="maxLength ? maxLength : '999'"
|
||||||
|
|
|
||||||
|
|
@ -45,25 +45,12 @@ import vehicleProtectedQuestion from "@/layouts/service-location/mobile-location
|
||||||
import textBlock from "@/digital-components/text-block/text-block";
|
import textBlock from "@/digital-components/text-block/text-block";
|
||||||
|
|
||||||
// Supporting Files
|
// Supporting Files
|
||||||
import { useForm } from "vee-validate";
|
|
||||||
|
|
||||||
// Define Validation Rules
|
// Define Validation Rules
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "mobile-location-modal-questions",
|
name: "mobile-location-modal-questions",
|
||||||
emits: ["update:modelValue"], // The component emits an event
|
emits: ["update:modelValue"], // The component emits an event
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
answers: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const modalForm = useForm();
|
|
||||||
|
|
||||||
return {
|
|
||||||
modalForm,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
@ -75,11 +62,12 @@ export default {
|
||||||
state: "",
|
state: "",
|
||||||
zipCode: "",
|
zipCode: "",
|
||||||
},
|
},
|
||||||
|
isVehicleProtected: Boolean,
|
||||||
isZipServiceableMobile: Boolean,
|
isZipServiceableMobile: Boolean,
|
||||||
isZipServiceableInShop: Boolean,
|
isZipServiceableInShop: Boolean,
|
||||||
isVehicleProtected: Boolean,
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
serviceZipCode: String,
|
||||||
linkWidgetName: String,
|
linkWidgetName: String,
|
||||||
modalWidgetName: String,
|
modalWidgetName: String,
|
||||||
mobileFeeDisclaimerWidgetName: String,
|
mobileFeeDisclaimerWidgetName: String,
|
||||||
|
|
@ -88,10 +76,21 @@ export default {
|
||||||
alertInvalidZipWidgetName: String,
|
alertInvalidZipWidgetName: String,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
getModalId() {
|
||||||
|
return "#" + this.modalWidgetName;
|
||||||
|
},
|
||||||
mobileLocationLinkPromptText() {
|
mobileLocationLinkPromptText() {
|
||||||
return this.getCmsContent(this.linkWidgetName, "HeaderText");
|
return this.getCmsContent(this.linkWidgetName, "HeaderText");
|
||||||
},
|
},
|
||||||
mobileLocationLinkText() {
|
mobileLocationLinkText() {
|
||||||
|
if (
|
||||||
|
this.addressModel.streetAddress != "" &&
|
||||||
|
this.addressModel.city != "" &&
|
||||||
|
this.addressModel.state != "" &&
|
||||||
|
this.addressModel.zipCode != ""
|
||||||
|
) {
|
||||||
|
return `${this.addressModel.streetAddress}\n${this.addressModel.city}, ${this.addressModel.state} ${this.addressModel.zipCode}`;
|
||||||
|
}
|
||||||
return this.getCmsContent(this.linkWidgetName, "BodyText");
|
return this.getCmsContent(this.linkWidgetName, "BodyText");
|
||||||
},
|
},
|
||||||
modalHeaderText() {
|
modalHeaderText() {
|
||||||
|
|
@ -111,6 +110,19 @@ export default {
|
||||||
this.$emit("update:modelValue", newValue);
|
this.$emit("update:modelValue", newValue);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
addressModel: {
|
||||||
|
get: function () {
|
||||||
|
return this.mobileLocationQuestionModel.addressQuestions;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_isVehicleProtected: {
|
||||||
|
get: function () {
|
||||||
|
return this.modelValue.isVehicleProtected;
|
||||||
|
},
|
||||||
|
set: function (newValue) {
|
||||||
|
this.$emit("update:modelValue.isVehicleProtected", newValue);
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openModal() {
|
openModal() {
|
||||||
|
|
@ -119,10 +131,29 @@ export default {
|
||||||
closeModal() {
|
closeModal() {
|
||||||
this.$refs[this.modalName].closeModal();
|
this.$refs[this.modalName].closeModal();
|
||||||
},
|
},
|
||||||
|
resetModel() {
|
||||||
|
// Address
|
||||||
|
this.addressModel.streetAddress = "";
|
||||||
|
this.addressModel.apartmentNumberOrBusinessName = "";
|
||||||
|
this.addressModel.city = "";
|
||||||
|
this.addressModel.state = "";
|
||||||
|
this.addressModel.zipCode = "";
|
||||||
|
|
||||||
|
// Is Vehicle Protected
|
||||||
|
this._isVehicleProtected = null;
|
||||||
|
},
|
||||||
async setMobileLocation() {
|
async setMobileLocation() {
|
||||||
this.closeModal();
|
this.closeModal();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
serviceZipCode: {
|
||||||
|
handler() {
|
||||||
|
// if they modify the Service Zip Code, clear the model
|
||||||
|
this.resetModel();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
textLink,
|
textLink,
|
||||||
modal,
|
modal,
|
||||||
|
|
@ -148,4 +179,8 @@ export default {
|
||||||
.address-questions {
|
.address-questions {
|
||||||
margin-top: 0em;
|
margin-top: 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#mobileLocationLinkPromptId {
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||||
export default {
|
export default {
|
||||||
name: "vehicle-protected-question",
|
name: "vehicle-protected-question",
|
||||||
props: {
|
props: {
|
||||||
modelValue: String,
|
modelValue: {
|
||||||
|
isVehicleProtected: Boolean,
|
||||||
|
},
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
fmg
|
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
|
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
|
|
@ -12,6 +11,7 @@ fmg
|
||||||
alertInvalidZipWidgetName="AlertInvalidZipWidget" />
|
alertInvalidZipWidgetName="AlertInvalidZipWidget" />
|
||||||
<mobileLocationModalQuestions
|
<mobileLocationModalQuestions
|
||||||
v-model="mobileLocationQuestions"
|
v-model="mobileLocationQuestions"
|
||||||
|
:serviceZipCode="serviceZipQuestion.serviceZipCode"
|
||||||
linkWidgetName="MobileLocationLinkWidget"
|
linkWidgetName="MobileLocationLinkWidget"
|
||||||
modalWidgetName="MobileLocationModalWidget"
|
modalWidgetName="MobileLocationModalWidget"
|
||||||
mobileFeeDisclaimerWidgetName="MobileFeeDisclaimerWidget"
|
mobileFeeDisclaimerWidgetName="MobileFeeDisclaimerWidget"
|
||||||
|
|
@ -55,6 +55,9 @@ export default {
|
||||||
state: "",
|
state: "",
|
||||||
zipCode: "",
|
zipCode: "",
|
||||||
},
|
},
|
||||||
|
isVehicleProtected: null,
|
||||||
|
isZipServiceableMobile: null,
|
||||||
|
isZipServiceableInShop: null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -81,7 +84,9 @@ export default {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
resetMobileLocationTest() {
|
||||||
|
this.serviceZipQuestion.serviceZipCode = "43054";
|
||||||
|
},
|
||||||
backButtonAction() {},
|
backButtonAction() {},
|
||||||
forwardButtonAction() {},
|
forwardButtonAction() {},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,10 @@
|
||||||
:onModalOpenedCallback="onModalOpened"
|
:onModalOpenedCallback="onModalOpened"
|
||||||
:footerButtonText="modalFooterText"
|
:footerButtonText="modalFooterText"
|
||||||
@footer-button-event="setZipCode">
|
@footer-button-event="setZipCode">
|
||||||
<textboxQuestion
|
<serviceZipQuestion
|
||||||
ref="zipInputTextQuestion"
|
ref="serviceZipQuestion"
|
||||||
:cmsWidgetName="textboxQuestionWidgetName"
|
:cmsWidgetName="textboxQuestionWidgetName"
|
||||||
v-model="serviceZipModel.serviceZipCode"
|
v-model="serviceZipModel.serviceZipCode" />
|
||||||
inputId="serviceZipCode"
|
|
||||||
questionAlignment="center"
|
|
||||||
mask="#####"
|
|
||||||
:displayQuestionText="false"
|
|
||||||
isRequired
|
|
||||||
validationRules="zip-required|zip-format" />
|
|
||||||
<alert
|
<alert
|
||||||
ref="alertInvalidZip"
|
ref="alertInvalidZip"
|
||||||
v-if="displayInvalidZipAlert"
|
v-if="displayInvalidZipAlert"
|
||||||
|
|
@ -39,9 +33,9 @@
|
||||||
<script>
|
<script>
|
||||||
// Components
|
// Components
|
||||||
import textLink from "@/ux-components/text-link/text-link";
|
import textLink from "@/ux-components/text-link/text-link";
|
||||||
|
import serviceZipQuestion from "@/layouts/service-location/service-zip-modal-question/service-zip-question";
|
||||||
import modal from "@/digital-components/modal/modal";
|
import modal from "@/digital-components/modal/modal";
|
||||||
import alert from "@/ux-components/alert/alert";
|
import alert from "@/ux-components/alert/alert";
|
||||||
import textboxQuestion from "@/digital-components/textbox-question/textbox-question";
|
|
||||||
|
|
||||||
//Supporting Files
|
//Supporting Files
|
||||||
import { defineRule, useForm } from "vee-validate";
|
import { defineRule, useForm } from "vee-validate";
|
||||||
|
|
@ -66,7 +60,7 @@ export default {
|
||||||
default: () => ({
|
default: () => ({
|
||||||
serviceZipQuestion: {
|
serviceZipQuestion: {
|
||||||
serviceState: "",
|
serviceState: "",
|
||||||
serviceZipCode: "",
|
serviceZipCode: "1234",
|
||||||
isServiceable: null,
|
isServiceable: null,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
@ -120,7 +114,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
focusOnZipInput() {
|
focusOnZipInput() {
|
||||||
const input = document.getElementById("serviceZipCode");
|
const input = document.getElementById("serviceZipCodeTextBoxQuestion");
|
||||||
input.focus();
|
input.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -165,9 +159,9 @@ export default {
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
textLink,
|
textLink,
|
||||||
|
serviceZipQuestion,
|
||||||
modal,
|
modal,
|
||||||
alert,
|
alert,
|
||||||
textboxQuestion,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<textboxQuestion
|
||||||
|
ref="zipInputTextQuestion"
|
||||||
|
:cmsWidgetName="cmsWidgetName"
|
||||||
|
v-model="value"
|
||||||
|
inputId="serviceZipCodeTextBoxQuestion"
|
||||||
|
questionAlignment="center"
|
||||||
|
mask="#####"
|
||||||
|
:displayQuestionText="false"
|
||||||
|
isRequired
|
||||||
|
validationRules="zip-required|zip-format" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import textboxQuestion from "@/digital-components/textbox-question/textbox-question";
|
||||||
|
|
||||||
|
//Supporting Files
|
||||||
|
import { defineRule } from "vee-validate";
|
||||||
|
import { required, regex } from "@/helpers/validation-rules";
|
||||||
|
import { errorMessages } from "@/constants/error-messages";
|
||||||
|
|
||||||
|
// Define Validation Rules
|
||||||
|
defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
|
||||||
|
defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "service-zip-question",
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
serviceZipCode: String,
|
||||||
|
},
|
||||||
|
cmsWidgetName: String,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
value: {
|
||||||
|
get: function () {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
set: function (newValue) {
|
||||||
|
this.$emit("update:modelValue", newValue);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
textboxQuestion,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
Loading…
Reference in a new issue