Monday
Dec172007

« .NET Gotchas: Part I – Multi-line Text boxes and the DefaultButton in ASP.NET 2.0 »

Have you ever received an error message that resisted even the mighty Google? An application failure that it seems only happens to you and 10 other people in the world (all of whom, as luck would have it, speak different languages)?

Have you ever felt you were going mad, staring at the same piece of code over and over again, knowing it should work - willing it to work because it should, but it does not?

Good news! You are not going mad (at least not in this!). Sometimes, the fault lies not with your code, but with your tools. I suppose this is a glancing compliment to Microsoft, because frankly it had never occurred to me that the fault could lie with their products (as I type that it feels peculiar to say, but there it is). As our lives as developers are made easier in many ways due to new and better tools, this is due to a shifting, not removal, of complexity. That complexity has moved to our tools and effects are bound to pop up.

If you were a carpenter, you would be well within your rights to show surprise at your hammer behaving like a saw. Likewise, as a developer, you are, I believe, within your rights to be surprised when your tools do not respond in the expected manner.

My intent is to produce a series of articles providing succor to fellow developers faced with those .NET issues that crop up for which information is difficult to find.
By their very nature, these issues should all be short-lived affairs, with corrections (hopefully) on the way in newer releases of the .NET framework or the Visual Studio IDE. However, in the meantime, I hope these articles will help prevent frustration for somebody else.

Many of the issues we explore here are not being explored due to their ground-breaking solutions or because the problems are of such an interesting, cutting-edge nature that the world will want to tune in to watch it all as it happens. On the contrary, they will most likely be mundane, uninteresting solutions to mundane, uninteresting problems. In fact, you will likely not believe that there could ever be such problems, but they can and do crop up.

Let's get to it.

 .NET Gotchas - Part I – Multi-line Text boxes and the DefaultButton in ASP.NET 2.0

Different browsers each have their own default behaviour detailing what actions to take when a user hits enter in a form. This is well and good, but there seems to be some natural, unspoken standard that says one should be able to submit a form by simply pressing enter. Through the use of JavaScript, web developers have been able to happily and easily handle this requirement for years. In designing the ASP.NET portion of the .NET Framework 2.0, Microsoft, not being oblivious to this unspoken standard, provided methods of handling and implementing this desired behaviour.

The HtmlForm class contains a property called DefaultButton which gets or sets the child control of the HtmlForm that causes postback when the ENTER key is pressed. When the DefaultButton property is not explicitly set, the browser resorts to whatever its default behaviour is. As you would expect, this feature has been implemented with JavaScript emitted when the page is generated. ASP.NET includes a special handler named WebResource.axd designed to retrieve and serve assembly resources and all of the JavaScript code that makes up the magic of ASP.NET is embedded in such resources and served to the client browser through WebResource.axd.**

Sounds effortless, does it not? A quick mental ‘Thank you Microsoft’ and our work should be completed, right?

Unfortunately, it is not (never) quite so simple. Although I was quite happy with the DefaultButton solution and it was chugging happily along for me on many forms, things all fell apart when I threw a multi-line text box into the mix.

Let's create a web form to illustrate the problem:

<form id="form1" runat="server">
	<asp:Panel runat="server" DefaultButton="btnSubmit">
		Textbox 1:
		<asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine"/>
		<asp:Button ID="btnSubmit" runat="server" OnClick="SubmitClick" Text="Submit"/>
		<asp:Label ID="Label1" runat="server" Width="500px"/>
	</asp:Panel>
</form>

Your code-behind should resemble the following:

public partial class testbuttons : System.Web.UI.Page
{
	protected void Page_Load(object sender, EventArgs e)
	{
		this.Label1.Text = "";
	}
	
	protected void SubmitClick(object sender, EventArgs e)
	{
		this.Label1.Text = "Submit button clicked";
	}
}

If you have developed a website for use in multiple browsers, you may have bumped your head against an interesting issue with this feature. In Internet Explorer, load up your page with a form that has the DefaultButton duly set, type in some lines of text into the text box. Go ahead and type in many lines - feel the heady rush that overcomes you as the textbox bends to your will, quietly inserting newline characters into the textbox with each and every stroke of the ENTER key! Now, load up that self-same page in Firefox, start typing in some text and hit ENTER.

What happened? Our joy has been interrupted!

What happened is that our handy-dandy multi-line text box no longer acts like a multi-line text box. Rather than causing a new line, hitting ENTER activates the default button.

The reason for this behaviour is the FireDefaultButton JavaScript code that is responsible for supplying the behaviour. Unfortunately, it seems that some IE-specific code managed to make make its way into that method, the end result being that Firefox (and other browsers using a different object model than IE) will not run the code as expected.

Here is the code for FireDefaultButton with the offending parts emphasized:

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 property event.srcElement is not understood by Firefox which causes our problem. That's all. As I said, dead simple, but that simplicity is cold comfort when you are shaking your fist at a monitor for 3 hours cursing the heavens because you can see no reason why your code isn't working as it should.

The fix? Equally as simple. In my case, I added a new variable,

var element = event.target || event.srcElement;
and replaced
event.srcElement
with
element
resulting in:

