plentz / jquery-maskmoney

jQuery plugin to mask data entry in the input text in the form of money (currency).
https://plentz.github.io/jquery-maskmoney/
MIT License
964 stars 505 forks source link

Not working on smartphones #126

Open jhonathanvini opened 10 years ago

jhonathanvini commented 10 years ago

Tested at the demo page to confirm it wasn't a problem with my implementation, on a Galaxy S4 and Iphone 4S.

The mask isn't applied, the numbers won't through the decimal point as normal, they keep being added at the end of the current value.

After you move to another field and get back the mask is correctly applied.

Reproduce steps:

1 - Original value: 0.00 2 - type 123: 0.00123 (digits added to the end) 3 - move to another field: 0.00123 (nothing happens) 4 - get back to the original field: 1.23 (mask is applied)

Thanks in advance!

Regars

Take Care

jglawrence commented 10 years ago

Any updates on this? We are seeing the same issues on a Galaxy S4

plentz commented 10 years ago

@jglawrence not really. we have a few bugs in the line, but this one I didn't even took a look. if you guys can provide a pull request, I can merge and release another version sooner. thanks in advance :)

ghost commented 10 years ago

Same thing. Any updates? Thanks!

sk8sta13 commented 10 years ago

I had the same problem, and the research that made ​​navigating the android does not detect these evendos: (event.keyCode, event.which and event.charCode), if your plugin is using it can be is your problem.

I managed to solve but tested only on androids, if my solution was to not use these events if I was on a android, I used the direct character

steimntz commented 10 years ago

This bug happen on the Galaxy S4 mini as well.

sk8sta13 commented 9 years ago

Hi guys, well steimntz is likely that this problem also aconteceça in S4 Galaxy mini.

In the research I have done, as I said earlier was to detect the keyboard event (event.keyCode, event.which and event.charCode), so I managed to solve the problem fazerndo mascaras with regular expreções. Veja aqui: https://github.com/sk8sta13/maskregex, testing can be done in http://www.sk8sta13.dx.am

I made some test:

Safari 6.2 Iphone 5s, everything worked correctly 100% ok;

Google Chrome 4.1 Android 4.2.2 Samsung Duos Gran, the "setted" property does not work, the other features are ok; Native browser on Android 4.2.2 Samsung Duos Gran, did not work properly;

Nabegador Windows Phone Nokia Lumia 900 on one, did not work properly; I'll find a way to test more frequently in windows phone, do not have easy access to this system, I am currently looking for an emulator operating system.

tahb commented 8 years ago

Found this exact issue today with android 5x, native browser and chrome.

fpupor commented 8 years ago

Sk8sta13, The great solution for mobile devices... i change type for tel, auto open number keyboard... https://jsfiddle.net/7vwe3Lya/6/

rafaelmb commented 8 years ago

This is still a bug. I couldn't manage a way to solve this.

kikomesquita commented 8 years ago

For Android Crhome the event.keyCode and event.which on the 'keypressEvent' event always returns 0.

To fix use the funcion keypressEvent like this:

`function keypressEvent(e) { e = e || window.event; var key = e.which || e.charCode || e.keyCode, keyPressedChar, selection, startPos, endPos, value; //added to handle an IE "special" event if (key === undefined) { return false; }

                //for android chrome keycode fix
                if (key == 0 || key == 229) { 
                    key = getKeyCode($input.val());
                }

                // any key except the numbers 0-9
                if (key < 48 || key > 57) {
                    // -(minus) key
                    if (key === 45) {
                        $input.val(changeSign());
                        return false;
                        // +(plus) key
                    } else if (key === 43) {
                        $input.val($input.val().replace("-", ""));
                        return false;
                        // enter key or tab key
                    } else if (key === 13 || key === 9) {
                        return true;
                    } else if ($.browser.mozilla && (key === 37 || key === 39) && e.charCode === 0) {
                        // needed for left arrow key or right arrow key with firefox
                        // the charCode part is to avoid allowing "%"(e.charCode 0, e.keyCode 37)
                        return true;
                    } else { // any other key with keycode less than 48 and greater than 57
                        preventDefault(e);
                        return true;
                    }
                } else if (!canInputMoreNumbers()) {
                    return false;
                } else {
                    preventDefault(e);

                    keyPressedChar = String.fromCharCode(key);
                    selection = getInputSelection();
                    startPos = selection.start;
                    endPos = selection.end;
                    value = $input.val();
                    $input.val(value.substring(0, startPos) + keyPressedChar + value.substring(endPos, value.length));
                    maskAndPosition(startPos + 1);
                    return false;
                }
            }`

