CSR-762 WIP

This commit is contained in:
Katie 2022-09-15 17:30:46 -04:00
parent 6e901a6918
commit ace997bbf5
6 changed files with 235 additions and 165 deletions

View file

@ -42,7 +42,7 @@
v-for="answer in answers" v-for="answer in answers"
:key="answer.Name ? answer.Name : answer" :key="answer.Name ? answer.Name : answer"
> >
<component <component
:is="buttonType" :is="buttonType"
:buttonLabel=" :buttonLabel="
answer.Text ? answer.Text : getAnswerString(answer, 'Name') answer.Text ? answer.Text : getAnswerString(answer, 'Name')
@ -50,10 +50,11 @@
:buttonLabelSubCopy="answer.SubText" :buttonLabelSubCopy="answer.SubText"
:isMultiSelect="isMultiSelect" :isMultiSelect="isMultiSelect"
:groupName="groupName" :groupName="groupName"
:value="answer.Value" :value="answer.Name"
:modelValue="modelValue" :modelValue="modelValue"
@change="e => handleSelectionChange(e, answer.Value)" @change="(e) => test(e)"
/> />
<!-- <component <!-- <component
:is="buttonType" :is="buttonType"
@isCheckedChanged="handleCheckedChanged" @isCheckedChanged="handleCheckedChanged"
@ -111,7 +112,7 @@ import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-bu
import listCard from "@/ux-components/list-card/list-card"; import listCard from "@/ux-components/list-card/list-card";
import { ErrorMessage } from "vee-validate"; import { ErrorMessage } from "vee-validate";
import radio from "@/ux-components/radio/radio"; import radio from "@/ux-components/radio/radio";
import testButton from "@/common-components/test-button.vue"; // import buttonWrap
export default { export default {
name: "buttonQuestion", name: "buttonQuestion",
@ -205,7 +206,6 @@ export default {
}, },
methods: { methods: {
formatString(str) { formatString(str) {
console.log(str);
return str?.replace(" ", "-"); return str?.replace(" ", "-");
}, },
getValue(answer) { getValue(answer) {
@ -242,28 +242,40 @@ export default {
} }
this.$emit("isCheckedChanged", val); this.$emit("isCheckedChanged", val);
}, },
handleSelectionChange(event, value) { test(event) {
console.log(value) console.log(event)
console.log("BQ handleSelectionChange: ", event) this.$emit("update:modelValue", event);
let isChecked = event.target.checked;
if (this.isMultiSelect && this.modelValue instanceof Array) {
let newValue = [...this.modelValue];
const toggledValue = event.target.value;
console.log("A: ", this.modelValue)
console.log("isChecked: ", isChecked)
console.log("value: ", event.target.value)
if (isChecked) {
newValue.push(toggledValue);
} else {
newValue.splice(newValue.indexOf(toggledValue), 1);
}
console.log("handleCheckboxChange: ", newValue);
this.$emit("update:modelValue", newValue);
} else {
console.log("handleRadioChange: ", isChecked);
this.$emit("update:modelValue", value);
}
}, },
// test(event, value) {
// console.log(value)
// console.log("BQ event: ", event)
// let isChecked = event.target?.checked;
// let valueToEmit;
// if (this.isMultiSelect && this.modelValue instanceof Array) {
// let newValue = [...this.modelValue];
// const toggledValue = event.target?.value;
// console.log("A: ", this.modelValue)
// console.log("isChecked: ", isChecked)
// console.log("value: ", toggledValue)
// if (isChecked) {
// newValue.push(toggledValue);
// } else {
// newValue.splice(newValue.indexOf(toggledValue), 1);
// }
// console.log("handleCheckboxChange: ", newValue);
// // this.$emit("update:modelValue", newValue);
// // this.$emit("update:value", newValue)
// valueToEmit = newValue;
// } else {
// console.log("handleRadioChange: ", isChecked);
// // this.$emit("update:modelValue", value);
// valueToEmit = value;
// }
// console.log("BQ emitting: ", valueToEmit)
// this.$emit("update:modelValue", valueToEmit);
// },
}, },
components: { components: {
listButton, listButton,
@ -271,7 +283,7 @@ export default {
listCard, listCard,
ErrorMessage, ErrorMessage,
radio, radio,
testButton, // testButton,
}, },
}; };
</script> </script>

