Jquery ui autocomplete autoFocus on android device - android

I am using Jquery ui autocomplete.
I am using the autoFocus option so that as soon as the autocomplete list is shown, the first option is automatically selected.
This is a fiddle. The autocomplete code is:
$(".ac").autocomplete({
source: availableTags,
autoFocus: true
});
However, if this is tested on a chrome browser on android, then for any non-last form input, the item isn't selected.
Upon inspection, I noticed that the "enter" (button on bottom right of keyboard) button on an android device for any non-last input element in a form is "Next" while the "enter" button for the last input element of the form is "Go".
The issue I described only occurs when the "enter" button is "Next" (ie: any non-last input element).
Are there any suggestions for how I might fix this issue? That is, how can I have the "enter" key select the auto focused element on an android Chrome browser?
Thanks

You can try to get/set the focused item through events callbacks.
See this example:
$(document).ready(function() {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
// Add variable to hold focued item value
let focusedItem = '';
$(".ac").autocomplete({
source: availableTags,
autoFocus: true,
focus: function(event, ui) {
// on focus set the focued item value to the variable
focusedItem = ui.item.value;
return true;
},
change: function(event, ui) {
// user moved away from input, if variable is not null set it to input
if (focusedItem != '')
jQuery(this).val(focusedItem);
return true;
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<form>
<input type="text" class="ac" />
<input type="text" class="ac">
</form>

You can capture enter button on keypress.
$('input').on('keydown', function(e){
if(e.which === 9) {
//your code here
}
});
then set focus manually to your autocomplete.

Related

Showing soft keyboard when autofocusing on a text input does not work without user interaction

I want to autofocus on a text field and show the soft keyboard when I load my page in the android system webview. Unfortunately, it appears that the soft keyboard never shows up unless I explicitly click a button that calls input.focus().
I'm using androidx.webkit:webkit:1.4.0 and can reproduce the issue on an emulator as well as a physical device using this minimal sample app: https://github.com/dsyang/android-webview-auto-soft-keyboard-bug
In the sample app, I load the webview url like this:
/* MainActivity.kt */
...
// Load the content
binding.webview.loadUrl("......./index.html")
binding.webview.requestFocus()
...
override fun onPageFinished(view: WebView?, url: String?) {
val webView = view ?: return
webView.requestFocus()
webView.evaluateJavascript("""
onPageFinished()
""".trimIndent(), null)
}
The html and javascript look like this:
/* index.html */
<body>
<input type="text" id="focusme" placeholder="Auto focus and show soft keyboard" />
<button class="button" onclick="focusToShowSoftKeyboard()" type="button" value="Focus">Focus #focusme</button>
</body>
/* main.js */
function focusToShowSoftKeyboard() {
console.log("I am about to focus the following element: ", document.getElementById("focusme"));
document.getElementById("focusme").focus();
console.log("details", {
activeElement: document.activeElement,
hasFocus: document.hasFocus(),
focusMe: document.getElementById("focusme")
})
}
function onPageFinished() {
console.log("onPageFinished")
setTimeout(() => {
console.log("focusing to show keyboard")
focusToShowSoftKeyboard()
}, 1000)
}
There's a video of the sample app in action in the repo (link: https://user-images.githubusercontent.com/529969/169964147-665722e7-58a1-4c55-baa5-b231d6a87f43.mp4).
You can see that the input field focuses on page load but it doesn't show the soft keyboard unless I focus it with the button.
What do I need to do so that I can focus on the input field and get the soft keyboard to show up on page load?

Issues with input type date in cordova app

I am using input type=date to capture a date from user. Because we cannot have placeholder for input(type=date), I have done the following:
created the input field with Type text with a placeholder
in JS, on focus, changing the type to date
$("#datefield").on('focus', function() {
$("#datefield").attr('type', 'date');
})
In IOS, this is working perfectly fine and brings the native datepicker everytime I tap on the input field.
But in android, it brings the native datepicker but I have to click twice. After debugging, I found on first, it goes through the focus event and change the type to date. On second click, it doesn't go through the event, but brings the native keyboard. After that as long as I stay on that page, because the type has been changed to date, it will bring the native datepicker on one click.
Am I handling it the right way? What am I doing wrong? Is there any better way of doing it?
P.S. I want to avoid plugins as long as I can. I am using, HTML, CSS, JS, Jquery
Try to use onfocus attribute to change the text field to date field.
I hope this helps you...
<input placeholder="Date" type="text" onfocus="(this.type='date')" id="date">
or use jquery
$('input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="month"], input[type="time"], input[type="week"]').each(function() {
var el = this, type = $(el).attr('type');
if ($(el).val() == '') $(el).attr('type', 'text');
$(el).focus(function() {
$(el).attr('type', type);
el.click();
});
$(el).blur(function() {
if ($(el).val() == '') $(el).attr('type', 'text');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input name="date" type="date" placeholder="Date">

Enable enter key on numeric keyboard in PhoneGap

We are running PhoneGap 2.6 on Android 3.22 (also jquery mobile and backbone are also in the mix). We want to make it so the user can tap the enter key to submit a form after entering a value in a field. The field is a numeric input.
<input id="myfield" type="number">
Unfortunately, the enter button on the soft keyboard appears to be disabled. So when you tap it, no event is fired. None of the following work:
$('#myfield').on('keyup', keyhandler);
$('#myfield').on('keydown', keyhandler);
$('#myfield').on('keypress', keyhandler);
$('#myfield').keyup(keyhandler);
$('#myfield').keydown(keyhandler);
$('#myfield').keypress(keyhandler);
keyhandler: function(e) {
console.log('You tapped a key');
if (e.keyCode == 13) {
console.log('You tapped ENTER! Yay!');
}
}
Is there a way to enable the enter button on a numeric keyboard?
Not sure if this relates to your problem... but you can simulate form submit similar to what happens when you click on 'Go' via a press via the 'Next' button on a numeric keyboard. You can detect the next keyboard press by using the following bind in JQuery:
$('input').on('keydown', function(e){
if(e.which === 9) {
//your code here
}
});
The 'next' button emulates the tab keypress event on a keyboard, which is key code 9. Unfortunately, keypress and keyup events do not detect the next key event, so you need to bind it on keydown.

How can I detect a user submission of a search field in jQuery Mobile?

I've got a search bar in a jQM/phonegap/cordova Android app.
How on earth do I detect when the user presses 'enter' or 'done' or whatever, so I can submit the search??
Do I have to build a custom key detector, or is there an event for this?
So frustrating - I can't find this in the docs anywhere....
Cheers all!
You would wrap the field in a form element ie:
<form id="foo">
<input type="text" />
</form>
Then to trigger an event when "the user presses the equivalent of 'return' on a PC keyboard i.e. 'go' or 'done', or whatever the OS has called it" you can use
$('#foo').submit(function(){
//do stuff
})
You would use the same code you would in a "normal" HTML application. Since you are using jQuery Mobile, you can use jQuery. If the field had an id of foo, you could use
$("#foo").on("click", function() {
//do stuff here
});

HTML: Why does Android browser show "Go" instead of "Next" in keyboard?

I have an HTML login form that contains following elements (in this order):
input type=text (user name input)
input type=password (password)
input type=submit (Login button)
Why does the Android browser show "Go" button in soft keyboard instead of "Next" button when the focus is in the text input? This causes user to fail to login very easily because after entering the user name, the user presses the bottom right button in the keyboard (usually the correct action) and the form will be submitted with an empty password, which obviously is not going to work. [This behavior would make sense in case my browser was set to remember passwords and the password manager would be able to fill in the password. However, this is not the case here as you can test yourself below.]
I'd like to have the input type text to have "Next" button and the input type password (the last input before the submit) to have the "Go" button.
An example of problematic form is at https://peda.net/:login (this form contains code to detect "Enter" key for the input and prevents submitting the form unless the last visible form input is focused).
Do you know a real fix for this issue? I know that if I were implementing native application, I'd use android:imeOptions="actionNext" (see How to change the Android softkey keyboard "Go" button to "Next"). However, in this case it's an HTML form and Android default browser.
The problem is visible with at least following configurations:
"Browser" system app running on Android 2.3.4 (Cyanogenmod 7)
"Browser" system app running on Android 4.2.2 (Cyanogenmod 10.1)
"Browser" system app running on Android 4.3.1 (Cyanogenmod 10.2 M1)
"Browser" system app (AOSP Browser) running on Android 4.4.2 (Cyanogenmod 11.0 M3)
"Browser" system app (AOSP Browser) running on Android 5.5.1 (Cyanogenmod 12.1) [has an arrow icon instead of word "Go"]
"Browser" system app (AOSP Browser) running on Android 6.0.1 (Cyanogenmod 13.0) [has an arrow icon instead of word "Go"]
To add to John's answer, Android always adds 'Go' to text inputs and always adds 'Next' to number inputs. I'd love to hear the person responsible for this choice explain their logic.
The softkeyboard design is just lousy in this respect, because every user I've tested with so far has thought the big blue button in the keyboard must be the button that takes you to the next form field and then at the last form field lets you submit the form.
iOS it's even worse in this respect, since they offer a 'Go' button with every form field and no way to tab through the fields. It's nice that Apple likes to make computers simple for people, but sometimes assuming that people like it simple can shade into presuming people are all idiots.
Sorry about that rant. I do have something constructive to offer:
If your last form field happens to be type=number, then there is a tiny hack that will work on Android as well as iOS: add an invisible text input to the form with onfocus="$('#thisForm').submit();". In Android this field will briefly flash into view: in iOS it wont. To make the Android situation more palatable, you can either set a value for the text input like "Closing this form", or you can set its width to 0, which will cause the form field to be not quite 0 width but still very small.
Horrible hack, but hey, blame it on the UI people at Google and Apple.
The Android Browser always displays Go for input fields because some forms on the web (especially search boxes) have no submit button, and can only be activated by pressing Enter (Go is equivalent to Enter).
Instead some versions of Android will show a tab key in the bottom right of the keyboard to facilitate navigating between form fields.
I don't think you can prevent either of these behaviours.
Two possible workarounds:
Use JavaScript to ignore submission of the login form until both inputs are non-blank:
<form name="loginForm" onsubmit="return document.loginForm.user.value != '' && document.loginForm.pass.value != ''">
<input type="text" name="user">
<input type="password" name="pass">
<input type="submit" value="Login">
</form>
The cleanest solution would be to set both inputs to be required using the new HTML5 required attribute - but the Android Browser doesn't support this yet. However a good approach would be to supplement the required attribute with a JavaScript fallback such as that described by CSSKarma.
This is the Chromium issue if you want to watch it: https://bugs.chromium.org/p/chromium/issues/detail?id=410785
Here is a workaround for Android that changes the "enter" in the user input so that it "tabs" to the password field (and doesn't submit the form):
http://jsbin.com/zakeza/1/quiet
<form action="?">
User <input type=text onkeypress=key(event)><br><br>
Password <input id=pw type=password><br><br>
<input type=submit>
</form>
<script>
function key(event) {
if (event.charCode == 13 && /Android/.test(navigator.userAgent)) {
event.preventDefault();
document.getElementById('pw').focus();
}
}
</script>
Edit: Note Windows Phone also puts Android into the UA, so needs testing that works on Windows Phone (and Android Firefox).
I was having this problem, and then I realized that I had forgot to wrap everything in a <form> element. That fixed everything.
see Replace Go button on soft keyboard with Next in Phonegap.
For a quick navigation see this plunker.
To follow complete code
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<form action="" id="form">
First name: <input type="text" name="firstname">
Last name: <input type="text" name="lastname">
<select name="select" readonly="readonly">
<option>Select Something</option>
</select>
Last name: <input type="text" name="lastname" disabled="disabled">
Select <select name="select" id="selectBox">
<option>Select Something</option>
</select>
Last name: <input type="text" name="lastname">
Select <select name="select" readonly="readonly">
<option>Select Something</option>
</select>
<button type="submit">Submit</button>
</form>
<script>
(function($) {
$.fn.enterAsTab = function(options) {
var settings = $.extend({
'allowSubmit': false
}, options);
$(this).find('input, select, textarea, button').live("keydown", {localSettings: settings}, function(event) {
if (settings.allowSubmit) {
var type = $(this).attr("type");
if (type == "submit") {
return true;
}
}
if (event.keyCode == 13) {
var inputs = $(this).parents("form").eq(0).find(":input:visible:not(:disabled):not([readonly])");
var idx = inputs.index(this);
if (idx == inputs.length - 1) {
idx = -1;
} else {
inputs[idx + 1].focus(); // handles submit buttons
}
try {
inputs[idx + 1].select();
}
catch (err) {
}
return false;
}
});
return this;
};
})(jQuery);
$("#form").enterAsTab({ 'allowSubmit': true});
</script>
NOTE: don't forget to replace .live() method of jquery with .on() if using newer version of jquery than 1.9.
If you want the button to be 'Go' always use:
enterKeyHint="Go"
see this answer
https://stackoverflow.com/a/71593469/2721727
You can generically change ENTER keys into input elements into focussing the next input, using pure JavaScript.
It is not only useful in mobile browsers, but in desktop browsers too.
You can refine it for textarea and select.
function keyControls(e) {
// [enter] on inputs tranformed into focus next input.
// Sending events to inputs is security forbidden.
// We find the next element and focus() it.
// optionally restrict to certain user agens: && /Android/.test(navigator.userAgent)
if (e.key === "Enter") {
var el = document.activeElement;
if (el.tagName == "INPUT" || el.tagName == "SELECT") {
e.preventDefault();
var nextEl = null;
var found = false;
for (var i = 0, element; element = el.form.elements[i++];) {
if (element.type !== "hidden" && element.type !== "fieldset" ) {
if (found) {
nextEl = element;
console.log("found next element", element.name, " at ", i);
break;
}
if (el === element) {
console.log("found current element", element.name, " at ", i);
found = true;
}
// console.log("iterating form elements", element.name, " to ", i);
} else {
// console.log("iterating form elements - skipping ", element.name, " - ", i);
}
}
if (nextEl && nextEl.focus) nextEl.focus();
if (nextEl) {
console.log("key listener ENTER - transformed into TAB:", el.tagName, el.name, nextEl.tagName, nextEl.name );
} else {
console.log("key listener ENTER - transformed into TAB:", el.tagName, el.name, " next element not found" );
}
} else {
console.log("key listener ENTER on tagname:", el.tagName, el.name );
}
}
}
window.onload = function () {
document.addEventListener("keydown", keyControls, false);
console.log("key listener registered");
};
We can not prevent this default behavior because there is not input type="next" tag available in HTML as of now. So by default "Go" button appears. Below link having list of available input type tags: http://www.w3schools.com/tags/att_input_type.asp
To avoid confusion for user let GO button function as enter button only.
For this use a form tag but to avoid incomplete submissions use disabled attribute on submit button.
$("input:not(.submit)").bind('input',function(){
var isValid = validateInputs();
if(isValid)
{
$('.submit').removeAttr('disabled');
}
else
{
$('.submit').attr('disabled','disabled');
}
});
Now To avoid page reload dont use action or onsubmit attributes in form tag, instead use
$('#formid').submit(function(){
var disabled=$('.submit').attr('disabled');
if(disabled=='disabled')
{
return;
}
callOnSubmitFunction();
return false;
}
);
return false is important here to avoid page reload.
with the exception of chrome, the firefox and the default android browsers show a prev and next buttons which will work as tab buttons, so use proper tabindex atrributes on form input element.

Categories

Resources