11

I have a web form consisting of input text boxes, drop downs and submit button.

When I use my website on android phone - chrome browser(or any browser on my android device, I am using next on my phone keyboard to navigate to the next field.

the sequence of fields on my form:

  • first name (Text input)
  • last name (Text input)
  • day(drop down)
  • month(drop down)
  • year(drop down)
  • address(text) zip(text)
  • submit(button)

Next button on my android keyboard works fine to navigate from the first name to the last name. However, when I select next after I finish typing in the last name, it takes me directly to address field. It skips the drop-down fields.

tabbing works fine on desktop and on Apple devices. It is just an issue with the android device.

Should I be doing something specifically to handle that for android browsers?

Vishal Thakkar
  • 2,117
  • 2
  • 16
  • 33
nisha kanani
  • 273
  • 1
  • 4
  • 16
  • in android you can do like this https://developer.android.com/training/keyboard-input/navigation – Vishal Thakkar Jun 12 '18 at 14:00
  • Did you ever find a solution? I recently discovered this "bug" and it seems ubiquitous across every site I try, but yours is the only post that comes up when I search on the issue. I can't believe other people haven't run into this. – Chris Jan 26 '19 at 07:23
  • @Chris are you looking for a Java or JavaScript solution to this? Would you use this in a WebView or via a web browser? If JS does jQuery suit? – Siavas Jan 26 '19 at 22:35
  • Javascript. jQuery is fine, I can strip out the good bits. – Chris Jan 26 '19 at 23:53

4 Answers4

13

Don't confuse the Next button of your keyboard as TAB key, it's not. The next button of your keyboard just looks for next input field that is editable by your keyboard e.g text or number field. It will skip everything else because that will require closing the keyboard and bringing up the native calendar or combo box selector.

The TAB key if exists in your keyboard works just as expected. Some keyboards on play-store has a TAB key, like this one. You can download and see pressing the TAB key does focus the next select element or date-input element.

The following demo shows the difference of TAB key and Next button. You can see while navigating using the TAB key, keyboard events fire, which reveals the TAB keyCode 9. But while using the Next key, no keyboard event fires, as if the browser doesn't even know what just happened.

document.getElementById('my_form').addEventListener('keydown', function(event) {
  document.getElementById('response_view').innerHTML = event.keyCode;
})
<form action="" id="my_form">
  <div>
    Last Key Press Key Code:
    <span id="response_view" style="color: red;"></span>
  </div>
  <div>
    <input type="text" name="first_name" id="first_name" size="35" placeholder="Select it by click">
  </div>
  <div>
    <input type="text" name="last_name" id="last_name" size="35" placeholder="Then use TAB/Next key to focus this input">
  </div>
  <select name="date_day">
    <option value="-1">Select Day</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
  </select>
  <div>
    <input type="text" name="address" id="address" size="35" placeholder="address">
  </div>
</form>

The only way I see fit to resolve this issue is to use JavaScript to keep track of input elements in focus to determine if the Next key was pressed and it skipped a select element, then focus the select element by JavaScript.

(function(){
  let editableElementsSelector = 'input[type=text],input[type=email],input[type=number]';
  let nonEditableElementsSelector = 'select,input[type=date],input[type=time]';
  let userClickDetected = false, userTouchDetected = false;
  // Kepps track of user click for 0.5 seconds
  window.addEventListener('click', function() {
    userClickDetected = true;
    setTimeout(()=>{userClickDetected = false;}, 500);
  });
  // Kepps track of user touch for 0.5 seconds
  window.addEventListener('touchstart', function() {
    userTouchDetected = true;
    setTimeout(()=>{userTouchDetected = false;}, 500);
  });
  document.querySelectorAll('form[next-button-fix]').forEach(function(form){
    let formElements = form.elements;
    let editableElements = form.querySelectorAll(editableElementsSelector);
    let nonEditableElements = form.querySelectorAll(nonEditableElementsSelector);
    // linking elements
    for(let i=1; i<formElements.length; i++){
      formElements[i].previousFormElement = formElements[i-1];
      formElements[i-1].nextFormElement = formElements[i];
    }
    // Focuses next element on Next button click
    editableElements.forEach(function(element){
      element.addEventListener('blur', function(event){
        if(!userClickDetected && !userTouchDetected){
          if(element.nextFormElement && event.relatedTarget != element.nextFormElement){
            element.nextFormElement.focus();
          }
        }
      });
    });
    // Focuses next element on select element change
    nonEditableElements.forEach(function(element){
      element.addEventListener('change', function(event){
        if(element.nextFormElement){
          element.nextFormElement.focus();
        }
      });
    });
  });
})();
Munim Munna
  • 17,178
  • 6
  • 29
  • 58
  • This makes perfect sense. Tab vs. Next and all. The workaround is pretty cool, but it seems awfully convoluted for such a simple problem though. /sadface – Chris Jan 26 '19 at 13:31
  • Yeah, it is. I will post if anything better comes up. – Munim Munna Jan 26 '19 at 15:26
  • This functionally solves the problem, but creates a new UX problem. After "nexting" an input, the user is forced to focus on the subsequent select element. On Android Chrome, this results in a modal list of options with no context. For the OP's use-case, it sounds like the user will finish typing their last name and then be shown a list of 1-30. Not good. – Aaron Cicali Sep 06 '19 at 22:12
  • @AaronCicali may be that's why android decided to skip the combo boxes in the first place :P – Munim Munna Sep 07 '19 at 10:39
  • This does not work when the dropdown is the last element of the form. After pressing "next" on the penultimate input element, the form will be submitted. – daniol Sep 17 '20 at 13:00
1

Try like this

set your spinner with focusable attribute as true,

yourEditText.setOnEditorActionListener(new OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView textView, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_NEXT) { //trigger when user taps on next button in keyboard
            hideKeyboard(); //hides the keyboard as it is not necessary here
            yourEditText.clearFocus();
            yourSpinner.requestFocus();
            yourSpinner.performClick();//opens the dropdown in your spinner
        }
        return true;
    }
});

