uNmAnNeR / imaskjs

vanilla javascript input mask
https://imask.js.org
MIT License
4.86k stars 249 forks source link

It's moving cursor end of the mask on first focus #916

Open fatihturan opened 1 year ago

fatihturan commented 1 year ago

Describe the bug When you click on the input as first time, it's moving the cursor to end of mask characters and can't write anything in the input.

See screen recording below:

https://github.com/uNmAnNeR/imaskjs/assets/26871/c2eca9f7-661f-47ed-a82d-ccce9bb5169b

To Reproduce

  1. Enter the sample form in this web site
  2. Click on the Phone input
  3. Try to write something.
  4. If you click outside and re-click on the input, it's working as expected.

Expected behavior It must move the cursor at the start and it would allow to write in the input.

Environment:

Additional context I added two event listener that updates the lazy option to false when you focus and set it true when you lost the focus on the input. Because I want to show default placeholder until users fill the input.

    const element = document.getElementById('phone');
    const maskOptions = {
        mask: '(000) 000-0000',
    };
    const mask = IMask(element, maskOptions);

    phone.addEventListener('focus', function() {
        mask.updateOptions({
            lazy: false
        });
    })

    phone.addEventListener('blur', function() {
        mask.updateOptions({
            lazy: true
        });
    })
dakota-kallas commented 1 year ago

I had the same issue. It is because the masking characters are being placed on the screen before the on click event is being registered. The only way for me to get around it was to put a wait timer on the focus/blur event listeners for 1ms, so it gave time for the onclick event to happen first. Something like this:

phone.addEventListener('focus', function() { setTimeout(() => { mask.updateOptions({ lazy: false }); }, 1); })

It's definitly a workaround, but it would be nice if this was fixed natively for the plugin. I breifly mentioned the issue in #900 but to no avail.

fatihturan commented 1 year ago

Hi @dakota-kallas,

Unfortunately it didn't help to solve the issue. The issue still persist.

https://github.com/uNmAnNeR/imaskjs/assets/26871/dc9f138f-bfe5-4735-944f-5d7c7ee9452a

You can see it live from here.

gterras commented 11 months ago

Same problem on a mask with spaces, I can confirm waiting for the DOM to be updated does the trick. In Svelte :

const focus = async (el) => tick().then(() => el.focus())
<input use:focus ... />
mallchel commented 8 months ago

In my case, the selectionEnd in safari becomes to 0 seems like on its own. and in time of select method in imask/esm/controls/mask-element.js we have early return because end === this.selectionEnd but caret in UI is still in the end 🤯

image

image
howlettt commented 1 month ago

Another way to fix this: set lazy=false always and toggle the transparency of the input text instead, something like:

color: isFocused || (value !== null && value !== undefined) ? undefined : "transparent"