The Single Form Problem with ASP.NET
August 4th, 2004
A common problem with ASP.NET is that every page is a single form and many submit buttons and form elements can be placed all over the page. To simulate the behavior of many virtual forms in one real form the ASP.NET technique is to use the identity of the submit button to determine which virtual form sent the HTTP request. But what if Enter is pressed and the identity of the button is not defined? That is a usability nightmare, but there is a solution...
Every time a user presses Enter in a text field or on any form element it will trigger the submission of the form. Since it is really only a single form and no button is currently selected a default button is selected which can result in unwanted behavior which tends to confuse the user.
In a specific case I worked on a website which has a search box at the top of every page. It does a basic search, but the site features a page with an advanced search. The advanced search has a separate submit button but the basic search box and button are still at the top of the page. Pressing enter while the cursor is focused in the advanced search box simply triggers the default search to run, likely without any text value. The users were very frustrated with that behavior. The users can get around this by simply clicking the advanced search submit button with the mouse, but as we have all learned from our favorite search engine, we just hit enter once we have our keywords entered.
A quick look around the web and I found that many people were having this same problem but nobody had a good solution, so I went digging. The solution relies on Javascript. The event handler onkeydown is the magic handler to make it all work. Essentially you can capture all key events with onkeydown and use Javascript to define it's behavior. With ASP.NET the common solution I found was to define the onkeydown handler for the entire page. OK, I see problems with that, but let's go with it. I put together a static example to try it out. The page has two distinct submission areas but the page is made up of only a single form. Pressing enter while in one of the text boxes should cause the default behavior. But what I have done here is check for the Enter key and determine which button should be pressed.
The difference you will notice is in the query string which appears in the location bar of the browser. If the advanced search is activated the query string will show a value for the AdvancedSearchButton. If the basic search is activated the value for the BasicSearchButton is defined. This is what ASP.NET keys on for the code behind so we want to contro it with multple virtual forms on the page. It appears this technique works.
In this case I have a Javascript variable called context which defaults to "basic" for the basic form. In each text box I have an onfocus which will update the context. Once Enter is pressed the onkeydown handler determines which context is current and chooses which button to click with the Javascript.
There is a third button you can press to see the current context. You can see it change after moving the cursor to the other text box. This solution works just fine, but in studying the onkeydown handler and testing it in different browsers I found there is a much simpler means of solving this problem. And while this solution is what is the commonly recommended approach in many online forums it has some problems which creep in which must be resolved.
The onkeydown handler simply tells the current container to send all key events to that handler. This means that if I place the event handler in a table tag or a div tag, anything in that HTML block will use that handler. So I could have several form areas on a single page and if each is contained in seperate tables of div tags I can place the onkeydown events where I find them most useful. In the new version I can remove the context variable and much of the Javascript and simply wrap div tags with the event handler around the two search forms. The handler will find the desired button and click it. This solution also works in both MSIE and Mozilla/Firefox as it is using standard Javascript/DOM to do it. I have tested it in both browsers, resolved any problems with simple workarounds, and now the code is browser neutral. And adding it to an ASP.NET page is extremely easy.
The downside of the first approach is not easily revealed. First, it requires more Javascript and each page will require unique logic to define which context is associated with what button depending on how many buttons appear on the page. It also requires the onfocus handler to set the context in each form element. The second approach reduces the necessary Javascript and the added event handlers.
The second problem is that the Enter key is being suppressed. In the case of a textarea element, it is completely valid to press Enter to move to the next line in the box. In this case we do not want the form to submit. By carefuly placing the onkeydown handlers outside the scope of the textarea elements the proper behavior can be maintained.
Lastly, it seems it is helpful to set the focus for the page for the likely default form on the page. Doing so is shown in both examples with the init function. Sometimes a user will simply want the default results from a form and press enter without hitting tab or clicking into a form to set the context. So defaulting the context using Javascript is a good method to default the page context and enhance usability.