View file

@ -0,0 +1,28 @@
<template>
<label :class="classes" :for="buttonId">
classes: {{classes}}<br/>
value: {{value}} <br/>
modelValue: {{modelValue}} <br/>
buttonId: {{buttonId}} <br/>
<input
:type="inputType"
:id="buttonId"
:name="groupName"
:aria-required="isRequired"
:value="value"
:checked="isChecked"
@change="handleSelectionChange"
/>
<slot></slot>
</label>
</template>
<script>
import buttonMixin from "@/mixins/button-mixin";
export default {
name: "button-wrapper",
mixins: [buttonMixin],
};
</script>

View file

@ -1,35 +0,0 @@
<template>
<label :class="{ classNames }">
value: {{value}} <br/>
modelValue: {{modelValue}} <br/>
isChecked: {{isChecked}} <br/>
<input
v-if="isMultiSelect"
type="checkbox"
:id="JSON.stringify(modelValue)"
:name="groupName"
:aria-required="isRequired"
:value="value"
:checked="isChecked"
@change="handleSelectionChange"
/>
<input
v-else
type="radio"
:id="JSON.stringify(modelValue)"
:name="groupName"
:aria-required="isRequired"
v-model="modelValue"
:checked="isChecked"
@change="handleSelectionChange"
/>
</label>
</template>
<script>
import buttonMixin from "../mixins/button-mixin";
export default {
name: "test-button",
mixins: [buttonMixin],
};
</script>

View file

@ -1,7 +1,28 @@
<template> <template>
<div> <div>
<h2>ListButton</h2>
selectedMultiselectValues: {{ selectedMultiselectValues }} selectedMultiselectValues: {{ selectedMultiselectValues }}
<button-question
questionText="This is a question?"
:answers="sampleAnswers"
:isMultiSelect="true"
groupName="multiselect-test"
v-model="selectedMultiselectValues"
></button-question>
<br /><br /><br />
selectedRadioValue: {{ selectedRadioValue }}
<button-question
questionText="This is another question?"
:answers="sampleAnswers"
:isMultiSelect="false"
groupName="radio-test"
v-model="selectedRadioValue"
></button-question>
<!-- selectedMultiselectValues: {{ selectedMultiselectValues }}
<button-question <button-question
buttonType="testButton" buttonType="testButton"
:answers="sampleAnswers" :answers="sampleAnswers"
@ -19,7 +40,7 @@
:isMultiSelect="false" :isMultiSelect="false"
groupName="radio-test" groupName="radio-test"
v-model="selectedRadioValue" v-model="selectedRadioValue"
></button-question> ></button-question> -->
</div> </div>
</template> </template>
@ -33,15 +54,15 @@ export default {
sampleAnswers: [ sampleAnswers: [
{ {
Text: "Part 1", Text: "Part 1",
Value: "PART1", Name: "PART1",
}, },
{ {
Text: "Part 2", Text: "Part 2",
Value: "PART2", Name: "PART2",
}, },
{ {
Text: "Part 3", Text: "Part 3",
Value: "PART3", Name: "PART3",
}, },
], ],
selectedMultiselectValues: [], selectedMultiselectValues: [],

View file

@ -1,4 +1,5 @@
export default { export default {
emits: ["change"],
model: { model: {
prop: "modelValue", prop: "modelValue",
event: "change", event: "change",
@ -32,22 +33,36 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
validationRules: {
type: String,
required: true,
},
classes: [String, Array, Object],
}, },
data() {},
methods: { methods: {
handleSelectionChange(event) { handleSelectionChange(event) {
console.log(event);
console.log(this.value);
console.log(this.modelValue);
let isChecked = event.target.checked; let isChecked = event.target.checked;
console.log("BM value: ", this.value);
let valueToEmit;
if (this.isMultiSelect && this.modelValue instanceof Array) { if (this.isMultiSelect && this.modelValue instanceof Array) {
let newValue = [...this.modelValue]; let newValue = [...this.modelValue];
if (isChecked && !newValue.includes(this.value)) { if (isChecked && !this.modelValue.includes(this.value)) {
newValue.push(this.value); newValue.push(this.value);
} else { } else {
newValue.splice(newValue.indexOf(this.value), 1); newValue.splice(newValue.indexOf(this.value), 1);
} }
this.$emit("change", newValue);
valueToEmit = newValue;
} else { } else {
this.$emit("change", isChecked); valueToEmit = isChecked;
} }
console.log("ButtonWrapper is emitting: ", valueToEmit);
this.$emit("change", valueToEmit);
// this.$emit("change", event);
}, },
}, },
computed: { computed: {
@ -57,5 +72,11 @@ export default {
} }
return this.modelValue === this.value; return this.modelValue === this.value;
}, },
inputType() {
return this.isMultiSelect ? "checkbox" : "radio";
},
buttonId() {
return JSON.stringify(this.value);
},
}, },
}; };