//hide keyboard when spinner is focused

private void hideKeyboard() {
    InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(),
            InputMethodManager.HIDE_NOT_ALWAYS);
}
SaravInfern
  • 3,338
  • 1
  • 20
  • 44
0

consider using the tabIndex

The tabindex global attribute indicates if its element can be focused, and if/where it participates in sequential keyboard navigation (usually with the Tab key, hence the name).

Here is an example which focus input and div in a weird order choised by me:

div:focus { font-weight: bold; }
<br>
<label>CLICK THIS INPUT THEN TAB <input  tabindex="0"></label>
<br>

<div tabindex="1">FOCUS 2 (ye u can focus text too)</div><br>

<label>FOCUS 4<input  tabindex="3"></label><br>

<label>FOCUS 3<input  tabindex="2"></label><br>

<label>no FOCUS<input  tabindex="-1"></label><br>

<label>FOCUS 5<input  tabindex="4"></label><br>
Robdll
  • 5,865
  • 7
  • 31
  • 51
  • 1
    The tabindex property does not work. The select element is still skipped. I suspect it has something to do with the fact that the select element is not handled by the virtual keyboard input, but it seems like something this obvious would have been resolved a long time ago. – Chris Jan 26 '19 at 13:28
-1

Edit: This technique works well on Android, but causes the select element to no longer function in Firefox. Pooh.

Simply add the contenteditable attribute to your select element. It will cause the keyboard to recognize the select as a viable element for focus.

Upon nexting to the select, it will receive focus and the keyboard will remove itself from the screen. The select element will not be expanded, requiring the user to touch it for expansion and to make a selection. Additionally, after making a selection, the user will be required to touch the next field in the form because the keyboard is not active to provide its next button.

My opinion is that this is the most reasonable behavior for the form to exhibit. That said, this problem should be solved higher up the chain (by browser and/or keyboard software vendors).

This was tested on Android 6.0.1 using both the GBoard and TouchPal keyboards. The CSS below is only included to make the form look a little nicer. The only thing needed for this to work is the contenteditable attribute on the select element. The fields must also be contained within a <form> tag (nexting does not appear to work without the form tag).

.form-field {
 padding: 10px;
}

.form-field label {
 display: block;
}

.form-field input,
.form-field select {
 display: block;
 width: 100%;
 margin: 0;
 padding: 0;
}
<form>
 <div class='form-field'>
  <label>Name</label>
  <input/>
 </div>
 <div class='form-field'>
  <label>Age</label>
  <input/>
 </div>
 <div class='form-field'>
  <label>Mood</label>
  <select contenteditable>
   <option value=''>Please Select</option>
   <option>Happy</option>
   <option>Sad</option>
   <option>Glad</option>
   <option>Mad</option>
   <option>Rad</option>
  </select>
 </div>
</form>
Aaron Cicali
  • 1,496
  • 13
  • 24