When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, January 9, 2008

Two Common Pitfalls When Submitting a Web Form Using the Enter Key

By Scott Mitchell


Introduction


When filling out a form on a web page you have probably experienced the fact that if you hit enter when typing in a single-line textbox the form is submitted. This is a feature that browsers provide to make it possible to submit a form without having to touch the mouse. For example, when visiting Google's homepage focus is immediately set to the search textbox and, after typing in your query, you can hit Enter to submit the form and see the results.

Since it is the browser that submits the form when the Enter key is pressed, you might think that as an ASP.NET developer you do not have to worry about this functionality. Just create a Web Form, like always, and the user can optionally use the Enter key to submit the form. Unfortunately, the life of an ASP.NET developer is never that simple! There are two cases where the user hitting Enter doesn't result in the desired behavior. The first case involves a page with multiple Submit buttons. Hitting Enter has the effect of submitting the form using the first Submit button on the page, although you may mean for a different button to have caused the submit (because you want its Click event handler to execute). The second case involves hitting Enter in a form with only one form field when using Internet Explorer.

In this article we will examine these two cases in detail and look at simple workarounds. Read on to learn more!

- continued -

A Quick Primer on Form Submissions


When a Web Form is submitted, the browser posts back the names and values of the form fields. The form fields are the textboxes, drop-down lists, checkboxes, radio buttons, and hidden form fields defined within the <form> tags. The web browser will initiate the form submission process if a submit button within the form is clicked, if the user hits the Enter key while the focus is in a single-line textbox within the form, or if the form's submit() function is called.

Another important piece of information that may be included is the name and value of the submit button that caused the form submission. That is, if the form was submitted because the user clicked a submit button or hit the Enter key while focused in a single-line textbox, the browser will include the name and value of the form's submit button. This is important because the presence of this name and value pair is what triggers ASP.NET to raise the corresponding Button control's Click event. If the name and value of the submit button is not included, the Click event is not raised. Consequently, it is usually essential that the appropriate submit button's name/value pair is sent by the browser when the form is officially submitted because there is usually form processing logic that occurs in that Button control's Click event handler.

In HTML there are two types of buttons: submit buttons and regular buttons. A submit button is one that, when clicked, will submit the form. A regular button, however, does not have any special action it performs when clicked. When using regular buttons, page developers typically execute JavaScript on the button's client-side onclick event. So it is possible to have a regular button submit the form by executing JavaScript in the button's onclick event that calls the form's submit() function. The HTML for a submit button is an <input> element with a type attribute value of "submit". A regular button has a type attribute value of "button". By default, the ASP.NET Button Web control renders a submit button.

To hammer home these concepts, let's build at a simple ASP.NET Web Form, examine its rendered markup, and then see what information is sent back to the server on postback. Create a new ASP.NET page and add a variety of Web controls. I have created a page with two TextBox controls, a RadioButtonList, a CheckBox, and a Button. (This page, SimpleWebForm.aspx is included in the download at the end of this article.)

<form id="form1" runat="server">
   <p>
      What is your name?
      <asp:TextBox ID="YourName" runat="server"></asp:TextBox>
   </p>

   <p>
      What is your age?
      <asp:TextBox ID="YourAge" runat="server" Columns="3"></asp:TextBox>
   </p>

   <p>
      What is your favorite color?<br />
      <asp:RadioButtonList ID="FavoriteColor" runat="server">
         <asp:ListItem Selected="True">Red</asp:ListItem>
         <asp:ListItem>Green</asp:ListItem>
         <asp:ListItem>Blue</asp:ListItem>
      </asp:RadioButtonList>
   </p>

   <p>
      <asp:CheckBox ID="EatGreenEggsAndHam" runat="server" Checked="True"
      Text="Will You Eat Green Eggs and Ham?" TextAlign="Left" />
   </p>

   <p>
      <asp:Button ID="SubmitButton" runat="server" Text="Submit Form" />
   </p>
