views:

149

answers:

2

Hi

I have an issue that appears in all browsers.

I am working with ASP.NET MVC.

My controller renders an html form with various submit buttons (the reason for this is explained in the Addendum below).

Whilst tabbing sends the focus to the right submit button under the right circumstances, hitting enter seems to submit the form using the wrong button. I can tell which button has submitted the form using the HttpContext.Request.Params collection as follows:

        foreach (var step in WizardSteps)
        {
            // A naming convention links the step action to the button name.
            // If returns null, then it was a Next or Previous button
            string s = step.Value.ActionName;
            if (ControllerContext.HttpContext.Request.Params[s + "Button"] != null)
            {
                return s;
            }
        }
        return null;

[I am designing a wizard framework in ASP.NET MVC, hence the WizardSteps collection. See the Addendum]

SUMMARY:

The issue is that, if the user simply hits enter from the last input control, the form gets submitted using the WRONG button, instead of using the submit button that follows in the rendered html (Ie, the "NEXT >>" button). Hitting the Tab key sends the focus to the correct control.

Surely hitting the Tab key and the Enter key should send the focus to the same place?

Can you think what is happening? Tabbing happens in the correct order, so that is not the issue.

PLEASE NOTE: As this is an HTML issue, it is no good trying to solve it via jQuery.

ADDENDUM:

I am designing a wizard framework for ASP.NET MVC. I need a lot of wizards so it is worth while putting in the extra effort. I have a base controller that is smart enough to figure out what steps there are and in what order (it builds WizardSteps using attributes and reflection). All is working, but...

A previous issue was solved (just one text input control produces an error in IE). But now this has me snookered: any framework has to produce standard behaviors.

These are HTML issues, so please, no jQuery.

SOURCE CODE OF FORM:

<div id="wizardStep">
    <form action="/Membership/Form" id="wizardForm" method="post" name="wizardForm" onclick="Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));"
    onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, updateTargetId: &#39;wizardStep&#39; });">
    <input name="wizardData" type="hidden" value="EncryptedFormValuesGobbleDeGooke" />
    <div class="WizardNavigator">
        <input type="submit" class="Before" name="StartButton" id="StartButton" value="Start" />
        <input type="submit" class="Before" name="CategoryButton" id="CategoryButton" value="Category" />
        <input type="button" class="Current" name="ContactDetailsButton" id="ContactDetailsButton" value="Contact Details" />
        <input type="button" class="After" name="IllnessDetailsButton" id="IllnessDetailsButton" value="Illness Details" />
        <input type="button" class="After" name="LinkUpButton" id="LinkUpButton" value="Link Up" />
        <input type="button" class="After" name="ConfirmButton" id="ConfirmButton" value="Confirm" />
        <input type="button" class="After" name="CompleteButton" id="CompleteButton" value="Done!" />
    </div>
    <div class="WizardButtons">
        <input class="Start" type="submit" value="Start >>" title="Start >>" name="topNextButton"
            id="topNextButton" />
    </div>
    <p>
        Please enter the details of the person to whom newsletter and other information
        should be sent;</p>
    <fieldset>
        <legend>Name</legend>
        <div class="editor-label">
            <label for="Title">
                Title</label>
        </div>
        <div class="editor-field">
            <input id="Title" name="Title" type="text" value="" />
        </div>
        <div class="editor-label">
            <label for="FirstName">
                First Name</label>
        </div>
        <div class="editor-field">
            <input id="FirstName" name="FirstName" type="text" value="" />
        </div>
        <div class="editor-label">
            <label for="LastName">
                Last Name</label>
        </div>
        <div class="editor-field">
            <input id="LastName" name="LastName" type="text" value="" />
        </div>
    </fieldset>
    <fieldset>
        <legend>Postal Address</legend>
        <div class="editor-label">
            <label for="Address">
                Address</label>
        </div>
        <div class="editor-field">
            <textarea cols="40" id="Address" name="Address" rows="10"></textarea>
        </div>
        <div class="editor-label">
            <label for="Postcode">
                Postcode</label>
        </div>
        <div class="editor-field">
            <input id="Postcode" name="Postcode" type="text" value="" />
        </div>
    </fieldset>
    <fieldset>
        <legend>Comm Details</legend>
        <div class="editor-label">
            <label for="Email">
                Email</label>
        </div>
        <div class="editor-field">
            <input id="Email" name="Email" type="text" value="" />
        </div>
        <div class="editor-label">
            <label for="Telephone">
                Telephone</label>
        </div>
        <div class="editor-field">
            <input id="Telephone" name="Telephone" type="text" value="" />
        </div>
    </fieldset>
    <div class="WizardButtons">
        <input class="Start" type="submit" value="Start >>" title="Start >>" name="NextButton"
            id="NextButton" />
    </div>
    </form>
</div>

The problem is that when hitting the Enter key when the user is in the telephone text input, the form submits as if the StartButton submit button had been clicked.

Which is wrong, and I can't see any issues with the html to cause this. Hitting the tab key correctly sends the focus to the NextButton submit button.

A: 

IE is often a bit problematic when posting on pages with multiple forms. Given this, there isn't a lot you can do to make the behaviour regular.

If you're developing some sort of frame-work, it might be a better idea to flag a hidden field when your form is filled out (e.g. via JS) and have all submits go to the same handler.

You can then read the set flags and handle the forms in turn.

Iain Ballard
A: 

Chris gave me the hint for solving this, that in turn gave me the words to google for.

I was expecting that there was a default behaviour with the Enter key with HTML forms. Well, there is, but not what I expected.

HTML FORM DEFAULT BEHAVIOUR WHEN USER HITS ENTER KEY:

The form will submit using the FIRST submit button in the html flow. It does NOT do what I expected, which was that the next submit button in the HTML after the text input control where the user hit enter.

I have tested this behaviour in every modern browser I can lay my hands on and it seems to hold.

A number of blogs support this view, notably:

Html Workaround for HTML forms with multiple submit buttons and Enter key behaviour

I have used the recommended workaround in that post. Ie, placing a submit button at the very top of the form, "hidden" by placing it in a div tag with height and width set to 0:

<div style="height:0px; width:0px; position:absolute; overflow:hidden">
    <input type="submit" />
</div>

This works a treat in all browsers and my MVC wizard framework has inched closer to completion.

IMPORTANT: You MUST ensure that this is the FIRST submit button in the form!! Otherwise, this workaround won't work.

WIND BAG SECTION:

I think that this is one of the great things about MVC: it forces you to understand HTML, which is what I live off.

I hope this helps someone else.

THANKS:

To Chris for pin pointing the error and to Matthew Smith for a similar suggestion to a different problem.

Also, to Iain Ballard's answer about multiple forms. I will keep that on record, but the problem here was not related to multiple forms, rather, to multiple submit buttons.

awrigley