32

I'm creating a webapp for the iPhone, based in HTML/CSS/JS. I'm using forms to receive input and pass data to the script, but a problem I'm encountering is that the keyboard won't disappear. The user will enter the information, hit submit, and since it's JavaScript the page doesn't reload. The keyboard remains in place, which is a nuisance and adds another step for users (having to close it).

Is there any way to force the keyboard in Safari to go away? Essentially, I have a feeling this question is equivalent to asking how I can force an input box to lose focus or to blur. Looking online, I find plenty of examples to detect the blur event, but none to force this event to occur.

munchybunch
  • 6,033
  • 11
  • 48
  • 62

10 Answers10

44

Even more simply, you can call blur() on the currently focused element. $("#inputWithFocus").blur()

Steven
  • 456
  • 5
  • 2
43
document.activeElement.blur();
iPadDeveloper2011
  • 4,560
  • 1
  • 25
  • 36
28

You could try focus()ing on a non-text element, like the submit button.

Sathyajith Bhat
  • 21,321
  • 22
  • 95
  • 134
ceejayoz
  • 176,543
  • 40
  • 303
  • 368
  • thank you! works like a charm (in mootools, $('id-of-submit-button').focus() is all that was needed) – munchybunch May 23 '10 at 00:35
  • 2
    blur(), tap(), click(), focus() dont work anymore to solve this on iOS 8+ – mojjj Apr 23 '15 at 07:27
  • oh wait. my problem was different. using angularjs, the page transition was completed, and a new frame was displayed. on the new page, the command has no effect, when returning to original, 3rd party iframe which previously caused the vkeyboard, the keyboard again popsup despite no call to the text input was made. strange. – mojjj Apr 23 '15 at 11:23
  • how did you fix this @mojjj ? – Metagrapher Jun 25 '15 at 21:31
  • 2
    @Metagrapher the issue was caused by a custmer's login iframe, which didnt defocus after text input an soft-keyboard return press. the hacky solution was: create a hidden(e.g. off screen) text-input element, focus it and blur right before the screen transition to the next screen. – mojjj Jun 26 '15 at 23:06
19

Here's a small code snippet that always hides the keyboard whenever the focus is in an input or textarea field and the user taps outside of that element (the normal behaviour in desktop browsers).

function isTextInput(node) {
    return ['INPUT', 'TEXTAREA'].indexOf(node.nodeName) !== -1;
}

document.addEventListener('touchstart', function(e) {
    if (!isTextInput(e.target) && isTextInput(document.activeElement)) {
        document.activeElement.blur();
    }
}, false);
Husky
  • 5,757
  • 2
  • 46
  • 41
  • 5
    excellent, I can imagine this marvelous piece of code's greatly sought after by web App and phonegap developers – Jonathan Aug 09 '12 at 19:18
3

To detect when the return button is pressed use:

$('input').bind('keypress', function(e) { if(e.which === 13) { document.activeElement.blur(); } });

Ben Southall
  • 637
  • 1
  • 10
  • 16
3

I came across this issue and have spent some time until getting a satisfactory solution. My issue was slightly different from the original question as I wanted to dismiss the input event upon tapping outside input element area.

The purposed answers above work but I think they are not complete so here is my attempt in case you land this page looking for the same thing I was:

jQuery solution

We append a touchstart event listener to the whole document. When the screen is touched (doesn't matter if it's a tap, hold or scroll) it will trigger the handler and then we will check:

  1. Does the touched area represent the input?
  2. Is the input focused?

Given these two conditions we then fire a blur() event to remove focus from the input.

ps: I was a little bit lazy so just copied the line from above response, but you can use the jQuery selector for document in case you want to keep consistency of code

$(document).on('touchstart', function (e) {
  if (!$(e.target).is('.my-input') && $('.my-input').is(':focus')) {
    document.activeElement.blur();
  }
});

Hammer.JS solution

Alternatively you can use Hammer.JS to handle your touch gestures. Let's say that you want to dismiss that on a tap event but the keyboard should be there if the users is just scrolling the page (or let's say, hold a text selection so he can copy that and paste into your input area)

In that situation the solution would be:

var hammer = new Hammer(document.body);
hammer.on('tap', function(e) {
  if (!$(e.target).is('.search-input') && $('.search-input').is(':focus')) {
    document.activeElement.blur();
  }
});

Hope it helps!

rafg
  • 165
  • 6
2
$('input:focus').blur();

using the CSS attribute for focused element, this blurs any input that currently has focus, removing the keyboard.

Design by Adrian
  • 2,185
  • 1
  • 20
  • 22
1

Be sure to set, in CSS:

body {
  cursor: pointer;
}

otherwise, your event handler calling document.activeElement.blur() will never get fired. For more info, see: http://www.shdon.com/blog/2013/06/07/why-your-click-events-don-t-work-on-mobile-safari

davidgoli
  • 2,436
  • 1
  • 16
  • 13
0

For anyone using Husky's code in AngularJs here is the rewrite:

function isTextInput(node) {
    return ['INPUT', 'TEXTAREA'].indexOf(node.nodeName) !== -1;
}

angular.element($document[0]).on('touchstart', function(e) {
  var activeElement = angular.element($document[0].activeElement)[0];
  if(!isTextInput(e.target) && isTextInput(activeElement)) {
    activeElement.blur();
  }
});
0

In my case, I have an app: AppComponent -> ComponentWithInput and with the html:

<div class="app-container" (click)="onClick()">

    <component-with-input></component-with-input>

</div>

And everything I do is adding (click)="onClick()"

You can leave the method empty as I did:

onClick() {
    // EMPTY
}

This works for me.

NickNgn
  • 122
  • 2
  • 8