DigitalConsumer.FixMyGlass/src/common-components/button-question/button-question.vue
2022-04-28 09:29:24 -04:00

173 lines
5.5 KiB
Vue

<!-- Documented in confluence https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Component -->
<template>
<div :class="isOverflowScrollable ? 'button-question button-question-overflow' : 'button-question'">
<div v-if="questionText" :class="[this.buttonType === 'radio' ? ['mt-2', 'mb-0'] : ['mt-5', 'mb-4'], 'd-flex']">
<span class="fs-5 fw-bold w-100" :class="this.buttonType === 'radio' ? 'text-start' : 'text-center'">{{ questionText }}</span>
</div>
<div class="w-100 d-flex justify-content-center">
<fieldset class="w-100" :aria-required=isRequired :class="getFieldSetClasses" :role="isMultiSelect ? 'group' : 'radiogroup'" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
<legend class="sr-only" :data-focus-target="groupName" tabindex="-1">
{{(isMultiSelect && answers && answers.length > 1) ? 'Select one or more options below.' : 'Select an option below.' }}
</legend>
<div :class="getComponentWrapperClasses">
<component
:is="buttonType"
v-for="answer in answers"
:key="answer.Name ? answer.Name : answer"
@isCheckedChanged="handleCheckedChanged"
:buttonID="answer.Name ? groupName + '-' + answer.Name : groupName + '-' + answer"
:value="getValues(answer)"
:buttonLabel="answer.Text ? answer.Text : answer"
:buttonLabelSubCopy="answer.SubText"
:textPosition="textPosition"
:isMultiSelect="isMultiSelect"
:groupName="groupName"
:selectingInitiatesLoad="selectingInitiatesLoad"
:loaderColor="loaderColor"
:loaderPosition="loaderPosition"
:isWide=isWide
:isRequired=isRequired
:buttonImage="answer.AnswerImageUrl"
:buttonImageId="answer.ImageId"
:altText="answer.Name ? answer.Name : answer"
screenReaderOnlyText="(opens new window)"
:colLength="getColLength"
:selectedValues="selectedValues"
data-test="button"
:validationRules="validationRules"
:class="[suppressError ? 'alertError' : '']"
/>
</div>
</fieldset>
</div>
<div class="row mt-2 form-test-error">
<error-message :name="groupName" v-if="!suppressError"></error-message>
</div>
</div>
</template>
<script>
import listButton from "@/ux-components/list-button/list-button";
import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-button-horizontal";
import listCard from "@/ux-components/list-card/list-card";
import { ErrorMessage } from 'vee-validate';
import radio from "@/ux-components/radio/radio";
export default {
name: "buttonQuestion",
props: {
buttonType: {
type: String,
default: "listButton",
},
isMultiSelect: Boolean,
groupName: String,
questionText: String,
answers: Array,
textPosition: {
type: String,
default: "text-center",
},
selectingInitiatesLoad: Boolean,
loaderColor: {
type: String,
default: "blue",
},
loaderPosition: {
type: String,
default: "right",
},
isRequired: Boolean,
isOverflowScrollable: Boolean,
isWide: Boolean,
modelValue: Array,
validationRules: String,
suppressError: Boolean,
useTextForValue: Boolean,
},
computed: {
getFieldSetClasses() {
return this.isOverflowScrollable
? "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"
: "";
},
getComponentWrapperClasses() {
let classes;
switch (this.buttonType) {
case "listButton":
classes = "w-100";
break;
case "listButtonHorizontal":
classes = "d-flex flex-row p-0";
break;
case 'listCard':
classes = 'row justify-content-center g-2'
break;
case 'radio':
classes = 'ui-radio d-flex'
break;
}
return classes;
},
getColLength(){
if(this.isWide) {
return "12"
} else {
return this.answers.length < 3 ? '' : '-4';
}
},
selectedValues: {
get: function() {
return this.modelValue;
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
},
},
methods: {
getValues(answer){
if (this.useTextForValue){
return answer.Text
}
return answer.Name ? answer.Name : answer;
},
handleCheckedChanged(val) {
if(this.isMultiSelect && this.selectedValues) {
// Add or remove item to array of data to emit
const newSelectedValues = this.selectedValues;
if(Array.isArray(this.selectedValues)) {
val.checkValue ? newSelectedValues.push(val.value) : newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1);
this.selectedValues = newSelectedValues;
}
} else {
this.selectedValues = [val.value];
}
},
},
components: {
listButton,
listButtonHorizontal,
listCard,
ErrorMessage,
radio,
},
};
</script>
<style lang="scss" scoped>
.button-question-overflow {
height: calc(100vh - 266px);
.overflow-scroll {
// Height will be determined by overall height of content above list
height: calc(100% - 314px);
overflow-x: hidden !important;
-webkit-overflow-scrolling: touch;
}
}
.button-question {
color: $black;
}
</style>