Merge pull request #1230 from Safelite/feature/richardson/INSR-9659

Manual form validation on service packages
This commit is contained in:
brich1212safe 2026-05-15 22:59:03 -04:00 committed by GitHub
commit 76ebbf335a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 57 additions and 13 deletions

View file

@ -2,7 +2,7 @@
<buttonQuestion
ref="buttonQuestion"
v-model="selectedPackageName"
class="service-package-question"
:class="['service-package-question', additionalClass]"
:answers="servicePackageAnswers"
:groupName="groupName"
:questionText="questionText"
@ -39,6 +39,7 @@ export default {
buttonQuestion
},
props: {
additionalClass: String,
cmsWidgetName: String,
groupName: String,
validationRules: String,

View file

@ -21,12 +21,16 @@
ref="servicePackage"
cmsWidgetName="ServicePackage"
groupName="ServicePackageQuestion"
:additionalClass="showFormErrorState ? 'parent-error' : ''"
:availableLineItems="availableLineItems"
:validationRules="rules.optionRequired"
isRequired
@vapsItemsSelected="vapsItemsSelectedAction"
@packageSelected="packageSelectedAction"
@link-event="openModalAction" />
<div v-if="showFormErrorState" class="form-test-error">
{{ errorMessageText }}
</div>
<div class="d-flex justify-content-center mt-8 mb-4">
<buttonMain
ref="buttonMain"
@ -44,7 +48,7 @@
</div>
<p
class="caption disclaimer"
v-html="PriceDisclaimerText"></p>
v-html="priceDisclaimerText"></p>
</div>
<loadingModal
ref="loadingModal"
@ -67,7 +71,6 @@
import baseFormMixin from '@/mixins/base-form-mixin';
import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
import loadingModal from '@/iss-components/loading-modal/loading-modal.vue';
import settleAllPromises from '@/helpers/layout-helper';
@ -80,6 +83,7 @@ import globalRules from '@/constants/global-rules';
import servicePackageQuestion from '@/layouts/service-packages/service-package-question/service-package-question.vue';
import issPageValues from '@/router/router-constants/issPage-values';
import bailoutMessage from '@/constants/bailoutMessage';
import errorMessages from '@/constants/error-messages.js';
import buttonMain from '@/ux-components/button-main/button-main.vue';
import { analyticsServicePackageMap, analyticsVapsModalMap } from '@/constants/analytics';
@ -174,6 +178,7 @@ export default {
selectedVaps: [],
selectedPackageTier: '',
availableLineItems: [],
formSubmitAttempted: false,
loadingText: [
'Finding shops near you',
'Looking for dates',
@ -187,22 +192,31 @@ export default {
};
},
computed: {
PriceDisclaimerText() {
errorMessageText() {
return errorMessages.OPTION_REQUIRED;
},
hasSelectedServicePackage() {
return !!this.selectedPackageTier;
},
priceDisclaimerText() {
return this.getCmsContent('PriceDisclaimerWidget', 'Text');
},
vehicleMake() {
return (store.order.vehicle.make ?? '').toUpperCase();
},
vehicleModel() {
return (store.order.vehicle.model ?? '').toUpperCase();
secondaryText() {
return this.getCmsContent('SiteSubHeaderWidget', 'SecondaryText');
},
servicePackagesSubHeader() {
return this.getCmsContent('SiteSubHeaderWidget', 'SubHeaderText')
.replace('{custom:vehicleMake}', this.vehicleMake)
.replace('{custom:vehicleModel}', this.vehicleModel);
},
secondaryText() {
return this.getCmsContent('SiteSubHeaderWidget', 'SecondaryText');
showFormErrorState() {
return this.formSubmitAttempted && !this.hasSelectedServicePackage;
},
vehicleMake() {
return (store.order.vehicle.make ?? '').toUpperCase();
},
vehicleModel() {
return (store.order.vehicle.model ?? '').toUpperCase();
}
},
methods: {
@ -232,6 +246,11 @@ export default {
this.selectedPackageTier = packageTier;
},
forwardButtonAction() {
if (!this.hasSelectedServicePackage) {
this.formSubmitAttempted = true;
return false;
}
showIssLoadingModal(true);
const parts = {
vaps: this.selectedVaps

View file

@ -14,6 +14,7 @@ html {
input[type="radio"]:focus+.list-button-content {
box-shadow: 0 0 0 2.5px $red;
}
&:not(.selected):not(.no-hover):hover {
position: relative;
@include box-shadow-hover($red-200);
@ -135,6 +136,7 @@ html {
}
.has-success {
// START HOVER
&.list-button,
&.list-button.list-group,
@ -271,7 +273,8 @@ html {
}
}
//Quote page radio button group
// Service Packages page radio button group
// With form validation error state
.package-main {
.package-wrapper {
.has-error {
@ -284,7 +287,28 @@ html {
}
}
//Restore to default style if alert box is present
// With parent form validation error state
div.service-package-question.parent-error {
@include media-breakpoint-up(md) {
+.form-test-error {
margin-top: 0.25rem;
padding: 0 1.5rem 0 1.5rem;
}
}
.package-main {
.package-wrapper {
input[type="radio"] {
+.package-label {
border: 1px solid $red;
}
}
}
}
}
// Restore to default style if alert box is present
.alertError {
.has-error {