Determining Event KeyCode on Mobile Browser (Chrome, Android, Firefox)

Recently, I run into a very common issue with regards to determining the Event KeyCode when entering text into a textarea on a mobile device. This had me scratching my head for a good couple of hours, but eventually I managed to get a solution that works perfectly well on desktop and mobile for the same piece of code.

Here is the final code with some comments to explain the logic behind everything

// we use a keyup event to ensure to only check after text has been
// typed into the field
$("#textarea_id").on('keyup', function(event) {
    var textarea = this;

    // determine keycode of the last character typed. This works in desktop
    // browsers very well. event.which is a JQuery wrapper to ensure
    // the right keyCode is returned in every browser
    var kc = event.which || event.keyCode;

    // if we are on a crazy mobile device, then determine the last 
    // character typed based on where the selection start is located
    if( !kc || kc == 229 ) {
        var ss = textarea.selectionStart - 1;
        var ssv = ss || 0;
        var char = textarea.value.substr(ssv,1);
        kc = char.charCodeAt(0);
    }

    // for this piece of code, we are only interested in keyCodes for 
    // space, comma, semi-colon, single-quote, open bracket, close bracket 
    if( [32,188,186,222,221,219].indexOf(kc) > -1 ) {
        // do stuff
    } 

    // if none of those keycodes were fired, then we should try to detect if a
    // paste action occurred and process the text based off that
    else {
        detectPaste(textarea, function() {
            // do stuff
        });
    }
});

Here is the piece of code for detecting if a paste event occurred in a textarea, included here in case anyone needs it in the future.

function detectPaste(textarea, callback) {
    textarea.onpaste = function() {
        var sel = getTextAreaSelection(textarea);
        var initialLength = textarea.value.length;
        window.setTimeout(function() {
            var val = textarea.value;
            var pastedTextLength = val.length - (initialLength - sel.length);
            var end = sel.start + pastedTextLength;
            callback({
                start: sel.start,
                end: end,
                length: pastedTextLength,
                text: val.slice(sel.start, end)
            });
        }, 1);
    };
}

Thanks to all the various StackOverflow posts that helped shape this final piece of code. I can’t seem to find all the tabs I opened and closed in search of this answer, but hopefully this condensed piece of code will help someone else in the future.

PS: Post written in 5 minutes, so excuse any typos, will fix in the future, or perhaps never. (troll)

Do check out Memberz.Org, a membership management platform on which this piece code is used to build functionality for detecting URLs in posts.

Advertisements