DigitalConsumer.ISS/src/digital-components/dropdown-question/dropdown-question.vue
DavidAtSafelite 80509bda53 We have advanced the code enough to call this one 8.5
It has more layout page linting and I have removed (really re-removed) the reduntant router parms.
2023-08-23 07:16:58 -04:00

174 lines
5 KiB
Vue

<template>
<div
class="dropdown-question"
:class="(errors && errors.length) || hasError ? 'has-error' : ''">
<label
:for="inputId"
:aria-label="questionText"
class="form-label"
v-html="labelText"></label>
<select
:id="inputId"
v-model="selectedOption"
class="form-select"
:name="inputId"
:aria-disabled="isDisabled"
:disabled="isDisabled"
:aria-required="isRequired"
:validationRules="validationRules"
:placeHolderText="placeHolderText">
<option
v-if="placeHolderText"
value=""
selected>
{{ placeHolderText }}
</option>
<option
v-for="(value, name, index) in options"
:key="index"
:value="name">
{{ value }}
</option>
</select>
<div
v-show="errorMessage"
class="row mt-1 form-test-error">
<span role="alert">{{ errorMessage }}</span>
</div>
</div>
</template>
<script>
import { useField } from 'vee-validate';
export default {
name: 'dropdown-question',
props: {
modelValue: String,
inputId: String,
options: {
type: Object,
required: true
},
isDisabled: Boolean,
isRequired: Boolean,
disableAutoFill: Boolean,
validationRules: String,
cmsWidgetName: String,
hasError: Boolean,
placeHolderText: String
},
emits: ['update:modelValue'],
setup(props) {
const propsClone = { ...props };
const { modelValue } = propsClone;
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
};
const { errorMessage, handleBlur, handleChange, meta, errors } = useField(props.inputId,
props.validationRules,
fieldOptions);
return {
errorMessage,
handleBlur,
handleChange,
meta,
errors
};
},
computed: {
questionText() {
return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
},
selectedOption: {
get() {
return !this.modelValue ? '' : this.modelValue;
},
set(newValue) {
this.$emit('update:modelValue', newValue);
}
},
labelText: {
get() {
const noBreakChar = '&NoBreak;';
let questionText = '';
if (this.disableAutoFill) {
const words = this.questionText.toString().split(/[ ]+/);
words.forEach((word) => {
const position = 1;
const newWord = [
word.toString().slice(0, position),
noBreakChar,
word.toString().slice(position)
].join('');
questionText += `${newWord} `;
});
questionText = questionText.trimEnd();
} else {
questionText = this.questionText.toString();
}
return questionText;
}
}
},
watch: {
selectedOption(newValue) {
this.handleChange(newValue);
}
}
};
</script>
<style lang="scss" scoped>
.dropdown-question {
label {
color: $black;
font-weight: 500;
}
.form-label {
margin-bottom: 0.25rem;
}
.form-select {
border: 1px solid $gray-500;
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");
color: $gray-600;
border-radius: 0.5rem;
min-height: 3rem;
&:focus,
&:focus-visible {
box-shadow: 0 0 0 2.5px $blue;
}
&:disabled,
&.disabled {
background-color: $gray-100;
color: $gray-500;
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>