« November 2007 | Main | January 2008 »

December 2007

December 17, 2007

.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.)

December 12, 2007

Memories of QCon San Francisco

Last month I had the opportunity to be a track host at QCon San Francisco, and it was a very rewarding experience. There was a lot of stage-managing which had to happen behind the scenes, including ensuring presentations were collected, equipment set up, and ensuring that the speakers had everything they required etc... Needless to say, it was busy yet it was a great opportunity to get a view of a conference from the other side of the podium. We lined up several high-quality talks, including:

In addition, the last slot of the day was a discussion about what the future of Java development would look like, and we were able to assemble a diverse and rich set of opinions from Joshua Bloch, Chet Haase, Rod Johnson, Erik Meijer and Charles Nutter. The discussion was at times animated, and the room was packed beyond capacity (standing room only) - a good end to a good day.

When I wasn't running back and forth on Wednesday, I took the opportunity to talk to some of the people who were at the conference. I was surprised to find that almost everyone was a manager of this, a senior engineer of that, or an architect. I was also astonished at the speaker/attendee ratio, and for several of the presentations that I attended (e.g. Charles Nutter's JRuby presentation) there were other Ruby Committers present such as Ola Bini and Obie Fernandez present. It gave the questions and conversations a richness that just isn't present at a normal conference.

On Thursday, my time as an attendee was cut short when Floyd asked me to take over the Java Emerging Technologies track.  After another set of very good speakers including Charles Nutter, Jason Rudolph, Neal Ford, Adrian Colyer and Wayne Lund, I went to the QCon Speakers' Dinner. The talk of the night ranged from Agile food queues through Software Transactional Memory plus OpenLaszlo to JSR 277 (a contentious discussion) and Ruby hacking. It was a great chance to share some drinks with people I'd previously only read about.

The keynotes were also quite good. I wasn't able to catch all of Kent Beck's keynote because I was busy preparing for my track, but everything I heard was well-presented and made a lot of sense. Richard Gabriel also had a very interesting and well-crafted stroll through the history of programming languages - who knew that there were programming languages that used color and pictures to represent the code? I was also captivated by James Noble's Lego Hypothesis. It reminded me a lot of some things I've been thinking about, and we will be collaborating on a blog entry here in the very near future, so stay tuned! I also participated in several interviews, including Charles Nutter on JRuby, Rod Johnson on the Spring ecosystem, Cedric Beust on TestNG, and MLB.com on Silverlight. They will all be appearing on InfoQ in the future, with the JRuby interview likely coming out this month.

Finally, if you are interested in a detailed summary of the conference, I wrote up a comprehensive summary on InfoQ.com. I hope you enjoy it... Thanks for reading.

December 04, 2007

Are you in the Loop?

Get in the loop at JamLoop.com, a music oriented search engine. Looking for a particular instrument and not sure where to go or what’s out there? Looking for that particular vintage guitar, or piece for your collection? Let JamLoop bring the power of the web to you. Just type in the keywords, and let JamLoop’s search engine do the work. JamLoop indexes content from multiple classifieds sites, used equipment stores and new equipment retailers for its users to bring results to a single destination using a customized spidering technology. JamLoop shows you relevant location-based results using a mashup of IP2Location's innovative geolocation solution in conjunction with the Google Maps API.

 

To help make JamLoop’s ideas a reality we used a variety of leading-edge technologies including Amazon EC2, JBoss and Lucene. For the end user, JamLoop’s site incorporates sliders and other custom controls to enhance and enrich their user experience.

 

JamLoop’s founder came to us with an idea. He wanted a better way to find musical instruments on the web, and needed help designing the solution. Our customized Agile Project Methodology  is ideally suited for such an engagement. Through regular scrum meetings and our change-friendly approach, we delivered what you see today. We have captured new ideas along the way and continue to work on these User Stories to help JamLoop deliver a rich, personalized experience for its end user.

 

We have formed a strong partnership with JamLoop, and it has been very exciting for our team to be working with our client to help make their ideas reality. Special thanks to the team of Matt Butler, Oliver Chan, and Joe Nowak who delivered this product. Now for those reading this post, it’s time for you to get in the loop at JamLoop.com.

-->

December 17, 2007

.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...read more

Categories: Web/Tech

December 12, 2007

Memories of QCon San Francisco

Last month I had the opportunity to be a track host at QCon San Francisco, and it was a very rewarding experience. There was a lot of stage-managing which had to happen behind the scenes, including ensuring presentations were collected, equipment set up, and ensuring that the speakers had everything they required etc... Needless to say, it was busy yet it was a great opportunity to get a view of a conference from the other side of the podium. We lined up several high-quality talks, including: Rod Johnson - Configuring the Spring Container Cedric Beust and Alexandru Popescu - Designing for Testability Brian Goetz - Concurrency, Past and Present Adrian Colyer - AOP in the Enterprise In addition, the last...read more

Categories: Conferences and Events

December 4, 2007

Are you in the Loop?

Get in the loop at JamLoop.com, a music oriented search engine. Looking for a particular instrument and not sure where to go or what’s out there? Looking for that particular vintage guitar, or piece for your collection? Let JamLoop bring the power of the web to you. Just type in the keywords, and let JamLoop’s search engine do the work. JamLoop indexes content from multiple classifieds sites, used equipment stores and new equipment retailers for its users to bring results to a single destination using a customized spidering technology. JamLoop shows you relevant location-based results using a mashup of IP2Location's innovative geolocation solution in conjunction with the Google Maps API. To help make JamLoop’s ideas a reality we used a...read more

Categories: Web/Tech

Privacy Policy| Sitemap| Contact Us

Copyright 2002-2007 Codesta LLC. All rights reserved.