0

I currently have a form in one of my applications which uses a hidden button as a fix for problems with the numeric keyboard on Android. Essentially, either pressing the enter key or focusing the button will submit the form.

Pressing enter works in Chrome (desktop), Firefox (desktop), and Safari (iOS) and only submits the form once. In IE, the browser is submitting the form twice, so I can only assume that it is focusing the submit button when the user presses enter.

Here's an example to demo this. In Chrome and other browsers I've tested, it will simply clear the box. In IE, it will alert for "Invalid quantity."

jsfiddle

HTML:

<form data-bind="submit: SubmitQuantity">
    Quantity: 
    <input id="quantity" type="number" data-bind="value: Quantity, valueUpdate: 'afterkeydown'"/>
    <button type="submit" data-bind="event: { focus: SubmitQuantity }" class="hidden_button"></button>
</form>

CSS:

.hidden_button {
    width: 0px;
    height: 0px;
    font-size: 0px;
    border: 0px;
    left: -9999px;
    padding: 0px 0px 0px 0px;
}

JS:

var viewModel;

function ViewModel() {
    var self = this;
    self.Quantity = ko.observable('');
    self.SubmitQuantity = function() {
        if (isNaN(self.Quantity())) {
            alert('Invalid quantity');
            return;
        }
        self.Quantity(undefined);
    };
}

viewModel = new ViewModel();
ko.applyBindings(viewModel);

Is there a way to prevent IE from doing this double submission that is caused by focusing the hidden field?

Nathan
  • 390
  • 1
  • 2
  • 10

1 Answers1

0

There isn't any really need to call your SubmitQuantity function twice. Not exactly sure of your Android problems (maybe you could elaborate?), but I suspect you are using the hidden submit button to actually post the form. Using a submit data-binding on a form element will prevent the form from submitting. From the KO docs:

When you use the submit binding on a form, Knockout will prevent the browser’s default submit action for that form. In other words, the browser will call your handler function but will not submit the form to the server. This is a useful default because when you use the submit binding, it’s normally because you’re using the form as an interface to your view model, not as a regular HTML form. If you do want to let the form submit like a normal HTML form, just return true from your submit handler.

So you could remove the hidden button entirely, and return true in your SubmitQuantity function when you are ready for the form to submit - in this example, it would be only after Quantity is a number.

self.SubmitQuantity = function() {
    if (isNaN(self.Quantity())) {
        alert('Invalid quantity');
        return false;
    }else{
        return true; // form will be submitted
    }
    self.Quantity(undefined);        
};

Updated fiddle

rwisch45
  • 3,692
  • 2
  • 25
  • 36
  • The stock Android keyboard does not properly handle numeric input fields. Instead of having an enter button, it has a "next" button which acts as a tab. To submit the form when the next button is pressed, the typical solution is to have a hidden button after the field that submits when focused. This is in a single page application, so I actually don't want it to submit. That's why I'm handling the submission how I am. The problem here is that in IE it submits twice with this demo. This is causing the 'Invalid quantity' alert to be thrown even if a valid quantity is submitted. – Nathan Mar 12 '14 at 20:44
  • I think it's bad UX to submit the form on mobile when hitting next. Next should be that, next.. – Martin Hansen Mar 12 '14 at 20:48
  • @MartinHansen I agree, but since there is no enter button on the numeric keypad there is no way to submit the form on Android without adding a visible button, hijacking the Next button, or building a custom keyboard and having every customer install it. Some mobile applications (such as mine) simply cannot afford the real estate needed for a visible submit button, and the company would much rather this over paying to build a custom keyboard just to add the enter key. – Nathan Mar 12 '14 at 20:51
  • What do you do if the user just clicks on the page again? Looking for a submit button? Maybe use blur instead? http://jsfiddle.net/2rYaZ/4/ not sure how this plays out in IE. I see your problem though. What about when the user clicks next, the number field is hidden, the submit button is showed, saying something like(submit 5 as quantity), that way you have the real estate issue solved. Just an idea, maybe not the ideal though.. – Martin Hansen Mar 12 '14 at 21:14
  • Or use the tab keycode on the input, and remove the submit button. http://stackoverflow.com/a/20253643/94394 – Martin Hansen Mar 12 '14 at 21:16
  • @MartinHansen I considered using the tab keycode, but this is a single page application with multiple forms. I only want it to submit on tab when they are in this particular form (since this is the only numeric one). I suppose I could check that document.activeElement is the quantity field, but I'd have to test this on all of our supported devices to be sure it's supported. As for the on blur, this will also submit when they click outside of the box, which I don't want. There are other buttons/items on the page for them to click that shouldn't submit. – Nathan Mar 13 '14 at 13:04
  • Create a custom binding that listens for the TAB keycode. And bind it only to the input. I have done this for the enter key. – Martin Hansen Mar 13 '14 at 15:43