ASP.NET has great limitation — only one server form on the page. Even if you are developing complex page, which looks like several forms with different submit buttons, in fact you have only one form. So we have a problem: How browser understanding which button should be triggered when user pressed ENTER? It uses first Button control (usually that’s wrong), and if you have LinkButton‘s, they would never be triggered. In ASP.NET 2.0 new property has been added to the Panel and HtmlForm controls — DefaultButton, which can be used to specify ID of the control, which implements IButtonControl interface (usually Button and LinkButton). This button control would be triggered when user pressed ENTER. But there is one big problem exist: LinkButton control would not be triggered in Firefox on ENTER. In this article I will show why this problem take place and how to solve it.
Let’s look how DefaultButton is working in ASP.NET. Here is simple example:
1 2 3 4 5 | <asp:Label runat="server" ID="lblHello" /> <asp:Panel runat="server"> First name: <asp:TextBox runat="server" ID="txtFirstName" /> <asp:LinkButton ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click" /> </asp:Panel> |
1 2 3 4 | protected void lbHello_Click(object sender, EventArgs e) { lblHello.Text = String.Format("Hello, {0}", txtFirstName.Text); } |
When you will try to press ENTER button inside the text box, form will be submitted to the server, but LinkButton‘s Click event will not be fired. Let’s try to specify DefaultButton property of the panel:
1 2 3 4 | <asp:Panel runat="server" DefaultButton="lbHello"> First name: <asp:TextBox runat="server" ID="txtFirstName" /> <asp:LinkButton ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click" /> </asp:Panel> |
Great! It’s working perfectly in Internet Explorer, but what about Firefox? Oops, we found a problem. You could find solution at the end of the post, but first I want to show why this problem occurs. When you specify DefaultButton property, ASP.NET generates following code:
1 2 | <div onkeypress="javascript:return WebForm_FireDefaultButton(event, 'lbHello')"> </div> |
Here is WebForm_FireDefaultButton method, defined in ASP.NET JavaScript library:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function WebForm_FireDefaultButton(event, target) { if (event.keyCode == 13 && !(event.srcElement && (event.srcElement.tagName.toLowerCase() == "textarea"))) { var defaultButton; if (__nonMSDOMBrowser) { defaultButton = document.getElementById(target); } else { defaultButton = document.all[target]; } if (defaultButton && typeof(defaultButton.click) != "undefined") { defaultButton.click(); event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); return false; } } return true; } |
The problem occurs in the code typeof(defaultButton.click) != "undefined" — Firefox does not define click() method for the a element, so the form will be submitted without __EVENTTARGET parameter, and button will not be triggered. The simplest way to solve the problem is to define click() method for the a:
1 2 3 4 5 6 7 8 9 10 | var b = document.getElementById('<%= lbHello.ClientID %>'); if (b && typeof(b.click) == 'undefined') { b.click = function() { var result = true; if (b.onclick) result = b.onclick(); if (typeof(result) == 'undefined' || result) { eval(b.getAttribute('href')); } } } |
Our click() method imitates a element behavior: first it calls onclick() method (OnClientClick attribute of the LinkButton), and if it returns false — stops processing. Then it evals href attribute (where ASP.NET puts __doPostBack call).
Let’s create custom control which encapsulates this logic:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | using System; using System.Web.UI.WebControls; namespace App_Code { public class LinkButtonDefault : LinkButton { protected override void OnLoad(System.EventArgs e) { Page.ClientScript.RegisterStartupScript(GetType(), "addClickFunctionScript", _addClickFunctionScript, true); string script = String.Format(_addClickScript, ClientID); Page.ClientScript.RegisterStartupScript(GetType(), "click_" + ClientID, script, true); base.OnLoad(e); } private const string _addClickScript = "addClickFunction('{0}');"; private const string _addClickFunctionScript = @" function addClickFunction(id) {{ var b = document.getElementById(id); if (b && typeof(b.click) == 'undefined') b.click = function() {{ var result = true; if (b.onclick) result = b.onclick(); if (typeof(result) == 'undefined' || result) {{ eval(b.getAttribute('href')); }} }}}};"; } } |
And corresponding .aspx file:
1 2 3 4 5 6 | <%@ Register Namespace="App_Code" TagPrefix="ac" %> <asp:Label runat="server" ID="lblHello" /> <asp:Panel runat="server" DefaultButton="lbHello"> First name: <asp:TextBox runat="server" ID="txtFirstName" /> <ac:LinkButtonDefault ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click" /> </asp:Panel> |
Of course, JavaScript code should be moved out from the C# code, but for my example it’s good enough. If you are using ASP.NET AJAX library, you should use ScriptManager.RegisterStartupScript method instead of ClientScriptManager.RegisterStartupScript.
Hope, this post will help you. Your comments are welcome.
asp.net panel scroll bars not visible in opera.why?
hi
I am using Aspnet ajax in my application, i used asp button for submiting a form, beacuse asp:Button work in both condition when Javascript is enable or disabled.
but asp:button are not look good in mac broswer so client do want asp:Button/asp:ImageButton in whole application.
Please advise What would be the replcaement of asp:Button/asp:ImageButton which will work in both condition when Javascript is enable or disabled.
Thanks
Regards
Raghvendra
[email protected]
asp:LinkButton works only when JavaScript is enabled, you right. I see only one solution: add two buttons at the same time (for browsers that does not support JavaScript — asp:Button, visible by default, and asp:LinkButton for ones, that support JavaScript), and switch their visibility using JavaScript. Something like this:
2
3
4
5
6
<asp:LinkButton runat="server" ID="lbSubmit" style="display:none" Text="submit" />
<script type="text/javascript">
document.getElementById("<%= btnSubmit.ClientID %>").style.display = 'none';
document.getElementById("<%= lbSubmit.ClientID %>").style.display = '';
</script>
But of course this is not perfect solution. BTW, you could use images as background of the asp:Button or asp:ImageButton, and they would look perfectly in Safari.
That worked perfectly! Thank you for your post.
[…] is one solution that creates their own “click” event for the LinkButton. You can look at it here (this solution does work as well, i just found it too much). I wanted something simpler, Simple is […]
[…] But of course if you are using a LinkButton, then its a whole another ball game. None of the techniques described above might work for you. But you are in luck, this page has what you need to get around that — http://kpumuk.info/asp-net/using-panel… […]
One simple way to get around the Linkbutton issue and the firefox issue is to set up a “shadow” button on the page with a style="display:none;"
So, say I have a login form, I will put a link button on the form in case the user is going to click it directly. Then, just underneath it I will add a hidden asp:Button, with display:none, and tie that to the same event as the regular login linkbutton.
Works in both IE7 and FF2 as far as I can tell, and doesn’t require any javascript — just a stupid workaround.
Работает идеально, спасибо! Но… Очень бы хотелось, чтобы работало в опере по Ctrl + Enter (автозаполнение). Есть идеи?
Спасибо.
Dave’s solution is the way to go.
Hi guys i found solution finally.
Setting link button as Default button for FIREFOX as well as IE:
use this fallowing code–>
in .aspx file—————————
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
debugger;
var bt = document.getElementById(buttonid);
if (typeof(bt) == 'object') {
if (navigator.appName.indexOf("Netscape") > -1) {
if(e.keyCode == 13) {
if (bt && typeof(bt.click) == 'undefined') {
bt.click = addClickFunction1(bt);
}
}
}
if (navigator.appName.indexOf("Microsoft Internet Explorer") > -1) {
if (event.keyCode == 13) {
bt.click();
return false;
}
}
}
}
function addClickFunction1(bt) {
debugger;
var result = true;
if (bt.onclick) result = bt.onclick();
if (typeof(result) == 'undefined' || result) {
eval(bt.href);
}
}
————————-
in aspx.cs file (write code for the text boxes u required)
aspx.cs file(C#.net code)—>
in Page_Load Event
reg Above Code–>
Please read this for the reference of the above code , and read the ID’s for the textbox’s and Link Buttons
for the above code in aspx form ,we have
a
asp Text box with id “txtUserName”
and
a
link button with id “btnSearch”
like
This solution worked perfectly. Thank you very much.
Solution is ok. Unfortunatelly, this does not work under Firefox 3.
Anyone know how to do it?
Hi uttam,
i am implemented what you are given the code in my aspx page, but in FireFox again its not working, when i enter key in textbox the cursor goes to next button, could you please give me any idea.
Thanks
Ramana
Hi,
I have implemented this fix and it seems to be ok in most cases. However, if I have a form with asp.net validators then it only works once. e.g. Enter an invalid entry, press enter and the correct button is clicked. However, press enter again, and the wrong one is clicked!
Anyone have any ideas? Thanks in advance.
Simon.
It seems that firefox 3 automatically htmlencode hrefs. So our :
becomes :
which obviously doesn’t work as expected.
To have it work again, change the end of addClickFunctionScript to :
After some research, it seems that DOM specs stand that href attribute should be an URI and that to get the exact content of href, one should use :
Nice point, mdespesse! Thanks for sharing your experience.
Mdespesse’s point in 17 makes this solution work perfectly in FF3. Thanks.
Based on Dave’s solution (post #7).
2
3
4
5
6
7
New Status:
<asp:TextBox ID="txbNewStatus" runat="server"/>
<asp:LinkButton ID="lnkBtnNewStatusCancel" runat="server" Text="Cancel" />
<asp:LinkButton ID="lnkBtnNewStatusSubmit" runat="server" Text="Submit" />
<asp:Button ID="btnHiddenSubmit" runat="server" />
</asp:Panel>
and then, on the code behind:
2
3
4
5
6
7
btnHiddenSubmit.Attributes.Add("style", "display:none;")
End Sub
Protected Sub lnkBtnNewStatusSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lnkBtnNewStatusSubmit.Click, btnHiddenSubmit.Click
'Do What you need to do for those clicks
End Sub
This is what i did in ASP.NET code behind and it works pretty well in both IE and FF:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
JavaScriptLoad()
Private Sub JavaScriptLoad()
Dim addClickFunctionScript As StringBuilder = New StringBuilder()
addClickFunctionScript.Append(" function addClickFunction(id) {{ ")
addClickFunctionScript.Append(" var b = document.getElementById(id); ")
addClickFunctionScript.Append(" if (b && typeof(b.click) == 'undefined') b.click = function() {{ ")
addClickFunctionScript.Append(" var result = true; if (b.onclick) result = b.onclick(); ")
addClickFunctionScript.Append(" if (typeof(result) == 'undefined' || result) {{ eval(b.getAttribute('href')); }} ")
addClickFunctionScript.Append(" }}}}; ")
Dim addClickScript As String = "addClickFunction('{0}');"
Dim ClickScript As String = String.Format(addClickScript, lnkLogin.ClientID)
Page.ClientScript.RegisterStartupScript(Me.GetType(), "addClickFunctionScript", addClickFunctionScript.ToString(), True)
Page.ClientScript.RegisterStartupScript(Me.GetType(), "click_" + lnkLogin.ClientID, ClickScript, True)
End Sub
corresponding .aspx file
2
3
4
First name: <asp:TextBox runat="server" ID="txtFirstName" />
<asc:LinkButton ID="lbHello" runat="server" Text="Click me" />
</asp:Panel>
The simplest, cross-browser approach I’ve seen is at this guy’s site:
http://weblogs.asp.net/jeff/archive/2005/07/26/420618.aspx
Just one line and you’re all set…
MyPasswordTextBox.Attributes.Add(“onKeyPress”, “javascript:if (event.keyCode == 13) __doPostBack(‘” + MySubmitButton.UniqueID + “‘,”)”)
I have a question: I try to find out the value of the disabled property of linkbutton in javascript. It’s not a problem in IE but it’s undefined in Firefox. My problem is that although the link is disabled clicking it triggers onClientClick event which shows a message. I want to check if the link is disabled before showing the message however the disabled property is undefined in FireFox. Thank you in a advance for your help.