7

In HTML/CSS/JS I would like to be able to hide the default keyboard on mobile from the screen when an input field gets focus.

The situation is this: I have a web solution on a handheld device (Android 5+, running something based on Chromium) with a built-in 2D scanner - for reading barcodes.

Some fields should by default get input from scanning barcodes and I would very much like to hide the default keyboard that otherwise appear on screen. Then, if necessary, I would like to have some option of actually displaying the default keyboard anyway, for example by some button or selection on the page.

I have read the various suggestions to similar questions (mostly making the field readonly, but also the one about blurring the field right after it gets focus) but these do not work, as the scanner does not input anything into the field - it needs the field to have focus.

2
  • 2
    There's no way of doing this, except losing focus from the input using blur. You can't tell the keyboard to show/hide, it's controlled by the browser. Commented Feb 1, 2017 at 12:16
  • Rik is right this is an interaction between the browser and the device's OS. The web page has no control over it. Commented Feb 1, 2017 at 12:31

3 Answers 3

6

Thank you for the replies. As the consensus is that this is not possible I did a work-around that I am posting here:

The basic principle is to blur the input field and then capture the keypresses to add them to the input field anyway.

In this situation I am using a barcode scanner with all-numeric barcodes so that's what this will work with but if someone else should be interested it should be trivial to adapt to other situations:

<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script> 
<script>
$( document ).ready( function () {
    // _input_fields and _scan_fields are jQuery objects with the relevant elements
    let _input_fields = $("input[type=number], input[type=text], input:not([type]), select");
    let _scan_fields = $("input[type=number].scanner");
    // _ignore is set to true when a scannable field actually _should_ get focus
    var _ignore = false;
    // onfocus() for relevant input fields on page
    _input_fields.focus(function(){
        // only do something if scannable fields shouldn't actually get focus
        if (!_ignore) {
            // outer is the current input field that is getting focus
            let outer = this;
            // found is set to true if the current input field is scannable
            let found = false;
            // loop through all scannable fields to see if the current input field is one of them
            _scan_fields.each(function(index) {
                // inner is one of the scannable fields, possibly the current input field
                let inner = this;
                // _field stores the current input field _if_ it is scannable
                var _field;
                // only check (and potentially reset key capture) if we have not found the current 
                // input field to be one of the scannable fields (yet)
                if (!found) {
                    // check if the current input field "outer" is the currently examined 
                    // scannable field "inner"
                    if (inner == outer) {
                        // the current input field is one of the scannable fields
                        // immediately remove focus to disable mobile keyboard
                        inner.blur();
                        // remember which input field we have found and disable further checks
                        _field = inner;
                        found = true;
                        // remove any existing keycapture (might destroy existing functionality!!!)
                        $(document).off("keypress");
                        // capture keypresses and add numbers to the input field
                        $(document).keypress(function(event){
                            var _field = inner;
                            let keynum = event.which;
                            if (keynum == 13) { // enter
                                // ignore or submit?
                            } else if ((keynum < 48) || (keynum > 57)) {
                                // not-a-number, ignore in this case
                            } else {
                                // a number, add to field value
                                $(_field).val($(_field).val() + String.fromCharCode(event.which));
                            }
                        });
                    } else {
                        // this is a regular field
                        // remove any existing keycapture (might destroy existing functionality!!!)
                        $(document).off("keypress");
                    }
                }
            });
        }
    });
    // add a button after each scannable input field
    $("input[type=number].scanner").after(function(){
        return "<button class='descanner'>123</button>";
    });
    // if those buttons are pressed, the input field before them actually gets focus
    // overriding the new behaviour
    $("button.descanner").click(function(event){
        // these buttons do not submit the form
        event.preventDefault();
        // remove any existing keycapture (might destroy existing functionality!!!)
        $(document).off("keypress");
        // set focus for the input field but make sure we don't catch this above
        // also, clear content of input field
        _ignore = true;
        $(this).prev("input[type=number].scanner").val("").focus();
        _ignore = false;
    });
});
</script>
</head>
<body>
<form>
    <input type="number" name="field1" class="" />
    <input type="text" name="field2" class="" />
    <input name="field3" class="" />
    <select name="field4" class="">
        <option value="bac">abc</option>
    </select>
    <input type="number" name="field5" class="scanner" />
    <input type="number" name="field6" class="" />
    <input type="number" name="field7" class="scanner" />
</form>

</body>
</html>

The form has 7 fields and 2 of those have the desired functionality. To enable manual edit of those fields a button is added next to each of those 2 fields.

This has been tested in Chrome 55 and on a Zebra TC 51 with Webview updated to Chromium 55.

Sign up to request clarification or add additional context in comments.

Comments

4
  1. Define an Input element above and append CSS property which will hide the soft keyboard to popping up.
  2. Set Focus to make ready for scanner input in the text field.
  3. The last Step Turn Read-only mode off to input data.

    yourInputVal = document.getElementById('myInputElement');
    yourInputVal.readOnly = true;
    yourInputVal.focus();
    setTimeout(function(){
      document.getElementById('myInputElement').readOnly = false;
    },
    

1 Comment

Easy solution and worked great for my barcode scanner app with invisible input field!
3

This worked for me:

Add the inputmode="none" attribute to your input element.

<input type="text" id="manageBinsBinId" inputmode="none" >

Javascript/jquery:

$(function() {
    $(document).on(`focus`,`input`,function() {
        myEl=$(this);
        setTimeout(function(){
            myEl.attr(`inputmode`,``);
        },1);
    });
    $(document).on(`blur`,`input`, function(){
        $(this).attr(`inputmode`,`none`);
    });
});

3 Comments

I don't think you can toggle inputmode client side: github.com/whatwg/html/issues/4876
You can if the user initiates it. It's working for me.
Many thanks for this Elegant solution. Verified working in Android 8.x Sadly not in old Android 4.x Best regards

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.