the fix is this:

//for android chrome keycode fix if (key == 0 || key == 229) { key = getKeyCode($input.val()); }

and finally declare getKeyCode function in somewhere into your code; function getKeyCode(str) { return str.charCodeAt(str.length - 1); }

kstyrose commented 8 years ago

I changed the keydown handler because in windows phone it seems that the onkeypress is not fired.

Applied the format to the input at keydown event for windows phone, added the numpad to the event also.

Hope it helps.

            function keydownEvent(e) {
                e = e || window.event;
                var key = e.which || e.charCode || e.keyCode,
                    keyPressedChar,
                    selection,
                    startPos,
                    endPos,
                    value,
                    lastNumber;
                //needed to handle an IE "special" event
                if (key === undefined) {
                    return false;
                }

                selection = getInputSelection();
                startPos = selection.start;
                endPos = selection.end;

                if ($.browser.msie) {

                    if (key !== 8 || key !== 46 || key !== 63272) {
                        // any key except the numbers 0-9

                        if (key < 48 || (key > 57 && key < 96) || key > 105) {
                            // -(minus) key
                            if (key === 45) {
                                $input.val(changeSign());
                                return false;
                                // +(plus) key
                            } else if (key === 43) {
                                $input.val($input.val().replace("-", ""));
                                return false;
                                // enter key or tab key
                            } else if (key === 13 || key === 9) {
                                return true;
                            } else if ($.browser.mozilla && (key === 37 || key === 39) && e.charCode === 0) {
                                // needed for left arrow key or right arrow key with firefox
                                // the charCode part is to avoid allowing "%"(e.charCode 0, e.keyCode 37)
                                return true;
                            } else { // any other key with keycode less than 48 and greater than 57
                                preventDefault(e);
                                return -true;
                            }
                        } else if (!canInputMoreNumbers()) {
                            return false;
                        } else {
                            preventDefault(e);

                            if (key >= 96 && key <= 105) {
                                keyPressedChar = String.fromCharCode(key - 48);
                            }
                            else {
                                keyPressedChar = String.fromCharCode(key);
                            }

                            selection = getInputSelection();
                            startPos = selection.start;
                            endPos = selection.end;
                            value = $input.val();
                            $input.val(value.substring(0, startPos) + keyPressedChar + value.substring(endPos, value.length));
                            maskAndPosition(startPos + 1);
                            return false;
                        }
                    }
                }

                if (key === 8 || key === 46 || key === 63272) { // backspace or delete key (with special case for safari)
                    preventDefault(e);

                    value = $input.val();
                    // not a selection
                    if (startPos === endPos) {
                        // backspace
                        if (key === 8) {
                            if (settings.suffix === "") {
                                startPos -= 1;
                            } else {
                                // needed to find the position of the last number to be erased
                                lastNumber = value.split("").reverse().join("").search(/\d/);
                                startPos = value.length - lastNumber - 1;
                                endPos = startPos + 1;
                            }
                            //delete
                        } else {
                            endPos += 1;
                        }
                    }

                    $input.val(value.substring(0, startPos) + value.substring(endPos, value.length));

                    maskAndPosition(startPos);
                    return false;
                } else if (key === 9) { // tab key
                    return true;
                } else { // any other key
                    return true;
                }
            }
dougmorris commented 7 years ago

I have cut and pasted these changes with no luck. I there anyone able to successfully use this for Android mobile devices? It does not seem to work successfully for me at all.

deepika-Gopala commented 7 years ago

To anyone who needs support and has faced the same issue. we fixed it by some tweaks int he plugin.

its a smart tweak cause in mobile it wasn't firing the focusEvent automatically , So calling the functionality happening in focusEvent and reducing the count of the selectionstart positioning worked as it was always taking +1 fromt he end of the strin in mobile .

Tested in IOS and other android devices and it works.

