Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursor jumps to end of mask if changing value during typing #2274

Closed
jurchiks opened this issue Feb 18, 2020 · 10 comments
Closed

Cursor jumps to end of mask if changing value during typing #2274

jurchiks opened this issue Feb 18, 2020 · 10 comments

Comments

@jurchiks
Copy link

There is an annoying bug that happens when changing the value during typing.
If I edit the typed value while typing, the cursor jumps to the end of the mask instead of after the last filled character and you cannot continue typing, even though the value is incomplete.

https://jsfiddle.net/jurchiks/5cro9k3z/9/

  • OS: Windows 10 Home x64
  • Browser: Chrome, Firefox, Edge, IE11
  • Inputmask version: 5.0.4-beta.8

Here's why I'm doing it.
The international input mask for Lithuanian phone numbers is +3709{8}. Normally, this is not a problem, because decent people see the +370 and automatically understand that they only have to type the remaining 8 digits.
However, some Lithuanians have this odd habit of writing their number with a prefix of 8 (i.e. 89{8}). This poses a problem, because we want to get rid of the 8 since it's the local equivalent of +370.
Normally, I would just trim the 8 if the number starts with it, but this doesn't work, because the cursor jumps to the very end of the mask as soon as I set the trimmed value.

Assuming trimmedValue = number.substring(1), I've tried input.value = trimmedValue, input.value = '+370' + trimmedValue, $(input).val(trimmedValue), $(input).val('+370' + trimmedValue), $(input).inputmask('setvalue', trimmedValue), $(input).inputmask('setvalue', '+370' + trimmedValue), and trimming when the number is at various lengths, but every single time the cursor jumps to the end.

The only workaround I found at the moment is to trim the value when it's fully typed in (you can see how that works by changing /^\+3708\d{6}/ to /^\+3708\d{7}/ in the fiddle).
It works, but it has the potential to trick the inattentive user into thinking that they already typed the number in and that they can switch to the next input field in the form. I'd very much like to avoid that, so if you have any suggestions as to how I could solve this problem more elegantly, I'm all ears.

As for the separate handler for pasting - since the mask is +3709{8}, this means that pasting a number like 877665544 would strip the last digit (it has happened before) and that is not what we want, so I'm forced to read directly from the clipboard to find out if the pasted value was indeed the oddly prefixed number. Again, I don't like this solution, but it's the only one I know of that works...

This issue only came up when I updated to the latest version of inputmask; before that, my code looked like this:

$('phone number input selector').on('keyup', function() {
        var $input = $(this);
        var value = $input.val();

        if (value && /^\+3708/.test(value)) {
            $input.val(value.replace('+370', ''));
            $input.attr('data-rule-pattern', '8\\d{8}');
            $input.rules('remove'); // there is no `replace`, and this cannot be chained either :(
            $input.rules('add', { pattern: '8\\d{8}' });

            $input.attr('data-inputmask', "'mask': '899999999'");
            $input.attr('placeholder', '8');
            $input.inputmask();
        }
    })

and the 8 was handled in back-end. However, this broke in the latest version, and typing 8 into such an input (same initial inputmask in every version) resulted in +370... being converted into 83708..., which is terrible, since we irreversibly lost 4 digits of the actual phone number.

I opted to get rid of this monstrosity altogether, but it resulted in a lot of headache...

@RobinHerbots
Copy link
Owner

RobinHerbots commented Feb 18, 2020 via email

@jurchiks
Copy link
Author

That is unfortunate, but at least I have the workaround for the time being.
Get well soon!

@RobinHerbots
Copy link
Owner

@jurchiks ,
Have a look at
https://jsfiddle.net/18wdLfk4/2/

@jurchiks
Copy link
Author

Well, it works, but I see that as a hack since it involves exposing the library's internals, and it's worse than what I currently have, since I don't actually set my masks directly on the elements, I do $('.masked').inputmask(), and then additionally for .masked.phone I do this magic.
I don't really care much about the pasting part, I only care about the cursor jumping to the end when replacing the value. Is it hard to make it jump to the right place in the mask?

@RobinHerbots
Copy link
Owner

@jurchiks ,

It is an example. You can always create an alias for it or something. The postvalidation is an option so not really internal. https://jsfiddle.net/9s6nrqh8/

Anyway, you can always trigger a click event within a settimeout.

@RobinHerbots
Copy link
Owner

@jurchiks ,
Example with the click event
https://jsfiddle.net/9s6nrqh8/1/

@jurchiks
Copy link
Author

Yeah, I definitely prefer the timeout.

@RobinHerbots
Copy link
Owner

@jurchiks,

And another one https://jsfiddle.net/3ou1y96w/

Because value.substring(5) passes 776655_ as value the last check in checkval returns false, resulting in not setting the caret. Stripping the _ fixes this, ... but I might also fix this in checkval.

@RobinHerbots
Copy link
Owner

@jurchiks,

Here we are back with the original fiddle only updating the inputmask lib

https://jsfiddle.net/eg0q2sz1/1/

@jurchiks
Copy link
Author

Excellent, works just as expected now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants