Monday, September 19, 2011

Wicket Form Submission in IE

No matter how much developers hate it, Internet Explorer is here to stay. And one of its fun little idiosyncrasies is how it handles form submission when a user presses [enter] with a text box selected. In most browsers, doing that would cause the form to be submitted as if it had been submitted by pressing the form's first submit, with the submit's name and value in the request. However, IE does not do that. This problem is universal in web development but the result in Wicket is that the Form's onSubmit() method gets called but none of the Button's onSubmit() methods do. If the Button's onSubmit() method is the one that deals with the data that was submitted, the user isn't going to get the result they expect and it's entirely possible that the information they entered may be lost.

In looking for a way to solve this, I ran across Wicket's setDefaultButton() method. However, that really just changes the rendered HTML in a best-effort attempt to override which button is used by browsers that do submit one by default. But since IE doesn't do that to begin with, setDefaultButton() won't have any effect.

Thankfully, IE's form submission problem can be addressed reliably in Java. The approach I took was to override a Form's delegateSubmit() method. Unless you have default form processing turned off, delegateSubmit() is called after validation passes and the models have been updated, but before any of the onSubmit methods are called. The IFormSubmittingComponent (typically a Button of some sort) that submitted the form is passed in as a parameter and this is the perfect opportunity to set one if there isn't one!

public class DefaultingForm extends Form {
    // Constructors go here...

    protected void delegateSubmit(IFormSubmittingComponent submittingComponent) {
        if(submittingComponent==null) {
            submittingComponent = getDefaultButton();
        }
        super.delegateSubmit(submittingComponent);
    }
}

You could set submittingComponent to any value you want but be warned - since that only happens when no submit is sent by the browser, any conditional logic you put in the if-block may only be seen by IE users. That kind of browser-specific behavior could be considered just as bad as the behavior we are trying to remedy! Instead, using the value of getDefaultButton() helps ensure that all browsers will get the same result. Browsers that choose a default button will benefit from the markup changes setDefaultButton() causes. And IE will benefit by having the same button chosen for it. I'm not sure why an approach like this wouldn't be used by Wicket itself. Thoughts?

No comments:

Post a Comment