cleave.js
cleave.js copied to clipboard
Phone/Numeric mask adds extra digit after blur / Using prefix prevents user from selecting all & deleting
Hi all,
I love Cleave, but I've always had this issue when trying to add masks to phone numbers. To recreate the issue, I've setup a Codepen here, I'm using Cleave with Vue:
https://codepen.io/MatrixClaw/pen/JjYXqKb
The first input uses the US region phone configuration:
{
phone: true,
phoneRegionCode: 'US'
}
The second uses a custom mask to add parentheses and dashes to the phone number:
{
numericOnly: true,
prefix: '(',
delimiters: [') ', '-'],
blocks: [4, 3, 4],
noImmediatePrefix: true
}
When I type in a phone number, Cleave correctly masks the input according to the rules, but then on blur, if you've over-typed, it adds an extra digit at the end.
Alternatively, if you try to select everything in the custom mask field and delete it, nothing happens (this seems to only happen if you use a prefix). You have to delete each character one by one. I've added a third example removing the prefix and adding it as a delimiter to demonstrate:
{
delimiters: ['(', ') ', '-'],
blocks: [0, 3, 3, 4],
numericOnly: true
}
Here's a short video for clarity:
https://video.drift.com/v/abylKah1gX7/
Any ideas what's going on here??
I have the same issue =(
I use the same custom component as @chrisvfritz show in is vue entreprise boilerplate and I've the same issue. If I'm not using a custom component it's working fine. Did you found any alternative ?
@DinsmoreDesign @demyan1411 I found the solution. You need to change the directive like this :
inserted: (el, binding) => {
const element = el.tagName === 'INPUT' ? el : el.querySelector('input')
element.cleave = new Cleave(element, binding.value || {})
},
update: (el) => {
const element = el.tagName === 'INPUT' ? el : el.querySelector('input')
const event = new Event('input', { bubbles: true })
requestAnimationFrame(() => {
element.value = element.cleave.properties.result
element.dispatchEvent(event)
})
}
Tell me if it's working on your side.
@DinsmoreDesign @demyan1411 I found the solution. You need to change the directive like this :
inserted: (el, binding) => { const element = el.tagName === 'INPUT' ? el : el.querySelector('input') element.cleave = new Cleave(element, binding.value || {}) }, update: (el) => { const element = el.tagName === 'INPUT' ? el : el.querySelector('input') const event = new Event('input', { bubbles: true }) requestAnimationFrame(() => { element.value = element.cleave.properties.result element.dispatchEvent(event) }) }
Tell me if it's working on your side.
We were having the same issue. I added these to the directive and it seemed to fix things on my end. Thanks @KaliaJS
@calebwaldner Glad I was able to help someone. Here is the version for Vue3 :
import Cleave from 'cleave.js'
export default {
mounted: (element, { value }) => {
const input = element.tagName === 'INPUT' ? element : element.querySelector('input')
input.cleave = new Cleave(input, value || {})
},
updated: (element) => {
const input = element.tagName === 'INPUT' ? element : element.querySelector('input')
const event = new Event('input', { bubbles: true })
requestAnimationFrame(() => {
input.value = input.cleave.properties.result
input.dispatchEvent(event)
})
},
}