</form>

When this page is visited by a browser, these controls are rendered into the following HTML:

<form name="form1" method="post" action="SimpleWebForm.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="..." />
</div>
   <p>
      What is your name?
      <input name="YourName" type="text" id="YourName" />
   </p>

   <p>
      What is your age?
      <input name="YourAge" type="text" size="3" id="YourAge" />
   </p>

   <p>
      What is your favorite color?<br />
      <table id="FavoriteColor" border="0">
   <tr>
      <td><input id="FavoriteColor_0" type="radio" name="FavoriteColor" value="Red" checked="checked" /><label for="FavoriteColor_0">Red</label></td>
   </tr><tr>
      <td><input id="FavoriteColor_1" type="radio" name="FavoriteColor" value="Green" /><label for="FavoriteColor_1">Green</label></td>
   </tr><tr>
      <td><input id="FavoriteColor_2" type="radio" name="FavoriteColor" value="Blue" /><label for="FavoriteColor_2">Blue</label></td>
   </tr>
</table>
   </p>

   <p>
      <span style="font-weight:bold;"><label for="EatGreenEggsAndHam">Will You Eat Green Eggs and Ham?</label><input id="EatGreenEggsAndHam" type="checkbox" name="EatGreenEggsAndHam" checked="checked" /></span>
   </p>

   <p>
      <input type="submit" name="SubmitButton" value="Submit Form" id="SubmitButton" />
   </p>
<div>
   <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="..." />
</div>
</form>

Compare the ASP.NET declarative markup to the rendered HTML. The rendered HTML includes two additional hidden form fields (__VIEWSTATE and __EVENTVALIDATION), and the ASP.NET Web control syntax has been changed to valid HTML. The Button control, for example, has changed from <asp:Button runat="server" ... /> to an HTML submit button (<input type="submit" name="SubmitButton" value="Submit Form" id="SubmitButton" />).

Go ahead and enter some values into the form fields.

A simple Web Form.

The Request.Form collection contains all of the form fields sent by the browser. To inspect these on postback you can set a breakpoint and examine the collection through the debugger. Or you could perform a simple Response.Write(Request.Form.ToString()). Or you could bind the Request.Form collection to a data Web control, which I have done for this page. After submitting the form with the values shown above, the page indicates that the following name/value pairs were sent from the browser:

The Web Form values sent to the server from the browser.

Each form field's name/value pair was sent by the browser, including the submit button's name and value (SubmitButton and "Submit Form", respectively). Because the button's name and value were sent in the form fields, the SubmitButton Button control's Click is raised. Note that you can submit the form by clicking the "Submit Form" button or by hitting Enter in either the YourName or YourAge TextBoxes. In either case, the form is submitted and the SubmitButton's name/value pair is returned by the browser. (You can disregard the __VIEWSTATE and __EVENTVALIDATION name/value pairs, as they are not pertinent to this article's topic.)

In a nutshell, everything works wonderfully if the form is submitted using the appropriate submit button, because that button's name and value are sent from the browser to the server and the corresponding Button control's Click event is raised. But there are two cases when using the Enter key to submit the form that the appropriate submit button's name/value pair is not sent. The remainder of this article examines these two cases in detail, along with easy to implement workarounds.

Multiple Submit Buttons on the Page


As we discussed earlier in this article, when a user hits Enter in a single-line textbox, the browser submits the form. In most situations, the browser includes the submit button's name/value pair in the form fields returned on submission (although this is not always the case, as we'll see later on in this article). If there are multiple submit buttons on the form, the browser sends the first submit button's name/value pair on form submission (the first one being the one that first appears in the rendered HTML markup, not necessarily the one that appears visually first on the page).

