简体   繁体   中英

Javascript String.fromCharCode returns wrong values

I have this Knockout custom binding to validate a text box to contain only English letters. But, it seems like Javascript's String.fromCharCode returns wrong values.

For example, the Hebrew letter "ש" returns as the English letter "A", and the number "1" from the right numbers pad has returns as "a"...

Here is my Knockout binding:

var arrValidKeys = [8, 16, 17, 20, 35, 36, 37, 39, 46];
    ko.bindingHandlers.validateText = {
        init: function (element, valueAccessor) {
            $(element).on("keydown", function (event) {

                //Regex pattern: allow only (A to Z uppercase, a to z lowercase)
                var englishAlphabet = /[A-Za-z]/g;

                // Retrieving the key from the char code passed in event.which
                var key = String.fromCharCode(event.which);

                // keyCodes list: http://stackoverflow.com/a/3781360/114029
                // check that the key is valid with the above Regex
                valueAccessor()($(this).val());

                return ((jQuery.inArray(event.keyCode, arrValidKeys) != -1) || englishAlphabet.test(key));
            });

            $(element).on("keyup", function (event) {

                //Regex pattern: allow only (A to Z uppercase, a to z lowercase)
                var englishAlphabet = /[A-Za-z]/g;

                // Retrieving the key from the char code passed in event.which
                var key = String.fromCharCode(event.which);

                // keyCodes list: http://stackoverflow.com/a/3781360/114029
                // check that the key is valid with the above Regex

                valueAccessor()($(this).val());

                return ((jQuery.inArray(event.keyCode, arrValidKeys) != -1) || englishAlphabet.test(key));
            });

            $(element).on("paste", function (e) {
                var englishAlphabet = /[A-Za-z]/g;
                if (englishAlphabet.test($(this).val()))
                    valueAccessor()($(this).val());
                else
                    e.preventDefault();
            });
        }
    };

Following @Jeanluca Scaljeri's suggestion from this post: Get Correct keyCode for keypad(numpad) keys

I updated my code to this:

// keyCodes list: https://stackoverflow.com/a/3781360/114029
var arrValidKeys = [8, /*backspace*/
                    16, /*shift*/
                    17, /*ctrl*/
                    20, /*caps lock*/
                    35, /*end*/
                    36, /*home*/
                    37, /*left arrow*/
                    39, /*right arrow*/
                    46, /*delete*/];

function validateChar(keyCode) {
    //Regex pattern: allow only (A to Z uppercase, a to z lowercase)
    var englishAlphabet = /[A-Za-z]/g;

    //Retrieving the key from the char code passed in event.which
    var key = String.fromCharCode(keyCode);

    //Check that the key is valid with the above Regex
    return ((jQuery.inArray(keyCode, arrValidKeys) != -1) ||     englishAlphabet.test(key));
}

ko.bindingHandlers.validateText = {
    init: function (element, valueAccessor) {
        $(element).on("keypress", function (event) {
            valueAccessor()($(this).val());
            return validateChar(event.which);
        });

        $(element).on("keydown", function (event) {
            valueAccessor()($(this).val());
            return validateChar(event.which);
        });

        $(element).on("keyup", function (event) {
            valueAccessor()($(this).val());
            return validateChar(event.which);
        });

        $(element).on("paste", function (e) {
            var englishAlphabet = /^[A-Za-z]+$/g;
            var text = e.originalEvent.clipboardData.getData('Text');
            if (!englishAlphabet.test(text))
                e.preventDefault();
        });
    }
};

The reason I've added all 3 events ( keypress , keydown and keyup ) is that keypress alone does not fire when pressing the backspace key, and I need it to update a label with knockout observable.

And here is a working jsfiddle link: https://jsfiddle.net/2ma9nhn7/6/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM