Hide or disable WebView softkeyboard Go/Done/Enter

2019-09-08 15:49发布

问题:

I've been searching for a working example of this all day and haven't found anything that actually works.

I have a simple feedback form online which I've setup with WebView to work on android devices, specifically for Nexus 7 (it will only be used locally at our hotel on these devices).

The thing is that the html feedback form has different fieldsets, some with radio buttons others with text fields and text areas. The form is sent via post and I have a jquery validation script called in the form:

<form name="form" method="post" action="feedback_manager/fb_save.php" onsubmit="return validateForm()" >

Everything works just fine, except for when a user fills in a text field there's an unmistakable blue "Go" button in the soft keyboard which they are bound to click (or touch) once they've finished typing, the problem is that it doesn't take them to the next form fieldset, instead it submits the form automatically (or in this case runs my validation script first).

Isn't the KEYCODE_ENTER button's default action supposed to send the user to the next fieldset instead of submitting the form?

I'll share my html form and my webView script in hopes that someone may find what I'm doing wrong:

<fieldset>
<legend>Food quality, taste &amp; presentation</legend>

    <input id="flavor4" name="flavor" value="excellent" type="radio" />
    <label for="flavor4"> Excellent</label><br>

    <input id="flavor3" name="flavor" value="good" type="radio" />
    <label for="flavor3"> Good</label><br>

    <input id="flavor2" name="flavor" value="average" type="radio" />
    <label for="flavor2"> Average</label><br>

    <input id="flavor1" name="flavor" value="bad" type="radio" />
    <label for="flavor1"> Needs improvement</label><br>

</fieldset>
<fieldset>
    <legend>Who was your waiter today?</legend>
    <input name="waiter" type="text">
</fieldset>

//then another fieldset with radio buttons and so on

Could it be that my text inputs aren't immediately right after one another and mixed in with radio buttons and combo boxes?

Here's my onKeyDown code:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack())
    {
        mWebView.goBack();
        return true;
    }
    if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
        // do nothing
        return false;
    }
    return true;
}

The funny thing about this is that my KEYCODE_BACK conditional is working fine but I would like the KEYCODE_ENTER button to either do nothing and just close the soft keyboard or go to the next field but not submit the form.

I've seen a lot of answers here on SO but none of them seem to be working on Nexus7 (haven't really tried on other devices).

So summing up, all I need is just have that blue "Go" button do nothing or go to the next field.

Help please.

** Edit **

I'm looking at this with a fresh outlook this morning and found this similar post that adds an OnKeyListener to detect the key and then returns false. Enter key on EditText hitting onKey twice

mWebView = (WebView) findViewById(R.id.webview);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.loadUrl("http://some.url");
    mWebView.setWebViewClient(new virtuoWebViewClient());

    mWebView.setOnKeyListener(new View.OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                if (keyCode == KeyEvent.KEYCODE_ENTER) {
                    // do nothing
                    return false;
                }
            }
            return false;
        }
    });

But still nothing, the "Go" button still submits the form :(, I'll keep trying, if anybody could point me in a different direction or share new ideas, I'll greatly appreciate it. Thx.

回答1:

I spent an awful long time looking for a solution, but nothing is perfect. This is the best workaround I could find, it replaces the 'return' (submit) action with a 'tab' action, unless focus is on a textarea or submit button:

$("form").keydown(function(e){
    if (e.which != 13) return; // ENTER
    if (e.target.type == "textarea" || e.target.type == "button") return;
    if ($("input[type=submit]", this).length == 1) return; // autosubmit form

    var nextTabbable = null;
    var $tr = $(e.target).closest("tr, form");
    var narrowContext = $tr.length && e.target.tabIndex == undefined && !$tr.is("form");
    if (narrowContext) nextTabbable = getNextTabbable($tr.add($tr.next()), e.target);
    if (!nextTabbable) nextTabbable = getNextTabbable(this, e.target);

    if (nextTabbable) {
        if (nextTabbable.type == "text" && nextTabbable.value != "") nextTabbable.select();
            nextTabbable.focus();
        return false;
    }
});

function getNextTabbable(ctx, current) {
    var $t = $("input[tabindex!=-1]:visible, select[tabindex!=-1]:visible, textarea[tabindex!=-1]:visible", ctx).not(":disabled");
    var docIndex = {};
    $t.each(function(i,e){ docIndex[e] = i });
    $sorted = $t.sort(function(a,b){ return a.tabIndex==b.tabIndex ? docIndex[a]<docIndex[b] : a.tabIndex<b.tabIndex ? -1 : 1 });
    return $sorted.get($sorted.index(current)+1);
}


回答2:

OK I had to let this simmer because it got a little frustrating, after lots of trial and error it seems that WebView by itself won't allow the behavior I was going for without EditText. I don't really need EditText for this app and I discovered that input type text shows the "Go" button but textareas don't, they replace it with a return carriage button (that isn't blue and doesn't send the form), it's cheap and rough but fits the purpose, so I basically ended up using textareas with the parameter rows="1" so it looks like an input type text.

<textarea rows="1" name="waiter"></textarea>

A very low-tech solution to hide the "Go", "Done" or "Enter" buttons XD.