Imagine that you have a page that collects user input and everything works fine. The user can hit Enter to submit the form, which causes the browser to send the submit button's name/value pair, which executes the corresponding Button's Click event handler, where you process the user's entered data. Great. But what would happen if you (or a coworker) updated the site's master page and included an ASP.NET Button control that, when clicked, would, say, Response.Redirect the user to a Login page? With this change, if a user visited your form and hit Enter to submit it, the browser would send the Login submit button's name/value pair, and the user would be redirected to the login page!

To illustrate this concept, I created a master page with a "Login" Button control appearing before the content page's markup. Then in the content page I recreated the form fields we used in the previous section. When this page is visited through a browser, the form has two submit buttons, as illustrated by this HTML snippet:

<form name="aspnetForm" method="post" action="MultipleButtonsBad.aspx" id="aspnetForm">
   ...

   <input type="submit" name="ctl00$LoginButton" value="Login" id="ctl00_LoginButton" />

   ...

   <input type="submit" name="ctl00$ContentPlaceHolder1$SubmitButton" value="Submit Form" id="ctl00_ContentPlaceHolder1_SubmitButton" />
</form>

If you visit this page and submit the form by hitting Enter in the YourName or YourAge textboxes, the Login button's name/value pair is submitted (ctl00$LoginButton and Login, respectively). This is depicted by the screen shot below, which shows the form fields sent by the browser in the GridView.

The Login Button's name/value pair is sent to the server.

The net result is that the Login Button's Click event is raised on postback, and the user is sent to the Login page. Talk about a confusing user experience! Everything works fine if they click the "Submit Form" button, but if they hit Enter, they are redirected to the Login page.

To fix this, we need to instruct the Login Button control that it should not render as a submit button, but rather a regular button. To accomplish this, set the Login Button's UseSubmitBehavior property to False. This causes the Login button to render as a regular button along with the necessary JavaScript to submit the form when the button is clicked (along with sending additional information so that ASP.NET knows that that button was what caused the postback so that its Click event handler can be raised).

With this change, the page's rendered markup now looks like:

<form name="aspnetForm" method="post" action="MultipleButtonsBad.aspx" id="aspnetForm">
   ...

   

<input type="button" name="ctl00$LoginButton" value="Login" onclick="javascript:__doPostBack('ctl00$LoginButton','')" id="ctl00_LoginButton" />



   ...

   <input type="submit" name="ctl00$ContentPlaceHolder1$SubmitButton" value="Submit Form" id="ctl00_ContentPlaceHolder1_SubmitButton" />
</form>

As you can see, the Login Button is now rendered as a regular button and its onclick event executes JavaScript that initiates the postback.

Using Enter to Submit a Form with Only One Single-Line TextBox


Another gotcha involving submitting forms with the Enter key arises with Internet Explorer and forms with just one single-line TextBox. Earlier I said that when hitting Enter in a single-line textbox, the browser submits the form and (usually) includes the first submit button's name/value pair in the form submission information. Unfortunately, this is not the case when using Internet Explorer and a Web Form with just one single-line TextBox. A more thorough description of this problem is documented in an earlier article of mine, Enter and the Button Click Event.

In short, the workaround is to never create a Web Form with just one single-line TextBox. If your form only requires one single-line TextBox, then add another one but use Casecading Stylesheets (CSS) to hide it. Just add markup like:

<asp:TextBox ID="DummyTextBox" runat="server" Style="visibility:hidden;display:none;" />

Yes, it's a hack, but it works.

The download at the end of this article includes an example of a form with just one single-line TextBox so that you can see how the Enter key submits the form, but does not cause the submit button's Click event handler to fire. Another demo adds a second, hidden single-line TextBox so that the submit button's server-side Click event is fired whether the user clicks the button or hits the Enter key.

Happy Programming!

  • By Scott Mitchell


    Further Readings:

  • Enter and the Button Click Event
  • Using JavaScript to Prevent or Trigger Form Submission When ENTER is Hit
  • Attachments


  • Download the Demo (in ZIP format)


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article