DigitalConsumer.FixMyGlass/src/digital-components/phonenumber-question/phonenumber-question.vue
2023-05-23 15:36:28 -04:00

175 lines
5.3 KiB
Vue

<template>
<div
class="phonenumber-question d-flex flex-column"
:class="[
(errors && errors.length) || hasError ? 'has-error' : '',
hideInput ? 'hide-input' : '',
]">
<textboxQuestion
maxLength="12"
v-model="selectedValue"
:isRequired="isRequired"
:validationRules="validationRules"
pattern="[0-9\-]+"
:keyDownHandler="onKeyDown"
cmsWidgetName="phoneNumberQuestionWidget"
/>
<!-- <label for="phone-number" class="mb-1 fw-bold" v-html="phoneNumberQuestionWidget"></label>
<input
class="form-control"
id="phone-number"
name="phone-number"
v-model="phoneNumber"
@input="formatPhoneNumber"
@change="handleChange"
@blur="handleChange"
:maxlength="phoneNumberMaxLength"
pattern="[0-9\-]+"
:aria-required="isRequired"
:validationRules="validationRules" /> -->
<div v-show="errorMessage" class="row my-1 form-test-error">
<span
class="d-inline-flex small mt-0"
role="alert"
:class="[centerErrorMessage ? 'center-error-message' : '']"
>{{ errorMessage }}</span
>
</div>
</div>
</template>
<script>
import textboxQuestion from "@/digital-components/textbox-question/textbox-question";
//Supporting files
import { errorMessages } from "@/constants/error-messages";
import { required, regex } from "@/helpers/validation-rules";
import { Form, defineRule } from "vee-validate";
import { useField, validate } from "vee-validate";
//Validation
defineRule(
"phone-number-format",
regex(/^(?=(?:.*\d){10})(?=(?:.*-){2})[\d-]{12}$/, errorMessages.PHONE_FORMAT)
);
export default {
name: "phoneNumberQuestion",
props: {
cmsWidgetName: String,
isRequired: Boolean,
validationRules: String,
hasError: Boolean,
centerErrorMessage: Boolean,
modelValue: String,
},
setup(props) {
const inputId = !props.customInputId ? `input-${crypto.randomUUID()}` : props.customInputId;
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: "text",
value: modelValue,
initialValue: initialValue,
};
const { errorMessage, handleBlur, handleChange, meta, validate, errors } = useField(
inputId,
props.validationRules,
fieldOptions
);
return {
inputId,
errorMessage,
handleBlur,
handleChange,
validate,
meta,
errors,
};
},
data() {
return {
phoneNumberMaxLength: 12,
};
},
computed: {
phoneNumberQuestionWidget() {
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
},
selectedValue: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
const formattedNumber = this.formatPhoneNumber(newValue);
this.$emit("update:modelValue", formattedNumber);
},
},
},
methods: {
formatPhoneNumber(value) {
// Remove all non-digit characters from the phone number
let formattedNumber = value.replace(/\D/g, "");
// Insert hyphens after the first three and the next three digits
if (formattedNumber.length > 3) {
formattedNumber = formattedNumber.slice(0, 3) + "-" + formattedNumber.slice(3);
}
if (formattedNumber.length > 7) {
formattedNumber = formattedNumber.slice(0, 7) + "-" + formattedNumber.slice(7);
}
// Update the phone number with the formatted version
return formattedNumber;
},
onKeyDown(event) {
if (this.selectedValue.length === 0 && event.key === "1") {
event.preventDefault();
}
this.formatPhoneNumber(event.target.value + event.key);
}
},
watch: {
async value(newValue) {
const result = await validate(newValue, this.validationRules); // do a test validation check, without triggering full validation
if (result.valid) {
this.handleChange(newValue); // trigger full validation on this field only
}
},
},
components: {
textboxQuestion
}
};
</script>
<style lang="scss">
.phonenumber-question {
label {
color: $black;
}
input {
border-radius: 0.5rem;
border: 1px solid $gray-500;
height: 48px;
&:focus {
box-shadow: 0 0 0 2.5px $blue;
outline: none;
}
&:hover {
box-shadow: 0 0 0 4px $blue-300;
}
}
}
</style>