DigitalConsumer.FixMyGlass/src/digital-components/dropdown-question/dropdown-question.vue
2024-08-27 16:18:22 -04:00

164 lines
4.9 KiB
Vue

<template>
<div
class="dropdown-question"
:class="(errors && errors.length) || hasError ? 'has-error' : ''">
<label
:for="dropdownId"
:aria-label="questionText"
class="form-label"
v-html="questionText"></label>
<select
v-model="selectedOption"
class="form-select"
:id="dropdownId"
:name="dropdownId"
:aria-disabled="isDisabled"
:disabled="isDisabled"
:aria-required="isRequired"
:validationRules="validationRules"
:placeHolderText="placeHolderText"
:valueAsKey="valueAsKey">
<option v-if="placeHolderText" value="" selected>{{ placeHolderText }}</option>
<option
v-for="(value, name, index) in options"
:value="valueAsKey == true ? value : name"
:key="valueAsKey == true ? value : index">
{{ value }}
</option>
</select>
<div v-show="errorMessage && this.disableValidation" class="row mt-2 form-test-error">
<span aria-atomic="true" aria-live="polite">{{ errorMessage }}</span>
</div>
</div>
</template>
<script>
import { useField } from "vee-validate";
import { v4 as uuidv4 } from "uuid";
export default {
name: "dropdown-question",
props: {
customDropdownId: String,
options: {
type: Object,
required: true,
},
modelValue: String,
isDisabled: Boolean,
isRequired: Boolean,
validationRules: String,
placeHolderText: String,
cmsWidgetName: String,
hasError: Boolean,
valueAsKey: {
type: Boolean,
required: false,
default: false,
},
disableValidationIfElementDisabled: {
type: Boolean,
required: false,
default: false,
},
},
setup(props) {
const uuid = uuidv4();
const dropdownId = !props.customDropdownId ? `dropdown-${uuid}` : props.customDropdownId;
const propsClone = Object.assign({}, props);
const modelValue = propsClone.modelValue;
let initialValue;
switch (typeof modelValue) {
case "number":
initialValue = modelValue;
break;
default:
initialValue = modelValue && modelValue.length > 0 ? modelValue : "";
break;
}
const fieldOptions = {
type: "select",
value: props.modelValue,
initialValue: initialValue,
};
const { errorMessage, handleBlur, handleChange, meta, errors } = useField(
dropdownId,
props.validationRules,
fieldOptions
);
return {
dropdownId,
errorMessage,
handleBlur,
handleChange,
meta,
errors,
};
},
mounted() {
this.$emit("dropdownQuestionEvent.inputIdAssigned", this.inputId);
},
computed: {
questionText() {
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
},
selectedOption: {
get: function () {
return !this.modelValue ? "" : this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
},
},
disableValidation() {
return this.disableValidationIfElementDisabled ? !this.isDisabled : true;
},
},
watch: {
selectedOption(newValue) {
this.handleChange(newValue);
},
},
};
</script>
<style lang="scss">
.dropdown-question {
label {
color: $black;
font-weight: 500;
}
.form-label {
margin-bottom: 0.25rem;
}
.form-select {
color: $gray-600;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.89' xml:space='preserve'%3e%3cpath d='M8 8.89c-.24 0-.46-.09-.63-.26L.26 1.53a.901.901 0 0 1 0-1.27C.43.1.66 0 .9 0s.47.1.64.26L8 6.74 14.47.27c.17-.17.4-.27.64-.27s.47.1.63.27c.17.17.26.4.26.64s-.1.47-.27.63l-7.1 7.09a.86.86 0 0 1-.63.26z' fill='%231474a2'/%3e%3c/svg%3e");
border: 1px solid $gray-500;
border-radius: 0.5rem;
min-height: 3rem;
&:focus,
&:focus-visible {
box-shadow: 0 0 0 2.5px $blue;
}
&:disabled,
&.disabled {
background-color: $gray-100;
filter: grayscale(100%);
&:hover {
box-shadow: 0 0 0 4px transparent;
border: 1px solid $gray-500;
}
}
&:hover {
border: 1px solid $gray-500;
box-shadow: 0 0 0 4px $blue-300;
}
}
}
</style>