`/**** Get input selection ***/

function getInputSelection() { var el = $input.get(0), start = 0, end = 0, normalizedValue, range, textInputRange, len, endRange;

                if (typeof el.selectionStart === "number" && typeof el.selectionEnd === "number") {
                       start = el.selectionStart-1;
                      end = el.selectionEnd-1;
                } else {
                    range = document.selection.createRange();

                    if (range && range.parentElement() === el) {
                        len = el.value.length;
                        normalizedValue = el.value.replace(/\r\n/g, "\n");

                        // Create a working TextRange that lives only in the input
                        textInputRange = el.createTextRange();
                        textInputRange.moveToBookmark(range.getBookmark());

                        // Check if the start and end of the selection are at the very end
                        // of the input, since moveStart/moveEnd doesn't return what we want
                        // in those cases
                        endRange = el.createTextRange();
                        endRange.collapse(false);

                        if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                            start = end = len;
                        } else {
                            start = -textInputRange.moveStart("character", -len);
                            start += normalizedValue.slice(0, start).split("\n").length - 1;

                            if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                                end = len;
                            } else {
                                end = -textInputRange.moveEnd("character", -len);
                                end += normalizedValue.slice(0, end).split("\n").length - 1;
                            }
                        }
                    }
                }

                return {
                    start: start,
                    end: end
                };
            }`

`/ key Up Function / function keyup(e) { e = e || window.event; var key = e.which || e.charCode || e.keyCode, keyPressedChar, selection, startPos, endPos, value;

                //added to handle an IE "special" event
                if (key === undefined) {
                    return false;
                }

                 //for android chrome keycode fix
                if (key == 0 || key == 229) { 
                    key = getKeyCode($input.val());
                }

                // any key except the numbers 0-9
                if (key < 48 || key > 57) {
                    // -(minus) key
                    if (key === 45) {
                        $input.val(changeSign());
                        return false;
                        // +(plus) key
                    } else if (key === 43) {
                        $input.val($input.val().replace("-", ""));
                        return false;
                        // enter key or tab key
                    } else if (key === 13 || key === 9) {
                        return true;
                    } else if ($.browser.mozilla && (key === 37 || key === 39) && e.charCode === 0) {
                        // needed for left arrow key or right arrow key with firefox
                        // the charCode part is to avoid allowing "%"(e.charCode 0, e.keyCode 37)
                        return true;
                    } else { // any other key with keycode less than 48 and greater than 57
                       preventDefault(e);
                       onFocusValue = $input.val();
                        mask();
                        return true;
                    }
                } else if (!canInputMoreNumbers()) {
                    onFocusValue = $input.val();
                     mask();
                    return false;
                } else {
                    preventDefault(e);

                    keyPressedChar = String.fromCharCode(key);
                    selection = getInputSelection();
                    startPos = selection.start;
                    endPos = selection.end;
                    value = $input.val();
                   $input.val(value.substring(0, startPos) + keyPressedChar);
                    maskAndPosition(startPos + 1);
                       onFocusValue = $input.val();
                        mask();
                    return false;
                }
            }`

if (!canInputMoreNumbers()) { onFocusValue = $input.val(); mask(); return false; }

if (typeof el.selectionStart === "number" && typeof el.selectionEnd === "number") { start = el.selectionStart-1; end = el.selectionEnd-1; }

$input.val(value.substring(0, startPos) + keyPressedChar);

Hope this helps!

dougmorris commented 7 years ago

This is great @deepika-Gopala - works for me!

hugoseabra commented 7 years ago

Any update on this issue, guys. It is working on Moto G5 Plus with Google Chrome 60.0.3112.107, but on Samsung Devices their are not yet.

I have edited the code with the corrections shared on this issue, but it is still not working.

@dougmorris , if it worked for you, would you share with us?

deepika-Gopala commented 7 years ago

hi @hugoseabra

It worked for us for all the other samsung device except for the samsung S7 , we analysed that problem is with the samsung keyboard. However it works well with the swift keyboard installed , if installed.

Samsung keyboard is firing the events is a different way and root cause analysis is not found yet.

Hope this info helps in anyway.

cxrod commented 6 years ago

@deepika-Gopala thanks for the help. As you said works fine with the Swift keyboard, but still broken with the LG keyboard as well.