CSR-447: refactoring logic of buttons and events, remove unused logic

This commit is contained in:
Adam Caouette 2022-04-26 09:51:13 -04:00
parent 8d04bc4845
commit f991b73f66
4 changed files with 139 additions and 77 deletions

View file

@ -2,8 +2,12 @@
<div <div
class="list-group list-button-horizontal d-flex flex-column w-100 mb-2" class="list-group list-button-horizontal d-flex flex-column w-100 mb-2"
:class="[(errors.length > 0 || hasError) ? 'has-error' : '']" :class="[(errors.length > 0 || hasError) ? 'has-error' : '']"
@mouseup="handleClick(value)" @mouseup="triggerButton()"
@keyup.space="handleClick(value)" @keyup.space="triggerButton()"
@keyup.up="handleKeyupArrow()"
@keyup.down="handleKeyupArrow()"
@keyup.left="handleKeyupArrow()"
@keyup.right="handleKeyupArrow()"
> >
<input <input
:type="isMultiSelect ? 'checkbox' : 'radio'" :type="isMultiSelect ? 'checkbox' : 'radio'"
@ -12,7 +16,7 @@
:value="value" :value="value"
:aria-required="isRequired" :aria-required="isRequired"
v-model="checkValue" v-model="checkValue"
@change="!selectingInitiatesLoad ? handleCheckChange() : ''" @change="handleInputChange()"
/> />
<label <label
tabindex="-1" tabindex="-1"
@ -31,13 +35,16 @@
class="m-0 small" class="m-0 small"
:class="textPosition" :class="textPosition"
> >
{{buttonLabelSubCopy}} {{ buttonLabelSubCopy }}
</span> </span>
<span v-if="screenReaderOnlyText" class="sr-only"> <span
{{screenReaderOnlyText}} v-if="screenReaderOnlyText"
class="sr-only"
>
{{ screenReaderOnlyText }}
</span> </span>
<loader <loader
v-if="isLoaderDisplayed && !isMultiSelect" v-if="isLoaderDisplayed && selectingInitiatesLoad"
:class="[loaderColor, loaderPosition]" :class="[loaderColor, loaderPosition]"
/> />
</label> </label>
@ -77,27 +84,47 @@ export default {
checkValue: Boolean, checkValue: Boolean,
}; };
}, },
created(){ created() {
if(Array.isArray(this.selectedValues)){ if (Array.isArray(this.selectedValues)) {
this.checkValue = this.isMultiSelect ? this.selectedValues.includes(this.value) : this.selectedValues[0]; this.checkValue = this.isMultiSelect
? this.selectedValues.includes(this.value)
: this.selectedValues[0];
} }
}, },
methods: { methods: {
displayLoader() { displayLoader() {
this.isLoaderDisplayed = true; this.isLoaderDisplayed = true;
}, },
handleClick(value) { handleInputChange() {
if(this.selectingInitiatesLoad) { if(!this.selectingInitiatesLoad) {
this.displayLoader(); this.handleCheckChange();
}
},
handleKeyupArrow() {
if (this.isMultiSelect) {
return; // Prevent arrow keys from doing anything if element is a checkbox
}
if(!this.selectingInitiatesLoad) {
this.handleCheckChange(); this.handleCheckChange();
} }
this.handleChange(value); this.handleChange(this.value);
}, },
handleCheckChange(newValue, oldValue){ triggerButton() {
const isInitialization = typeof(oldValue) === 'function'; if(this.selectingInitiatesLoad) {
if (!isInitialization) { this.displayLoader();
this.$emit('isCheckedChanged', { checkValue: this.checkValue, value: this.value.toString() }); this.handleCheckChange();
} }
this.handleChange(this.value);
},
handleCheckChange() {
const emitEvent = {
checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question
value: this.value.toString(),
buttonId: this.buttonID && this.buttonID.toString(),
};
this.$emit("isCheckedChanged", emitEvent);
this.$emit("update:modelValue", emitEvent);
} }
}, },
components: { components: {
@ -105,6 +132,7 @@ export default {
}, },
setup(props) { setup(props) {
const inputType = props.isMultiSelect ? "checkbox" : "radio"; const inputType = props.isMultiSelect ? "checkbox" : "radio";
const fieldOptions = { const fieldOptions = {
type: inputType, type: inputType,
checkedValue: props.value, checkedValue: props.value,
@ -118,13 +146,11 @@ export default {
} }
const { const {
checked,
handleChange, handleChange,
errors, errors,
} = useField(props.groupName, props.validationRules, fieldOptions); } = useField(props.groupName, props.validationRules, fieldOptions);
return { return {
checked,
handleChange, handleChange,
errors, errors,
fieldOptions, // only need to expose this for unit test purposes fieldOptions, // only need to expose this for unit test purposes

View file

@ -2,8 +2,12 @@
<div <div
class="list-group list-button d-flex flex-column w-100 mb-2" class="list-group list-button d-flex flex-column w-100 mb-2"
:class="[(errors.length > 0 || hasError) ? 'has-error' : '']" :class="[(errors.length > 0 || hasError) ? 'has-error' : '']"
@mouseup="handleClick(value)" @mouseup="triggerButton()"
@keyup.space="handleClick(value)" @keyup.space="triggerButton()"
@keyup.up="handleKeyupArrow()"
@keyup.down="handleKeyupArrow()"
@keyup.left="handleKeyupArrow()"
@keyup.right="handleKeyupArrow()"
> >
<input <input
:type="isMultiSelect ? 'checkbox' : 'radio'" :type="isMultiSelect ? 'checkbox' : 'radio'"
@ -12,7 +16,7 @@
:value="value" :value="value"
:aria-required="isRequired" :aria-required="isRequired"
v-model="checkValue" v-model="checkValue"
@change="!selectingInitiatesLoad ? handleCheckChange() : ''" @change="handleInputChange()"
> >
<label <label
tabindex="-1" tabindex="-1"
@ -40,7 +44,7 @@
{{ screenReaderOnlyText }} {{ screenReaderOnlyText }}
</span> </span>
<loader <loader
v-if="isLoaderDisplayed && !isMultiSelect" v-if="isLoaderDisplayed && selectingInitiatesLoad"
:class="[this.loaderColor, this.loaderPosition]" :class="[this.loaderColor, this.loaderPosition]"
/> />
</label> </label>
@ -80,33 +84,47 @@ export default {
checkValue: Boolean, checkValue: Boolean,
}; };
}, },
created(){ created() {
if(Array.isArray(this.selectedValues)){ if (Array.isArray(this.selectedValues)) {
this.checkValue = this.isMultiSelect ? this.selectedValues.includes(this.value) : this.selectedValues[0]; this.checkValue = this.isMultiSelect
? this.selectedValues.includes(this.value)
: this.selectedValues[0];
} }
}, },
methods: { methods: {
displayLoader() { displayLoader() {
this.isLoaderDisplayed = true; this.isLoaderDisplayed = true;
}, },
handleClick(value) { handleInputChange() {
if(!this.selectingInitiatesLoad) {
this.handleCheckChange();
}
},
handleKeyupArrow() {
if (this.isMultiSelect) {
return; // Prevent arrow keys from doing anything if element is a checkbox
}
if(!this.selectingInitiatesLoad) {
this.handleCheckChange();
}
this.handleChange(this.value);
},
triggerButton() {
if(this.selectingInitiatesLoad) { if(this.selectingInitiatesLoad) {
this.displayLoader(); this.displayLoader();
this.handleCheckChange(); this.handleCheckChange();
} }
this.handleChange(value); this.handleChange(this.value);
}, },
handleCheckChange(value, oldValue){ handleCheckChange() {
const isInitialization = typeof(oldValue) === 'function'; const emitEvent = {
if (!isInitialization) { checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question
const emitEvent = { value: this.value.toString(),
checkValue: this.checkValue, buttonId: this.buttonID && this.buttonID.toString(),
value: this.value.toString(), };
buttonId: this.buttonID.toString(), this.$emit("isCheckedChanged", emitEvent);
}; this.$emit("update:modelValue", emitEvent);
this.$emit('isCheckedChanged', emitEvent);
this.$emit("update:modelValue", emitEvent);
}
}, },
}, },
components: { components: {
@ -128,13 +146,11 @@ export default {
} }
const { const {
checked,
handleChange, handleChange,
errors, errors,
} = useField(props.groupName, props.validationRules, fieldOptions); } = useField(props.groupName, props.validationRules, fieldOptions);
return { return {
checked,
handleChange, handleChange,
errors, errors,
fieldOptions, // only need to expose this for unit test purposes fieldOptions, // only need to expose this for unit test purposes

View file

@ -6,8 +6,12 @@
isWide ? 'horizontal' : '', isWide ? 'horizontal' : '',
(errors.length > 0 || hasError) ? 'has-error' : '', (errors.length > 0 || hasError) ? 'has-error' : '',
]" ]"
@mouseup="handleChange(value)" @mouseup="triggerButton()"
@keyup.space="handleChange(value)" @keyup.space="triggerButton()"
@keyup.up="handleKeyupArrow()"
@keyup.down="handleKeyupArrow()"
@keyup.left="handleKeyupArrow()"
@keyup.right="handleKeyupArrow()"
> >
<input <input
:type="isMultiSelect ? 'checkbox' : 'radio'" :type="isMultiSelect ? 'checkbox' : 'radio'"
@ -16,13 +20,14 @@
:value="value" :value="value"
:aria-required="isRequired" :aria-required="isRequired"
v-model="checkValue" v-model="checkValue"
@change="handleCheckChange(value)" @change="handleInputChange()"
/> />
<label <label
tabindex="-1"
:for="buttonID" :for="buttonID"
:aria-labelledby="buttonID"
class="d-flex w-100 align-items-center px-2 h-100" class="d-flex w-100 align-items-center px-2 h-100"
:class="getLabelClasses" :class="getLabelClasses"
tabindex="-1"
> >
<img <img
:id="buttonImageId" :id="buttonImageId"
@ -93,15 +98,6 @@ export default {
: this.selectedValues[0]; : this.selectedValues[0];
} }
}, },
watch: {
// Changing this will impact pre-selection data loads on vehicle-parts.
// If changed, please regression test that vehicle-parts data still loads correctly with previous selections.
modelValue(newVal) {
if (newVal !== undefined) {
this.checkValue = newVal.value;
}
},
},
computed: { computed: {
getLabelClasses() { getLabelClasses() {
if (this.isWide) { if (this.isWide) {
@ -116,16 +112,44 @@ export default {
}, },
}, },
methods: { methods: {
handleCheckChange(newValue, oldValue) { handleInputChange() {
const isInitialization = typeof oldValue === "function"; if(!this.selectingInitiatesLoad) {
if (!isInitialization) { this.handleCheckChange();
const emitEvent = { }
checkValue: this.checkValue, },
value: this.value.toString(), handleKeyupArrow() {
buttonId: this.buttonID.toString(), if (this.isMultiSelect) {
}; return; // Prevent arrow keys from doing anything if element is a checkbox
this.$emit("isCheckedChanged", emitEvent); }
this.$emit("update:modelValue", emitEvent);
if(!this.selectingInitiatesLoad) {
this.handleCheckChange();
}
this.handleChange(this.value);
},
triggerButton() {
if(this.selectingInitiatesLoad) {
this.displayLoader();
this.handleCheckChange();
}
this.handleChange(this.value);
},
handleCheckChange() {
const emitEvent = {
checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question
value: this.value.toString(),
buttonId: this.buttonID && this.buttonID.toString(),
};
this.$emit("isCheckedChanged", emitEvent);
this.$emit("update:modelValue", emitEvent);
},
},
watch: {
// Changing this will impact pre-selection data loads on vehicle-parts.
// If changed, please regression test that vehicle-parts data still loads correctly with previous selections.
modelValue(newVal) {
if (newVal !== undefined) {
this.checkValue = newVal.value;
} }
}, },
}, },

View file

@ -56,19 +56,15 @@ export default {
handleClick(value) { handleClick(value) {
this.handleChange(value); this.handleChange(value);
}, },
handleCheckChange(newValue, oldValue) { handleCheckChange() {
const isInitialization = typeof oldValue === "function"; const emitEvent = {
if (!isInitialization) { checkValue: this.checkValue,
value: this.value.toString(),
buttonID: this.buttonID && this.buttonID.toString(),
};
const emitEvent = { this.$emit("isCheckedChanged", emitEvent);
checkValue: this.checkValue, this.$emit("update:modelValue", emitEvent);
value: this.value.toString(),
buttonID: this.buttonID.toString(),
};
this.$emit("isCheckedChanged", emitEvent);
this.$emit("update:modelValue", emitEvent);
}
}, },
}, },
setup(props) { setup(props) {