View file

@ -1,14 +1,8 @@
<template> <template>
<div <!-- <div
class="list-group list-button rounded-3 d-flex flex-column w-100 mb-2" class="list-group list-button rounded-3 d-flex flex-column w-100 mb-2"
:class="[(errors.length > 0 || hasError) ? 'has-error' : '']" :class="[(errors.length > 0 || hasError) ? 'has-error' : '']"> -->
@keyup.space="triggerButton" <!-- <input
@keyup.enter="triggerButton"
@keyup.up="handleKeyupArrow"
@keyup.down="handleKeyupArrow"
@keyup.left="handleKeyupArrow"
@keyup.right="handleKeyupArrow">
<input
:type="isMultiSelect ? 'checkbox' : 'radio'" :type="isMultiSelect ? 'checkbox' : 'radio'"
:id="buttonID" :id="buttonID"
:name="groupName" :name="groupName"
@ -17,39 +11,56 @@
v-model="checkValue" v-model="checkValue"
:checked="checkValue" :checked="checkValue"
@change="handleInputChange" @change="handleInputChange"
> > -->
<label <!-- <label
tabindex="-1" tabindex="-1"
:for="buttonID" :for="buttonID"
:aria-label="buttonLabel" :aria-label="buttonLabel"
class="d-flex flex-column justify-content-center py-3 px-4" class="d-flex flex-column justify-content-center py-3 px-4"
@mouseup="triggerButton" @mouseup="triggerButton"
> -->
LB value: {{ value }}<br />
LB modelValue: {{ modelValue }}
<!-- , {'has-error': errors.length > 0 || hasError} -->
<!-- <buttonWrapper
v-bind="$props"
:classes="['list-group list-button rounded-3 d-flex flex-column w-100 mb-2', {'has-error': errors.length > 0 || hasError}]"
@change="(e) => $emit('change', e)"
> -->
LB groupName: {{ groupName }}
<buttonWrapper
:isMultiSelect="isMultiSelect"
:modelValue="modelValue"
:value="value"
:groupName="groupName"
:classes="[
'list-group list-button rounded-3 d-flex flex-column w-100 mb-2',
{ 'has-error': errors.length > 0 || hasError },
]"
@change="lbTest"
>
<div
tabindex="-1"
:aria-label="buttonLabel"
class="list-button-content d-flex flex-column justify-content-center py-3 px-4"
> >
<span <span class="m-0" :class="textPosition">
class="m-0"
:class="textPosition"
>
{{ buttonLabel }} {{ buttonLabel }}
</span> </span>
<span <span v-if="buttonLabelSubCopy" class="m-0 small" :class="textPosition">
v-if="buttonLabelSubCopy"
class="m-0 small"
:class="textPosition"
>
{{ buttonLabelSubCopy }} {{ buttonLabelSubCopy }}
</span> </span>
<span <span v-if="screenReaderOnlyText" class="sr-only">
v-if="screenReaderOnlyText"
class="sr-only"
>
{{ screenReaderOnlyText }} {{ screenReaderOnlyText }}
</span> </span>
<loader <loader
v-if="isLoaderDisplayed && selectingInitiatesLoad" v-if="isLoaderDisplayed && selectingInitiatesLoad"
:class="[this.loaderColor, this.loaderPosition]" :class="[this.loaderColor, this.loaderPosition]"
/> />
</label> </div>
</div> </buttonWrapper>
<!-- </label> -->
<!-- </div> -->
</template> </template>
<script> <script>
@ -57,91 +68,99 @@ import { useField } from "vee-validate";
import { toRef } from "vue"; import { toRef } from "vue";
import loader from "@/ux-components/loader/loader"; import loader from "@/ux-components/loader/loader";
import { queryStrings } from "@/constants/query-strings"; import { queryStrings } from "@/constants/query-strings";
import buttonMixin from "@/mixins/button-mixin";
import buttonWrapper from "@/common-components/button-wrapper/button-wrapper";
export default { export default {
name: "listButton", name: "listButton",
mixins: [buttonMixin],
props: { props: {
isMultiSelect: Boolean, // groupName: String,
groupName: String,
buttonLabel: [Number, String], buttonLabel: [Number, String],
buttonID: [Number, String], buttonID: [Number, String],
isRequired: Boolean, // isRequired: Boolean,
textPosition: String, textPosition: String,
buttonLabelSubCopy: String, buttonLabelSubCopy: String,
screenReaderOnlyText: String, screenReaderOnlyText: String,
selectingInitiatesLoad: Boolean, selectingInitiatesLoad: Boolean,
loaderColor: String, loaderColor: String,
loaderPosition: String, loaderPosition: String,
value: {
// Field initial value
type: [String, Number],
default: "",
},
validationRules: String,
selectedValues: [Array, String],
hasError: Boolean, hasError: Boolean,
valueToLogType: String, valueToLogType: String,
}, },
data() { data() {
return { return {
isLoaderDisplayed: false, isLoaderDisplayed: false,
checkValue: false, // checkValue: false,
}; };
}, },
mounted() { // mounted() {
if (Array.isArray(this.validateValue)) { // if (Array.isArray(this.validateValue)) {
this.checkValue = this.isValueSelectedByArray(this.selectedValues); // this.checkValue = this.isValueSelectedByArray(this.selectedValues);
const isSelectedByValidator = this.isValueSelectedByArray(this.validateValue); // const isSelectedByValidator = this.isValueSelectedByArray(this.validateValue);
if (this.checkValue != isSelectedByValidator) { // if (this.checkValue != isSelectedByValidator) {
this.handleChange(this.value); // this.handleChange(this.value);
} // }
} // }
else { // else {
this.checkValue = this.selectedValues == this.value; // this.checkValue = this.selectedValues == this.value;
} // }
}, // },
emits: ["change"],
methods: { methods: {
isValueSelectedByArray(arr) { // isValueSelectedByArray(arr) {
return this.isMultiSelect // return this.isMultiSelect
? arr.includes(this.value) // ? arr.includes(this.value)
: arr[0]; // : arr[0];
}, // },
displayLoader() { displayLoader() {
this.isLoaderDisplayed = true; this.isLoaderDisplayed = true;
}, },
handleInputChange() { lbTest(e) {
if(!this.selectingInitiatesLoad) { console.log("lbTest event: ", e)
this.handleCheckChange(); this.$emit("change", e);
} },
}, // handleInputChange() {
handleKeyupArrow() { // if(!this.selectingInitiatesLoad) {
if (this.isMultiSelect) { // this.handleCheckChange();
return; // Prevent arrow keys from doing anything if element is a checkbox // }
} // },
}, // handleKeyupArrow() {
// if (this.isMultiSelect) {
// return; // Prevent arrow keys from doing anything if element is a checkbox
// }
// },
triggerButton() { triggerButton() {
if(this.selectingInitiatesLoad) { if (this.selectingInitiatesLoad) {
this.displayLoader(); this.displayLoader();
this.handleCheckChange(); // this.handleCheckChange();
} }
this.pushEventToGA(this.$route.query[queryStrings.FMG_PAGE], this.GaActions.CLICKED, this.value.toString(), true, this.valueToLogType);
},
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.handleChange(this.value); // TODO KO THIS IS IMPORTANT
this.$emit("isCheckedChanged", emitEvent); this.pushEventToGA(
this.$emit("update:modelValue", emitEvent); this.$route.query[queryStrings.FMG_PAGE],
this.GaActions.CLICKED,
this.value.toString(),
true,
this.valueToLogType
);
}, },
// 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.handleChange(this.value);
// this.$emit("isCheckedChanged", emitEvent);
// this.$emit("update:modelValue", emitEvent);
// },
}, },
components: { components: {
loader, loader,
buttonWrapper,
}, },
setup(props) { setup(props) {
const inputType = props.isMultiSelect ? "checkbox" : "radio"; const inputType = props.isMultiSelect ? "checkbox" : "radio";
@ -154,15 +173,19 @@ export default {
// Set initialValue for validation setup if pre-selected // Set initialValue for validation setup if pre-selected
// NOTE: props.selectedValues could be an array of strings, or an array of integers... // NOTE: props.selectedValues could be an array of strings, or an array of integers...
if (props.selectedValues && (props.selectedValues.includes(props.value) || props.selectedValues.includes(parseInt(props.value)))) { if (
fieldOptions['initialValue'] = fieldOptions.potentialInitialValue; props.selectedValues &&
(props.selectedValues.includes(props.value) ||
props.selectedValues.includes(parseInt(props.value)))
) {
fieldOptions["initialValue"] = fieldOptions.potentialInitialValue;
} }
const { const { handleChange, errors, value } = useField(
handleChange, toRef(props, "groupName"),
errors, toRef(props, "validationRules"),
value fieldOptions
} = useField(toRef(props, "groupName"), toRef(props, "validationRules"), fieldOptions); );
const validateValue = value; const validateValue = value;
@ -186,32 +209,32 @@ export default {
height: 0; height: 0;
opacity: 0; opacity: 0;
&:focus-visible + label { &:focus-visible + .list-button-content {
box-shadow: 0 0 0 2.5px $blue; box-shadow: 0 0 0 2.5px $blue;
} }
&:focus + label { &:focus + .list-button-content {
box-shadow: 0 0 0 2.5px $blue; box-shadow: 0 0 0 2.5px $blue;
} }
&:checked + label { &:checked + .list-button-content {
color: $black; color: $black;
font-weight: 500; font-weight: 500;
background: $blue-100; background: $blue-100;
box-shadow: 0 0 0 1px $blue; box-shadow: 0 0 0 1px $blue;
} }
&:checked:focus + label { &:checked:focus + .list-button-content {
box-shadow: 0 0 0 2.5px $blue; box-shadow: 0 0 0 2.5px $blue;
} }
&:checked + label p, &:checked + .list-button-content p,
&:checked + label span { &:checked + .list-button-content span {
font-weight: 500; font-weight: 500;
} }
&:checked + label span:nth-child(2) { &:checked + .list-button-content span:nth-child(2) {
font-weight: 400; font-weight: 400;
color: $gray-600; color: $gray-600;
} }
} }
} }
label { .list-button-content {
color: $gray-600; color: $gray-600;
position: relative; position: relative;
background: $white; background: $white;
@ -223,7 +246,7 @@ export default {
span { span {
&.small { &.small {
font-size: .75rem; font-size: 0.75rem;
color: $gray-550; color: $gray-550;
} }
} }