NumberFrmate
unknown
javascript
a year ago
4.2 kB
5
Indexable
<template> <div class="mb-0 input-form" :class="divClass"> <FormBaseLabel v-if="label" :label="label" :required="required" /> <div class="phone_field"> <input :id="id" :name="type" :type="type" v-model.trim="telNumber" @input="numberFormatting" @focus="focus" @keydown="keydownHandler" v-bind="$attrs" :placeholder="placeholder" class="form_input" :class="[errorMessage || error ? 'isWarning' : '', classes]" :style="{ paddingLeft: type === 'search' ? '40px' : '' }" :autocomplete="autocomplete" :disabled="disabled" :autofocus="autofocus" :required="required" :min="min" :max="maxNumberLength" ref="inputRef" /> </div> </div> <transition name="fade-in"> <p class="form_error_message" v-if="error"> <Icon name="ri:error-warning-fill" /> <span>{{ error }}</span> </p> </transition> </template> <script setup> const props = defineProps({ modelValue: { type: [String, Number], default: 0, }, type: { type: String, default: 'tel', // Possible values: 'text', 'phone' }, label: { type: String, default: '', }, id: { type: String, default: '', }, name: { type: String, default: '', }, placeholder: { type: String, default: '019XXXXXXXX', }, divClass: { type: String, default: '', }, classes: { type: String, default: '', }, required: { type: Boolean, default: false, }, error: { type: String, default: '', }, autocomplete: { type: String, default: 'off', }, disabled: { type: Boolean, default: false, }, autofocus: { type: Boolean, default: false, }, sanitizeInput: { type: Boolean, default: false, }, min: { type: Number, default: null, }, max: { type: Number, default: 11, }, }); const emit = defineEmits(['update:modelValue']); const errorMessage = ref(''); const telNumber = ref(''); const maxNumberLength = ref(props.max); const inputRef = ref(null); const isError = ref(false); let value = ''; // formate BD mobile & tel number const formatPhone = (str) => { const digits = String(str)?.replace(/\D/g, ''); if (/^02/.test(digits) && digits.length <= 9) { maxNumberLength.value = 9; isError.value = false; return `${digits.slice(0, 2)}-${digits.slice(2)}`; } if ((/^01/.test(digits) || /^09/.test(digits)) && digits.length <= 11) { maxNumberLength.value = 11; isError.value = false; return `${digits.slice(0, 5)}-${digits.slice(5)}`; } return ''; }; // remove hyphen const keydownHandler = (e) => { if (e.key === 'Backspace' && telNumber.value.endsWith('-')) { e.preventDefault(); telNumber.value = telNumber.value.slice(0, -1); } }; const numberFormatting = (e) => { const formattedNumber = formatPhone(e.target.value); if (formattedNumber !== '') { telNumber.value = formattedNumber; value = formattedNumber; } else { e.target.value = telNumber.value; isError.value = true; } // prevent input if exceed maximum length if (telNumber.value.length >= maxNumberLength.value) { telNumber.value = value; e.preventDefault(); } emit('update:modelValue', telNumber.value?.replace('-', '')); }; const focus = () => { telNumber.value = telNumber.value; }; watch( () => isError.value, (newVal, oldVal) => { if (newVal) { errorMessage.value = 'Please input a valid number'; } else { errorMessage.value = ''; } }, { deep: true, immediate: true }, ); // set default value watchEffect(() => { if (isEmpty(telNumber.value)) { telNumber.value = formatPhone(props.modelValue); } }); const focusInput = () => { if (inputRef.value && inputRef.value.focus) { inputRef.value.focus(); } }; onMounted(() => { if (props.autofocus) { focusInput(); } }); </script>
Editor is loading...
Leave a Comment