function WebForm_FireDefaultButton(event, target)
{
	//event.srcElement doesn't work in FF so we check whether
	//it or event.target exists, using whichever is returned
	var element = event.target || event.srcElement;

	if (event.keyCode == 13 &&
		!(element &&
		element.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;
}

So that is the fix and to put it all together, we just add a call to ClientScript.RegisterClientScriptInclude giving it the name and path to our newly fixed script:

protected void Page_Load(object sender, EventArgs e)
{
	/*register fixed FireDefaultButton script*/
	ClientScript.RegisterClientScriptInclude("FixFireDefault",
			"<<PATH TO SCRIPT>>/FireDefaultButtonFix.js");
}

And that is it. When your page loads, your new script will be registered, taking the place of the original.

(For a more detailed explanation of Web Resources, check out this Microsoft article.)

Reader Comments (8)

Thank you for that great explanation and work around. I just added it to a site I'm working on and it works great.
May 1, 2008 | Unregistered CommenterJohn McGuinness
Thanks. I registered the script in my parent BasePage.cs class, and it worked. Note that if one wishes to use the ~ relative path construct, then be sure to use Page.ResolveUrl:

ClientScript.RegisterClientScriptInclude("FixFireDefault", Page.ResolveUrl("~/scripts/FireDefaultButtonFix.js"));

See: http://forums.asp.net/p/987646/1276008.aspx#1276008

--Brett
May 7, 2008 | Unregistered CommenterBrett
The code worked great for me ..thanks very much...you saved a lot of time of mine..wish you all the best.
March 3, 2009 | Unregistered CommenterSeema Ahlawat
Thanks, this was very helpful, I'd have wasted a ton of time figuring this out! Thanks!
October 6, 2009 | Unregistered CommenterMeeko
Thank you it is very usefull to me
June 29, 2010 | Unregistered Commenterduckyvideos

I’m still waiting for some interesting thoughts from your side in your next post thanks
Christian Louboutin Sandals
Christian Louboutin Sandals
[url=http://www.christianlouboutinshoesale.org/ ]Christian Louboutin Sandals[/url]
[url="http://www.christianlouboutinshoesale.org/ " title="Christian Louboutin Sandals"]Christian Louboutin Sandals[/url]

No matter what type of uggs on sale

you are looking for, there is no doubt one available for you. They have come a long way from

their days of being in World War I aircrafts. And, thanks to their manufacturer, ugg boots outlet Australia, you can

feel good while wearing these shoes while still being in style! You will simply love the

options in color, styles, and designs that you have. The whole family will be wearing ugg outlet because they just are so

darn cute and comfortable!The ugg boots

sale is one of the a lot of accepted types of cossack on the bazaar appropriate now.

Anyone who is not accustomed with them should accede bottomward one on! They are appreciably

bendable and luxurious. They action an accomplished akin of abundance and a admirable

appearance as well. They are actual balmy and cozy. Your anxiety will be in shoe heaven! Let's

yield a afterpiece attending at what is accessible in the ugg boots clearance and uggs for cheap see if we can't

acquisition something that you will enjoy!

November 26, 2011 | Unregistered Commenterugg boots sale

At the same time, the investigation<h1>Coach Outlet</h1> that led the United States to <h1>Coach Outlet</h1>the bank, the Lebanese Canadian<h1>Chanel Handbags</h1> Bank, provides new insights <h1>Coach Outlet</h1>into the murky sources of<h1>Coach Outlet</h1> Hezbollah’s money. While law enforcement <h1>Chanel Bags</h1>agencies around the world <h1>Coach Factory Outlet</h1>have long believed that <h1>Coach Outlet Online</h1>Hezbollah is a passive beneficiary <h1>Coach Outlet</h1>of contributions from loyalists <h1>Coach Outlet</h1>abroad involved in drug trafficking <h1>Coach Outlet Online</h1>and a grab bag of other<h1>Louis Vuitton Bags</h1> criminal enterprises, intelligence <h1>Coach Factory Outlet</h1>from several countries points <h1>Louis Vuitton Bags</h1>to the direct involvement of <h1>Coach Factory Store</h1>high-level Hezbollah officials <h1>Coach Outlet</h1>in the South American cocaine<h1>Coach Factory Outlet</h1> trade.One agent involved in the<h1>Coach Outlet Store</h1> investigation compared Hezbollah <h1>Coach Factory Outlet</h1>to the Mafia, saying, “They <h1>Coach Outlet</h1>operate like the Gambinos on <h1>Chanel Bags</h1>steroids.”On Tuesday, federal <h1>Chanel Bags</h1>prosecutors in Virginia announced <h1>Louis Vuitton</h1>the indictment of the man <h1>Coach Factory Store</h1>at the center of the Lebanese<h1>Chanel Handbags</h1> Canadian Bank case, charging <h1>Coach Outlet</h1>that he had trafficked drugs <h1>Chanel Bags</h1>and laundered money not only <h1>Louis Vuitton</h1>for Colombian cartels, but also for<h1>Coach Factory Online</h1> the murderous Mexican gang <h1>Coach Outlet</h1>Los Zetas.The revelations about <h1>Chanel Bags</h1>Hezbollah and the Lebanese Canadian<h1>Coach Outlet</h1> Bank reflect the changing <h1>Louis Vuitton Bags</h1>political and military dynamics<h1>Coach Factory Outlet</h1> of Lebanon and the Middle East. <h1>Chanel Bags</h1>American intelligence analysts believe<h1>Coach Factory</h1> that for years Hezbollah

December 14, 2011 | Unregistered CommenterCoach Factory Outlet

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>