CSR-762 list-card with aggressive validation

This commit is contained in:
Katie 2022-09-19 16:17:52 -04:00
parent 4a2e21fe25
commit 95e972a02f
10 changed files with 125 additions and 74 deletions

View file

@ -263,9 +263,9 @@ export default {
// this.$emit("isCheckedChanged", val); // this.$emit("isCheckedChanged", val);
// }, // },
handleAnswerChange(eventValue) { handleAnswerChange(eventValue) {
console.log({ // console.log({
bqEvent: eventValue // bqEvent: eventValue
}) // })
this.$emit("update:modelValue", eventValue); this.$emit("update:modelValue", eventValue);
}, },
}, },

View file

@ -2,7 +2,6 @@
<label <label
:class="[buttonWrapperClasses, { 'has-error': errors.length > 0 }]" :class="[buttonWrapperClasses, { 'has-error': errors.length > 0 }]"
:for="buttonId" :for="buttonId"
@mousedown.left="handleEventAction('click', $event)"
> >
<!-- classes: {{classes}}<br/> <!-- classes: {{classes}}<br/>
value: {{value}} <br/> value: {{value}} <br/>
@ -17,7 +16,6 @@
:value="value" :value="value"
:checked="isChecked" :checked="isChecked"
@keypress.enter="handleEventAction('keypressSubmit', $event)" @keypress.enter="handleEventAction('keypressSubmit', $event)"
@keypress.space="handleEventAction('keypressSubmit', $event)"
@change="handleEventAction('change', $event)" @change="handleEventAction('change', $event)"
/> />
@ -81,6 +79,14 @@ export default {
hasFirstEventFired: false, hasFirstEventFired: false,
}; };
}, },
mounted() {
console.log({
isChecked: this.isChecked,
modelValue: this.modelValue
})
this.handleChange(this.modelValue)
},
methods: { methods: {
handleEventAction(eventType, e) { handleEventAction(eventType, e) {
const eventTypes = { const eventTypes = {
@ -89,25 +95,52 @@ export default {
CLICK: "click", CLICK: "click",
}; };
if (!this.hasFirstEventFired) { console.log({
switch (eventType) { handleKeypress: eventType,
case eventTypes.CLICK: hasFirstEventFired: this.hasFirstEventFired,
case eventTypes.KEYPRESS_SUBMIT: });
console.log("clicking");
this.handleClick(e); if (this.isMultiSelect) {
break; // if (true) {
case eventTypes.CHANGE: switch (eventType) {
console.log("selectOnKeypress: ", this.selectOnKeypress); case eventTypes.CLICK:
this.selectOnKeypress case eventTypes.KEYPRESS_SUBMIT:
? this.handleClick(e) console.log("clicking");
: this.handleSelectionChange(e); this.hasFirstEventFired = true;
break; this.handleClick(e);
} break;
case eventTypes.CHANGE:
console.log("selectOnKeypress: ", this.selectOnKeypress);
this.hasFirstEventFired = false;
this.selectOnKeypress
? this.handleClick(e)
: this.handleSelectionChange(e);
break;
}
// if (this.hasFirstEventFired) {
// this.hasFirstEventFired = eventType === eventTypes.CHANGE;
// }
// }
} else {
this.handleClick(e);
} }
this.hasFirstEventFired = eventType !== eventTypes.CHANGE; // if (!this.hasFirstEventFired) {
console.log("handleKeypress: ", eventType); // else {
// this.hasFirstEventFired = eventType !== eventTypes.CHANGE;
// }
// else {
// this.hasFirstEventFired = true;
// this.selectOnKeypress
// ? this.handleClick(e)
// : this.handleSelectionChange(e);
// }
// this.hasFirstEventFired = eventType !== eventTypes.CHANGE;
// this.handleClick(e);
// console.log({ // console.log({
// selectOnKeypress: this.selectOnKeypress, // selectOnKeypress: this.selectOnKeypress,
// event: e, // event: e,

View file

@ -78,7 +78,7 @@ export default ({
}, },
watch: { watch: {
selectedValue(selectedValue) { selectedValue(selectedValue) {
console.log("DLQ: ", selectedValue) // console.log("DLQ: ", selectedValue)
this.$emit("update:modelValue", selectedValue) this.$emit("update:modelValue", selectedValue)
} }
} }

View file

@ -8,7 +8,7 @@
:answers="answersToDisplay" :answers="answersToDisplay"
:groupName="groupName" :groupName="groupName"
buttonType="listCard" buttonType="listCard"
v-model="selectedValues" v-model="selectedValue"
:validationRules="validationRules" :validationRules="validationRules"
:suppressError="suppressError" :suppressError="suppressError"
:isRequired=isRequired :isRequired=isRequired
@ -20,9 +20,11 @@
<script> <script>
import buttonQuestion from "@/common-components/button-question/button-question"; import buttonQuestion from "@/common-components/button-question/button-question";
import store from "@/store"; import store from "@/store";
import buttonQuestionWrapperMixin from "@/mixins/button-question-wrapper-mixin";
export default ({ export default ({
name: "replaceOptionsQuestion", name: "replaceOptionsQuestion",
mixins: [buttonQuestionWrapperMixin],
data(){ data(){
return { return {
replaceOptions: [], replaceOptions: [],
@ -32,7 +34,7 @@ export default ({
isAvailable: Boolean, isAvailable: Boolean,
filterByVehicleCategory: Boolean, filterByVehicleCategory: Boolean,
groupName: String, groupName: String,
modelValue: Array, // modelValue: Array,
isMultiSelect: Boolean, isMultiSelect: Boolean,
validationRules: String, validationRules: String,
suppressError: Boolean, suppressError: Boolean,
@ -43,12 +45,13 @@ export default ({
initializeComponent(replaceOptions){ initializeComponent(replaceOptions){
this.replaceOptions = replaceOptions; this.replaceOptions = replaceOptions;
}, },
// updateSelectedValues() { updateSelectedValues() {
// // UPDATE SELECTEDVALUES IF ONLY ONE ANSWER // UPDATE SELECTEDVALUES IF ONLY ONE ANSWER
// if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) { // ex: BackGlass stationary
// this.selectedValues = [this.answersToDisplay[0].Name]; if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) {
// } this.selectedValue = [this.answersToDisplay[0].Name];
// }, }
},
}, },
computed: { computed: {
questionText(){ questionText(){
@ -91,7 +94,7 @@ export default ({
}, },
shouldDisplayReplaceOptionsQuestion(shouldDisplayReplaceOptionsQuestion) { shouldDisplayReplaceOptionsQuestion(shouldDisplayReplaceOptionsQuestion) {
if (!shouldDisplayReplaceOptionsQuestion) { if (!shouldDisplayReplaceOptionsQuestion) {
this.selectedValues = []; this.selectedValue = [];
} }
} }
}, },

View file

@ -38,14 +38,14 @@
alertClass="alert-danger" alertClass="alert-danger"
:isDismissible="false" :isDismissible="false"
/> />
<!-- <sideDoorOptions <sideDoorOptions
ref="sideDoorOptions" ref="sideDoorOptions"
cmsWidgetName="SideDoorSideQuestion" cmsWidgetName="SideDoorSideQuestion"
groupName="SideDoorSideQuestion" groupName="SideDoorSideQuestion"
v-model="sideDoorOptionsData" v-model="sideDoorOptionsData"
v-show="!hasRepairReplaceConflict" v-show="!hasRepairReplaceConflict"
:selectedDamageLocations="selectedDamageLocations" :selectedDamageLocations="selectedDamageLocations"
/> --> />
<!-- <replaceOptionsQuestion <!-- <replaceOptionsQuestion
ref="backGlassOptions" ref="backGlassOptions"
cmsWidgetName="RearReplaceOptionsQuestion" cmsWidgetName="RearReplaceOptionsQuestion"
@ -401,7 +401,7 @@ export default {
funnelFooter, funnelFooter,
vehicleBanner, vehicleBanner,
funnelSubHeader, funnelSubHeader,
// sideDoorOptions, sideDoorOptions,
damageLocationQuestion, damageLocationQuestion,
windshieldOptions, windshieldOptions,
// replaceOptionsQuestion, // replaceOptionsQuestion,

View file

@ -30,6 +30,7 @@ export default ({
cmsWidgetName: String, cmsWidgetName: String,
}, },
methods: { methods: {
// TODO KO is this being used? Always three options
updateSelectedValues() { updateSelectedValues() {
// UPDATE SELECTEDVALUES IF ONLY ONE ANSWER // UPDATE SELECTEDVALUES IF ONLY ONE ANSWER
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1 && this.selectedValues) { if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1 && this.selectedValues) {

View file

@ -50,17 +50,17 @@ export default ({
components: { components: {
buttonQuestion, buttonQuestion,
}, },
watch: { // watch: {
isAvailable(isAvailable) { // isAvailable(isAvailable) {
if (!isAvailable) { // if (!isAvailable) {
console.log({ // // console.log({
isAvailable: isAvailable // // isAvailable: isAvailable
}) // // })
console.log("updating") // // console.log("updating")
this.selectedValue = null; // this.selectedValue = null;
// this.$emit("update:modelValue", null); // // this.$emit("update:modelValue", null);
} // }
} // }
} // }
}) })
</script> </script>

View file

@ -1,6 +1,7 @@
export default { export default {
props: { props: {
modelValue: String, modelValue: String,
}, },
data() { data() {
return { return {

View file

@ -1,12 +1,22 @@
<template> <template>
<div class="list-group list-button-horizontal d-flex flex-column w-100" <inputButtonWrapper
:buttonWrapperClasses="[
'list-group list-button-horizontal d-flex flex-column w-100',
{ 'radio-fancy': isCashOrInsurance, 'has-error': errors.length > 0 }
]"
:isMultiSelect="isMultiSelect"
:modelValue="modelValue"
:value="value"
:groupName="groupName"
:validationRules="validationRules"
:selectOnKeypress="selectOnKeypress"
@change="handleAnswerChange"
>
<!-- <div class="list-group list-button-horizontal d-flex flex-column w-100"
:class="[(errors.length > 0 || hasError) ? 'has-error' : '', isCashOrInsurance ? 'radio-fancy' : '']" :class="[(errors.length > 0 || hasError) ? 'has-error' : '', isCashOrInsurance ? 'radio-fancy' : '']"
@keyup.space="triggerButton()" @keyup.up="handleKeyupArrow()" @keyup.down="handleKeyupArrow()" @keyup.space="triggerButton()" @keyup.up="handleKeyupArrow()" @keyup.down="handleKeyupArrow()"
@keyup.left="handleKeyupArrow()" @keyup.right="handleKeyupArrow()"> @keyup.left="handleKeyupArrow()" @keyup.right="handleKeyupArrow()"> -->
<input :type="isMultiSelect ? 'checkbox' : 'radio'" :id="buttonID" :name="groupName" :value="value" <div :aria-labelledby="buttonID" class="list-button-horizontal-content d-flex flex-column justify-content-center p-3" @mouseup="triggerButton()">
:aria-required="isRequired" v-model="checkValue" @change="handleInputChange()" />
<label tabindex="-1" :for="buttonID" :aria-labelledby="buttonID"
class="d-flex flex-column justify-content-center p-3" @mouseup="triggerButton()">
<span class="m-0" :class="textPosition"> <span class="m-0" :class="textPosition">
{{ buttonLabel }} {{ buttonLabel }}
</span> </span>
@ -17,8 +27,9 @@
{{ screenReaderOnlyText }} {{ screenReaderOnlyText }}
</span> </span>
<loader v-if="isLoaderDisplayed && selectingInitiatesLoad" :class="[loaderColor, loaderPosition]" /> <loader v-if="isLoaderDisplayed && selectingInitiatesLoad" :class="[loaderColor, loaderPosition]" />
</label> </div>
</div> <!-- </div> -->
</inputButtonWrapper>
</template> </template>
<script> <script>
@ -26,6 +37,7 @@ import { useField } from "vee-validate";
import loader from "@/ux-components/loader/loader"; import loader from "@/ux-components/loader/loader";
import { toRef } from "vue"; import { toRef } from "vue";
import { queryStrings } from "@/constants/query-strings"; import { queryStrings } from "@/constants/query-strings";
import inputButtonWrapper from "@/common-components/input-button-wrapper/input-button-wrapper";
export default { export default {
name: "listButtonHorizontal", name: "listButtonHorizontal",
@ -116,6 +128,7 @@ export default {
}, },
components: { components: {
loader, loader,
inputButtonWrapper
}, },
setup(props) { setup(props) {
const inputType = props.isMultiSelect ? "checkbox" : "radio"; const inputType = props.isMultiSelect ? "checkbox" : "radio";
@ -159,33 +172,33 @@ export default {
opacity: 0; opacity: 0;
width: 0; width: 0;
&:focus-visible+label { &:focus-visible+.list-button-horizontal-content {
box-shadow: 0 0 0 2.5px $blue; box-shadow: 0 0 0 2.5px $blue;
z-index: 2; z-index: 2;
} }
&:focus+label { &:focus+.list-button-horizontal-content {
box-shadow: 0 0 0 2.5px $blue; box-shadow: 0 0 0 2.5px $blue;
z-index: 3; z-index: 3;
} }
&:checked+label { &:checked+.list-button-horizontal-content {
background: $blue-100; background: $blue-100;
box-shadow: 0 0 0 1px $blue; box-shadow: 0 0 0 1px $blue;
outline: none; outline: none;
z-index: 2; z-index: 2;
} }
&:checked:focus+label { &:checked:focus+.list-button-horizontal-content {
box-shadow: 0 0 0 2.5px $blue; box-shadow: 0 0 0 2.5px $blue;
} }
&:checked+label p:first-child { &:checked+.list-button-horizontal-content p:first-child {
font-weight: 500; font-weight: 500;
} }
} }
label { .list-button-horizontal-content {
outline: none; outline: none;
position: relative; position: relative;
background: $white; background: $white;
@ -214,7 +227,7 @@ export default {
// Cash/Insurance option radio button styling // Cash/Insurance option radio button styling
&.radio-fancy { &.radio-fancy {
label { .list-button-horizontal-content {
border: 1px solid $blue-700; border: 1px solid $blue-700;
z-index: 2; z-index: 2;
color: $blue; color: $blue;
@ -225,7 +238,7 @@ export default {
} }
} }
label:hover { .list-button-horizontal-content:hover {
background-color: $blue-700; background-color: $blue-700;
color: $white; color: $white;
box-shadow: none; box-shadow: none;
@ -238,16 +251,16 @@ export default {
opacity: 0; opacity: 0;
width: 0; width: 0;
&:focus-visible+label { &:focus-visible+.list-button-horizontal-content {
border-radius: 0.5rem; border-radius: 0.5rem;
z-index: 2; z-index: 2;
} }
&:focus+label { &:focus+.list-button-horizontal-content {
z-index: 3; z-index: 3;
} }
&:checked+label { &:checked+.list-button-horizontal-content {
outline: none; outline: none;
box-shadow: none; box-shadow: none;
color: $white; color: $white;
@ -256,11 +269,11 @@ export default {
z-index: 5; z-index: 5;
} }
&:checked:focus+label { &:checked:focus+.list-button-horizontal-content {
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700; box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
} }
&:checked+label p:first-child { &:checked+.list-button-horizontal-content p:first-child {
font-weight: 500; font-weight: 500;
} }
} }
@ -270,7 +283,7 @@ export default {
.col { .col {
&:first-of-type { &:first-of-type {
.list-button-horizontal { .list-button-horizontal {
label { .list-button-horizontal-content {
border-bottom-left-radius: 0.5rem; border-bottom-left-radius: 0.5rem;
border-top-left-radius: 0.5rem; border-top-left-radius: 0.5rem;
} }
@ -279,7 +292,7 @@ export default {
&:last-of-type { &:last-of-type {
.list-button-horizontal { .list-button-horizontal {
label { .list-button-horizontal-content {
border-bottom-right-radius: 0.5rem; border-bottom-right-radius: 0.5rem;
border-top-right-radius: 0.5rem; border-top-right-radius: 0.5rem;
} }
@ -290,12 +303,12 @@ export default {
&:first-of-type { &:first-of-type {
.list-button-horizontal.radio-fancy { .list-button-horizontal.radio-fancy {
input[type="radio"] { input[type="radio"] {
&:checked+label { &:checked+.list-button-horizontal-content {
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
} }
&:checked:focus+label { &:checked:focus+.list-button-horizontal-content {
border-bottom-right-radius: 0.5rem; border-bottom-right-radius: 0.5rem;
border-top-right-radius: 0.5rem; border-top-right-radius: 0.5rem;
} }
@ -306,12 +319,12 @@ export default {
&:last-of-type { &:last-of-type {
.list-button-horizontal.radio-fancy { .list-button-horizontal.radio-fancy {
input[type="radio"] { input[type="radio"] {
&:checked+label { &:checked+.list-button-horizontal-content {
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-top-left-radius: 0; border-top-left-radius: 0;
} }
&:checked:focus+label { &:checked:focus+.list-button-horizontal-content {
border-bottom-left-radius: 0.5rem; border-bottom-left-radius: 0.5rem;
border-top-left-radius: 0.5rem; border-top-left-radius: 0.5rem;
} }

View file

@ -179,7 +179,7 @@ export default {
// this.$emit("isCheckedChanged", emitEvent); // this.$emit("isCheckedChanged", emitEvent);
// }, // },
handleAnswerChange(e) { handleAnswerChange(e) {
console.log(e) // console.log(e)
this.$emit("change", e); this.$emit("change", e);
}, },
}, },