Merge pull request #454 from Safelite/feature/CSR-563
CSR-563 | Scroll alert into view if it is not fully visible upon being shown
This commit is contained in:
commit
8923541348
9 changed files with 49 additions and 12 deletions
|
|
@ -27,6 +27,7 @@ module.exports = {
|
|||
"!src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue",
|
||||
"!src/common-components/dropdown-question/dropdown-question.vue",
|
||||
"!src/common-components/textbox-question/textbox-question.vue",
|
||||
"!src/ux-components/alert\alert.vue",
|
||||
"!src/helpers/validation-rules.js",
|
||||
// END
|
||||
], // ! means exclude from coverage.
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ describe("funnel-footer.vue", () => {
|
|||
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn()
|
||||
getCmsContent: jest.fn(),
|
||||
getFooterInfoBoxHeight: jest.fn(()=>80)
|
||||
}
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.paddingHeight = document.querySelector(".footer #infoBox").offsetHeight + 24;
|
||||
this.paddingHeight = this.getFooterInfoBoxHeight() + 24;
|
||||
this.$nextTick(() => {
|
||||
window.addEventListener('resize', this.onResize);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,27 +12,27 @@
|
|||
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" ref="funnelSubHeader" />
|
||||
<div class="fade-on-route-transition sub-container make-tall">
|
||||
<customerQuestions ref="customerQuestions" v-model="customerQuestions" />
|
||||
<alert ref="alertVinNotFound" v-show="displayVinNotFoundAlert"
|
||||
<alert ref="alertVinNotFound" v-if="displayVinNotFoundAlert"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertVinNotFoundWidget"
|
||||
alertClass="alert-danger"
|
||||
v-bind:isDismissible="false"
|
||||
/>
|
||||
<alert ref="alertMatchedDifferentVehicle" v-show="displayMatchedDifferentVehicleAlert"
|
||||
<alert ref="alertMatchedDifferentVehicle" v-if="displayMatchedDifferentVehicleAlert"
|
||||
class="mb-4"
|
||||
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
v-bind:isDismissible="false"
|
||||
/>
|
||||
<alert ref="alertNonServiceableZip" v-show="displayNonServiceableZipAlert"
|
||||
<alert ref="alertNonServiceableZip" v-if="displayNonServiceableZipAlert"
|
||||
class="mb-4"
|
||||
alertClass="alert-danger"
|
||||
:manualHeadline="AlertNonServiceableZipHeader"
|
||||
:manualCopy="AlertNonServiceableZipBody"
|
||||
v-bind:isDismissible="false"
|
||||
/>
|
||||
<alert ref="alertVinLookupsByHomeAddressNotAllowed" v-show="displayVinLookupByHomeAddressNotAllowedAlert"
|
||||
<alert ref="alertVinLookupsByHomeAddressNotAllowed" v-if="displayVinLookupByHomeAddressNotAllowedAlert"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
|
||||
alertClass="alert-danger"
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@
|
|||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<alert ref="alertVerificationWarning" v-show="displayVerificationWarning"
|
||||
<alert ref="alertVerificationWarning" v-if="displayVerificationWarning"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertVerificationWarningWidget"
|
||||
alertClass="alert-warning"
|
||||
v-bind:isDismissible="false"
|
||||
/>
|
||||
<alert ref="alertNoMatchWarning" v-show="displayNoMatchWarning"
|
||||
<alert ref="alertNoMatchWarning" v-if="displayNoMatchWarning"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertNoMatchWarningWidget"
|
||||
alertClass="alert-warning"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<alert
|
||||
class="my-3"
|
||||
cmsWidgetName="NoReplacementAvailableError"
|
||||
v-show="showNoReplacementAvailableError"
|
||||
v-if="showNoReplacementAvailableError"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false"
|
||||
/>
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
<alert
|
||||
class="my-3"
|
||||
cmsWidgetName="SplitSingleConflict"
|
||||
v-show="hasSplitSingleConflict"
|
||||
v-if="hasSplitSingleConflict"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ export default {
|
|||
el && el.focus();
|
||||
}
|
||||
},
|
||||
getFooterInfoBoxHeight() {
|
||||
return document.querySelector(".footer #infoBox").offsetHeight;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
storeActions() {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ describe("alert.vue", () => {
|
|||
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn()
|
||||
getCmsContent: jest.fn(),
|
||||
getFooterInfoBoxHeight: jest.fn(()=> 80),
|
||||
}
|
||||
}
|
||||
|
|
@ -52,6 +52,10 @@ export default {
|
|||
cmsWidgetName: String,
|
||||
manualHeadline: String,
|
||||
manualCopy: String,
|
||||
shouldScrollToOnMount: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
alertHeadline(){
|
||||
|
|
@ -85,8 +89,35 @@ export default {
|
|||
// first split would return 'estimate,provide your VIN'
|
||||
// second split would return 'provide your VIN'
|
||||
return copy.split(':')[1].split(',')[1];
|
||||
}
|
||||
},
|
||||
ensureAlertIsInViewPort() {
|
||||
if (this.shouldScrollToOnMount && this.$el.style.display != 'none') {
|
||||
var footerHeight = this.getFooterInfoBoxHeight();
|
||||
if (!this.isAlertInViewport(footerHeight)) {
|
||||
this.scrollContainerToAlert(footerHeight);
|
||||
}
|
||||
}
|
||||
},
|
||||
isAlertInViewport(footerHeight) {
|
||||
const rect = this.$el.getBoundingClientRect();
|
||||
return (
|
||||
rect.top >= 0 &&
|
||||
// remove footerHeight from window height to avoid items being hidden behind footer
|
||||
rect.bottom <= (window.innerHeight - footerHeight || document.documentElement.clientHeight - footerHeight)
|
||||
);
|
||||
},
|
||||
scrollContainerToAlert(footerHeight) {
|
||||
// alert position on page + height of alert + footer height
|
||||
var scrollToHeight = this.$el.scrollHeight + this.$el.offsetHeight + footerHeight;
|
||||
// find the div wrapped by the form element - this is the scrollable container
|
||||
// should be a more future-proof selector in case of CSS class changes
|
||||
var pageContainerScrollable = document.querySelector('form > div');
|
||||
pageContainerScrollable.scrollTo(0, scrollToHeight);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.ensureAlertIsInViewPort();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue