175 lines
5.3 KiB
Vue
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>
|