August 23rd, 2004 at 11:48 pm
thanks, for the information, i currently have the very same problem, i have a custom control as a header of every page which contains a search text box, and a submit button. Eventually after reading a few forums i've come to using this keydown approach. I'm not happy with it, but it works .. Apparently .net framework 2.0 is supporting server side events transparently w/o full page postbacks (i assume using hidden iframes or something), which should sidestep this problem. Why they decided not to support multiple forms on a page is beyond me.
August 24th, 2004 at 2:23 pm
Thank you. This is a much more graceful way of solving this problem. It is so obvious once you know the answer. My users will appreciate your contribution.
October 11th, 2004 at 2:44 pm
This works as long as the focus is in a textbox or other control. If a div has just static text as given below, then Mozilla firefox bypasses
the keydown handler of the DIV tag. Works fine in IE. I appreciate your comments.
askdjhakjsdhakjdhakjdsh
alksdjalkdsjalkdjalksdj
October 11th, 2004 at 2:45 pm
This works as long as the focus is in a textbox or other control. If a div has just static text as given below, then Mozilla firefox bypasses
the keydown handler of the DIV tag. Works fine in IE. I appreciate your comments.
<body onkeydown="alert('body-keydown')">
<div onkeydown="alert('div-keydown')">
askdjhakjsdhakjdhakjdsh<br>
alksdjalkdsjalkdjalksdj
</div>
</body>
January 18th, 2005 at 1:51 pm
I'm rather new at javascript so do you have an example of the code/javascript events that you used?
January 18th, 2005 at 1:59 pm
The code is right in the sample page which is linked from this blog entry. Just look for onkeydown and follow the Javascript there.
April 1st, 2005 at 8:02 pm
Hi
I my FireFox 1.02, your example always submits the basic button.
I've been looking for a solution on this for 4 hours now, so any suggestions are very welcome
Regards
Henrik, Syneo
April 22nd, 2005 at 11:28 am
bravo, works like magic
May 3rd, 2005 at 10:07 am
somehow i am unable to make it work. the submit on hit-enter works fine in IE but not ff. is the getElementbyID the right one for FF?
May 5th, 2005 at 11:11 am
Sorta unrelated question, are you using Visual Studio? Because I noticed in view source that you had your tags like "" and I can't get Visual Studio to not strip those out, if you are using Studio, how'd you get it to work? Thanks.
May 5th, 2005 at 11:15 am
Sorry, I'm talking about the tags with the closing "slash" - ""
May 8th, 2005 at 4:54 pm
Those examples were just static files created in VI actually. In VS.NET 2005 they have updated it to DTD aware. It will validate your code against live schema and underscore any invalid markup. They also come up as warnings during compilation. The entire time I have used VS.NET 2005 so far I have only use XHTML 1.0 Transistional simply because I still want to code to be like HTML 4 but have the XML rules enforced. This allows me to do some things in Javascript more reliably.
Also, I have noticed that Firefox behaves badly with the above example lately. I need to recode it and post an update about the problem.
June 29th, 2005 at 9:24 am
Thanks! It is the best explained solution to the problem I've read.
July 29th, 2005 at 6:50 pm
OH MY GOD YOU ARE A GENIUS!!! thank you!
August 10th, 2005 at 12:42 pm
This worked great. Thanks for such an elegent solution.
My only issue now is that the second "default" button does not "highlight" when I enter the textbox like the actualy default button of the form does. Do you know any way to accomplish this?
November 22nd, 2005 at 12:17 pm
WOW, I slapped this code into my tag, and solved all my issues. Thanks so much.
July 19th, 2006 at 6:09 am
Hi,
Thanks for this great tip. I've found a similar approach in ITTopics:
But, I wonder if anyone has found a solution which wouldn't require to add code for any textbox that we add on the form. Any ideas?
You are welcome to email me, after posting your reply on this blog!
Thanks
September 1st, 2006 at 5:07 am
A simple and effective solution. Thanks very much.
October 11th, 2006 at 10:51 am
Hey, great solution! This worked perfectly for me.
Thanks!
July 11th, 2007 at 7:03 am
My users were moaning about an ASP application refreshing the screen when they pressed the 'Enter' key.
I stuck in your JavaScript, tweaked it a bit to act on different buttons depending on what page was displayed,
and it worked a treat
Many Thanks
August 23rd, 2007 at 9:16 am
Hello,
I tried this in firefox, But it dosent worked for me.
Any help in FireFox?