The default button on enter on an ASP.NET form

I haven't really thought about this in a long time, but after searching a bit and finding some really complex solutions, I figured out a way to fire a "click" based on pressing enter in a text field. It works OK in IE and Firefox, which is good enough for me, and it only requires one line.

EmailTextBox.Attributes.Add("onKeyPress", "javascript:if (event.keyCode == 13) __doPostBack('" + LoginButton.UniqueID + "','')");

"EmailTextBox" is as you might suspect a text box control, while "LoginButton" is a link button. All it does is render an extra attribute in the rendered tag that checks for a key press, and if it's the enter key, it fires ASP.NET's __doPostBack method with the unique ID of the button that you want to virtually press. That in turn fires off whatever server-side event handlers you've wired up. You could pass in the eventargument as the second parameter in that Javascript if you wanted to.

I can't understand why this wasn't included somewhere in v2. They did offer a default button for the entire form, but I think that only works if you have actual buttons (I use LinkButtons almost exclusively). You could actually wire up any control name here if you wanted.

60 Comments

  • We use this in our apps all the time. Very handy! Even with regular buttons, there's still the problem of which one actually gets clicked when you have more than one in your form. By default it just has to do with whichever button is first on the page. It would be nice if a feature in 2.0 allowed you to specify default buttons for both the button and linkbutton. Have you posted anything on Product Feedback about it?

  • I don't remember. Maybe? I haven't thought this out enough to know what other implications there might be, such as those if you plant this thing inside a grid or something.

  • In ASP.NET V2 you can drive the enter behavior on any focus point on a page. You set this either on the <form> tag or by wrapping regions in an <asp:panel> and then setting the default button property on those container controls (the asp:panel approach is how you can have multiple default buttons all over the page). If the focus is inside that region and enter is hit, the container control will cause the right post-back control to fire.



    Hope this helps,



    Scott

  • That's awesome, Scott...thanks! :)

  • Jeff:



    I use this technique that I posted about a while back...



    http://www.mattberther.com/2003/06/000125.html



    Works everytime for me.

  • Matt: That solution isn't going to work if different text fields should activate different buttons.



    Scott: Good idea, but that only works with buttons, right? LinkButtons no?

  • I've been using a cool free control from MetaBuilders called DefaultButtons for my 1.1 apps. Here's the URL...



    http://www.metabuilders.com/Tools/DefaultButtons.aspx



    It makes the page a bit bigger because it injects some javascript to the client, but it has worked flawlessly for me. Works with link buttons too. Highly recommended.









  • Walker, your control is nice, but it seems still a little bit unperfect, for example, when I foucs on the second textbox and hit enter, Smack1 is foucsed and pressed on the page, althrough the label show Smack2 is fired

  • What happens if you have more than one textbox in the form.Then it doesn`t see the desired button but the first one in the form.How can I rounf this problem?

  • Sure it does. You set each TextBox to fire the right postback event as described above.

  • Scott...thanks! :)
    the panel solve the problem.

  • nice

  • I'm using LinkButton almost exclusively as well. Unfortunately Scott's suggestion only works in IE and not Firefox because there doesn't seem to be a Click() function on HTMLAnchorElement (this is what LinkButton are rendered as). Sadly looking at the W3C docs it looks like it isn't a requirement. Only HTMLInputElement is required to have that function.

  • Thanks Scott. But does not work with LinkButton and ImageButton (see http://support.microsoft.com/default.aspx/kb/921277). Maybe provide some standard scripting in the next .Net version?

  • First off, you don't need to check to see if a script is registered. Second, you're not wiring up anything to an alert box here. You're registering a script fragment that will execute when the page is loaded. You're not calling a function.

  • Thanks Jeff.

    I took out the alert box and just simply wrote:

    response.write("Got Here")

    when I click the button the data gets added and Got Here gets written.

    when I hit the enter key the data gets added but the "Got Here" doesn't get written.

    I'm baffled - any ideas?

    thanks,
    SImon

  • Thanks Scott, wrapping my second "form" in the panel and setting the default button did the trick. Thanks for the post, works great!

  • actually I was thinking of this solution but I did not have time to try it.
    Then I searched the internet to find some thing fast and this is it.

    Don't worry; all the rights are for you :)

  • After reading above i have made something like below for me just like window default button. Working fine but need to test more.


  • Should this code work for asp.net 1.1 too ?

    cheers

    -JD

  • I've been looking something that does that for ages. Thanks alot!

  • Hi All,

    Great solutions overall, however I can't seem to apply the theory to buttons which are not directly accessible in the code behind (such as buttons within templates of FormViews where a FindControl method is needed to access the control).

    Here's a short snippet from the code behind:

    Button btn = (Button)formView1.FindControl("btnUpdate");
    Panel1.DefaultButton = btn.UniqueID;

    I get an exception:

    The DefaultButton of 'Panel1' must be the ID of a control of type IButtonControl.

    I think the problem is Panel1 cannot find the button because it is nested in a template within the formview (i.e. the controls are roughly designed as:




    ...

    ...




    If anyone has a solution for setting buttons within templates as default please post!

    TIA

    Kevin.

  • Kevin: the DefaultButton property is of type string, so you need to set it to the UniqueID property of the control.

  • I used this in a user control and it worked fine. Thank you so much!

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    TextBox1.Attributes.Add("onKeyPress", "javascript:if (event.keyCode == 13) __doPostBack('" + btnGo.UniqueID + "','')")
    End Sub

  • If there were multiple buttons on the page then the page could end-up reloaded a couple of times (call page_load multiple times). Returning false avoids the extra reload.

    The following change fixes this problem.
    EmailTextBox.Attributes.Add("onKeyPress", "javascript:if (event.keyCode == 13) {__doPostBack('" + LoginButton.UniqueID + "',''); return false);");

  • You know what could solve all this? Having multiple forms on your page. Too bad you usually have the complete page in a form and nested forms are not allowed in HTML.

  • This doesn't sit well with me but it definitely does the trick for FormViews with templates. Add a panel into each template and set the DefaultButton value there.



    ...



    ...

  • I would use:

    this.Form.DefaultButton = LoginButton.UniqueID;

  • Note that if you are using this method in a user control you must use ClientID instead of UniqueID.

  • I was looking for similar problem but the stated solution did not work.
    My scenario:
    2 textboxes
    3 buttons
    My solution:
    Page.Form.DefaultButton = btnSubmit.UniqueID

  • Making a custom linkbutton server control from this website worked great for me in both IE and Firefox:

    http://kpumuk.info/asp-net/using-panel-defaultbutton-property-with-linkbutton-control-in-asp-net/

  • If you want to fix this problem without having a lot of extra markup, try this:
    http://sentia.com.au/2007/10/22/fixing-the-enter-key-in-asp-net-with-jquery

  • Thanks. This is great !

  • Josh, thanks for that 1 textbox bug find. I was having trouble with a button not doing anything on return. I added a second textbox, as you suggested, and it works now.

  • Thanks for the info, it helped my come up with a slightly different solution:
    http://droyad.blogspot.com/2008/04/enter-key-on-linkbuttons.html

  • Thanks Jeff,
    I have beed searching for days and your method seems to work just fine for me.

    Thanks again.

  • Another option is to put the controls in a panel and set the DefaultButton property to the button.






  • I have a slightly different but related problem.
    I want to suppress the default submit behavior when the enter key is hit. Limiting this to an element would be a bonus. Any ideas or pointers?

  • holy crap Scott, you're like the asp.net supreme guru. Actually, my opinion is bias dude, I've read tons of your books and watched a good number of your videos.

    Keep kickin' arse and takin' names, as I'm sure the internet community truly appreciates it, I know I do!

    Thanks.
    Jon

  • Damn Scott, you just lifted a stone of my chest thank you for sharing your knowlege! You da' man! :o)

  • Thanks for the simple, effective, cross-browser solution Jeff! It works great in IE, Firefox, and Chrome. You just saved millions of our users (and more importantly us developers that test the site constantly) much hassle. Thanks again!

  • I have been trying to make this work for a couple of hours and cannot get it working - Am I missing something (Using BN Net Framework 1.1)

    Using two buttons and trying to get textbox1 to initiate a button2 response. Keeps going to button1 response. See Code Below:

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    TextBox1.Attributes.Add(”onKeyPress”, “javascript:if (event.keyCode == 13) __doPostBack(’” + Button2.UniqueID + “‘,”)”)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Label1.Text = “button 1 clicked”
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Label1.Text = “Button 2 clicked”
    End Sub

    Thanks Barry

  • Hey Jeff, I've been using your method since I discovered it a while ago. I recently ran into an issue (surprised I hadn't earlier) in that the __doPostBack method is bypassing client validation (using ASP.NET validation controls). While looking around for a more elegant solution, I figure it simply had to do with adding some code to your method to check for client validation before posting back. Following PLBlum's advice at:

    http://forums.asp.net/p/1349427/2751480.aspx

    Using your example above, I modifed your method as follows:

    EmailTextBox.Attributes.Add("onKeyPress", "javascript:if(event.keyCode == 13){ if(Page_ClientValidate('" + LoginButton.ValidationGroup + "')){__doPostBack('" + LoginButton.UniqueID + "','')}}");

    This little snippet will now check client validation (and the validation group if you're doing multiple forms on one page) before processing the Default Button Enter Key press.

    Hope that helps anyone else who might have discovered this. Thanks for the starting code, however, it's been excellent!

  • Thanks for the tip on setting the Default button on a panel, saves a lot of time :-)

  • You can just use this control as you would a normal panel and it works with LinkButtons as well.

    public class DefaultButtonPanel : Panel
    {
    protected override void OnLoad(EventArgs e)
    {
    if (DefaultButton != "")
    {
    LinkButton btn = FindControl(DefaultButton) as LinkButton;
    if (btn != null)
    {
    Button defaultButton = new Button();
    defaultButton.ID = btn.ID + "_Default";
    defaultButton.Text = " ";
    defaultButton.Style.Add("display", "none");

    PostBackOptions p = new PostBackOptions(btn, "", null, false, true, true, true, true, btn.ValidationGroup);
    defaultButton.OnClientClick = Page.ClientScript.GetPostBackEventReference(p) + "; return false;";

    Controls.Add(defaultButton);

    DefaultButton = defaultButton.ID;
    }
    }

    base.OnLoad(e);
    }
    }

  • Oh and it works with validation groups. You could tweak that PostBackOptions object to include postback url, etc, but I didn't need it.

  • protected void Page_Load(object sender, EventArgs e)
    {
    Page.Form.DefaultButton = .UniqueID;
    }


    Note: may be button, imagebutton

  • Dude, you are the MAN! Thanks for the solution.

  • SNRaj

    Page.Form.DefaultButton = .UniqueID;

    That worked like a charm for me.
    Thanks a lot.

  • this is great!

  • Your help is much appreciated. Thanks!

  • Thanks for posting this.

  • Thanks for this post..

  • For me the best solution is to use the Panel

  • thx for solution. you save my time.

  • This solution is still very good, tried it today on Asp.Net 4.0 and it works very well. Thanx!

    I had to add some code to use it inside an element.
    Code example:
    ---
    TextBox Password =(TextBox)Login1.FindControl("Password");
    LinkButton ButtonLogin = (LinkButton) Login1.FindControl("ButtonLogin");
    Password.Attributes.Add("onKeyPress", "javascript:if (event.keyCode == 13) __doPostBack('" + ButtonLogin.UniqueID + "','')");
    ---

  • I used this and works fine in IE and FF and with LinkButton. Uses jQuery.

    $('#').keypress(function(e){
    if(e.keyCode==13){
    if(Page_ClientValidate('')){

    }
    }
    });

    Thanks to everyone who contributed.

  • Thank you so much Jeff. It works very well. You make me save a lot of time.

    Keep the good work !!

  • I need help in this please..in c#

    when i click button 1 it opens one pdf with the nameddestination...

    when i click button 2 it opens in another pdf with the namedestination...


    i want to open the different name destination in opne pdf when i click the button...

    example... button 1 should open nameddestination 4

    button 2 should open nameddestination 7

    but with this code.. the 2 nameddestination open in "2" pdf..

    i want to open it in "1" pdf.. can you please help me...

    Plz.... Desperate......Desperate.....


    ******this is my code*******


    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Linq;

    using System.Text;

    using System.Windows.Forms;

    namespace button_click_pdf_2

    {

    public partial class Form1 : Form

    {

    public Form1()

    {

    InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)

    {



    System.Diagnostics.Process myProcess = new System.Diagnostics.Process();

    myProcess.StartInfo.FileName = "AcroRd32.exe";

    myProcess.StartInfo.Arguments = " /n /A \"nameddest=nameddest\" C:\\temp\\file.pdf\"";

    myProcess.Start();

    }

    private void button2_Click(object sender, EventArgs e)

    {

    System.Diagnostics.Process myProcess = new System.Diagnostics.Process();

    myProcess.StartInfo.FileName = "AcroRd32.exe";

    myProcess.StartInfo.Arguments = "/n /A \"nameddest=nameddest:\" C:\\temp\\file.pdf\"";

    myProcess.Start();



    }

    }

    }

  • Thanks for the assistance everyone.

    The method of setting the DefaultButton="btnMethod" for a "<asp:Panel" worked for me.

Comments have been disabled for this content.