<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Rob's Blog</title>
        <link>http://robrich.org/Default.aspx</link>
        <description>Rob's Blog</description>
        <language>en-US</language>
        <copyright>Rob Richardson</copyright>
        <managingEditor>robrich@robrich.org</managingEditor>
        <generator>Subtext Version 2.0.0.43</generator>
        <image>
            <title>Rob's Blog</title>
            <url>http://robrich.org/images/RSS2Image.gif</url>
            <link>http://robrich.org/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>"Oh duh": Google Maps and iPhone</title>
            <category>Rants</category>
            <link>http://robrich.org/archive/2008/11/08/oh-duh-google-maps-and-iphone.aspx</link>
            <description>Google Maps is awesome.  It is phenomenally cool.  It is the quintessential definition to many of what is Web 2.0: a very dynamic, very interactive, very usable site that presents what I want in a way I want it right now, lets me use it intuitively, and publish it to anywhere else easily.  Some may argue Google Maps is the reason cell phones now have GPS's in them: for turn-by-turn directions based on map data downloaded to the phone on demand.&lt;br /&gt;
&lt;br /&gt;
Google Maps is also the quintessential example of a mashup: take two unrelated services, push them together, and you've got something incredibly new and cool.  Take presidential election results and geolocate voter preferences.  Take restaurant reviews and show me how close I am to them.  Take driving directions to the next level by overlaying speed trap markers.  It is awesome.  And the Google Maps API makes it drop-dead simple to do this in JavaScript, static images (with really long urls), or Flash.  I'm a happy camper.&lt;br /&gt;
&lt;br /&gt;
In the other corner is the iPhone.  It is an awesome piece of engineering and elegance.  It is the new standard for what a phone should do.  It's touch screen interface is the standard by which all PDAs are judged going forward.  It's simple user navigation is awesome.  It's "always within reach" browser is awsesome.  (Sometimes when I'm upstairs and want to quickly look something up, I won't bother going all the way downstairs to the computer.  I'll pop out the iPhone and get on the net.)  Stop by the App Store or Cydia and download just about any kind of app from "keep my kids busy while I just quickly finish up ..." to "are there any wireless networks open here?" to "lemmie quickly RDP / VNC into that machine over there and ..."  And all that "in your pocket", instantly available anywhere, at the push of a button is awesome.&lt;br /&gt;
&lt;br /&gt;
The iPhone takes Google Maps to the next level too: you can search for a restaurant name or genre, pan around the map, and see things close to you.  You can pick a contact from your address book, and get directions from "where I am right now" (thanks GPS) to their street address.  As you're driving, you can watch the little blue blinking ball dance accross the map in unison to your driving.  It's incredibly marvelous engineering feats behind the scenes, and incredibly simple to use.  Cudos to both Google and Apple.  Awesome.&lt;br /&gt;
&lt;br /&gt;
Here's the rub: iPhone Google Maps mashups.  They don't exist.  They can't.  Google Maps app for the iPhone is crafted by Apple.  It is not JavaScript, not Flash, not static images with cryptic urls.  It's an app.  Ok, granted, there is an iPhone app to show me speed traps.  An iPhone app to geolocate stuff "around me" -- restuarants, theatres, etc.  I can download 1000 iPhone apps to map various things.  They're cool.  They're also seperate applications.  If I want to both see route information and see the speed traps on 1 map, I'm screwed ... unless the app developer implimented everything and it's dog.&lt;br /&gt;
&lt;br /&gt;
The speed trap app is a great example.  I think they call it trapster.  I can see my current location, I can see speed traps identified by others using this service.  I can mark ones I find when I'm sitting by the side of the road with blinky lights in my rear view mirror.  It's like driving in a video game.  It's awesome.  But the developer didn't impliment screen jestures for navigating the map.  I can't pinch to zoom out or in, I can't swipe the screen sideways to move.  I have to use the little joystick controls on the bottom control bar.  And I definately can't put in my destination address and see the route of how to get there.  Or where the closest ATM is that supports my bank's card.  Or if any of my address book contacts live nearby.&lt;br /&gt;
&lt;br /&gt;
Around Me is another awesome app that shows me restaurants, theatres, etc, around me.  (Not that I have time to use any of them, but that's another mater.)  But what if I want directions to there?  Sorry, that's in the other maps app.&lt;br /&gt;
&lt;br /&gt;
"Ok," so I say to myself.  "I'm a 1/2 descent web user.  I'll just use the real Google Maps website for my mashups."  That's all fine and good except ... now I'm in app #3: Safari.  That has no Flash plugin, by the way.  And (in theory) any url that contains map information is automatically grabbed by the phone and routed to the Google Maps app.  And it doesn't have my GPS info, so I have to keep track of my current location by manually panning around as I drive.&lt;br /&gt;
&lt;br /&gt;
I came to the awful conclusion at the end of this mental journey that the iPhone's Google Maps app is incredibly cool.  But it fundamentally defeats the purpose: today's internet is about mashups.  Combining data in interesting ways.  And I can't do that with any map data, a target destination, and my current location from my iPhone with Google Maps.  "Oops."&lt;img src="http://robrich.org/aggbug/51.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/11/08/oh-duh-google-maps-and-iphone.aspx</guid>
            <pubDate>Sat, 08 Nov 2008 17:25:20 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/51.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/11/08/oh-duh-google-maps-and-iphone.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/51.aspx</wfw:commentRss>
        </item>
        <item>
            <title>jQuery - LINQ to JavaScript</title>
            <category>Code</category>
            <category>Events</category>
            <link>http://robrich.org/archive/2008/05/31/jquery---linq-to-javascript.aspx</link>
            <description>I had the privilege of presenting jQuery at Desert Code Camp today.  jQuery is the do more, write less JavaScript library.  Because it runs client-side, it can be used easily with any server framework.  There's nice support for intellisense in Visual Studio 2008 as well (with a bug-fix update).&lt;br /&gt;
&lt;br /&gt;
jQuery basically breaks down into two operations: picking things, and doing something with those things.  Picking things is done via a CSS / XPath strign describing the DOM nodes you want to do.  This returns an array of DOM elements (wrapped nicely in a jQuery object) that get passed into each of jQuery's 'do it' functions.  It becomes trivial to change css on all items, change the innerHTML, append DOM elements, even do AJAX and visual effects.  What's best: this whole process usually takes about 20 characters -- very small, very clean, very nice.&lt;br /&gt;
&lt;br /&gt;
The slides from the content can be found &lt;a href="http://robrich.org/content/jQuery-Desert-Code-Camp.zip"&gt;here&lt;/a&gt;.  We generated all the code we saw on the fly inside FireBug.  Enjoy!&lt;br /&gt;
&lt;br /&gt;
Rob&lt;img src="http://robrich.org/aggbug/50.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/05/31/jquery---linq-to-javascript.aspx</guid>
            <pubDate>Sat, 31 May 2008 20:22:26 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/50.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/05/31/jquery---linq-to-javascript.aspx#feedback</comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/50.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Conditional Compile based on .net framework version</title>
            <category>Code</category>
            <category>Tools</category>
            <link>http://robrich.org/archive/2008/05/15/conditional-compile-based-on-.net-framework-version.aspx</link>
            <description>Ok, I've been after this one for quite a while.  I want to include stuff like Moth.Linq and ExtensionAttribute in .net 2.0 compilations, but exclude them from .net 3.5 compilations.  In effect, I want to cross compile to .net 2.0 and .net 3.5.  Not only do I want to do this from within Visual Studio, I also want the Continuous Integration server to do it too.  Tall order?  Yes.&lt;br /&gt;
&lt;br /&gt;
A bit of background:&lt;br /&gt;
&lt;br /&gt;
- &lt;a href="http://www.danielmoth.com/Blog/Moth.Linq.cs"&gt;Moth.Linq&lt;/a&gt; is a mechanism for producing LINQ functionality in assemblies compiled in Visual Studio 2008 targeted to the .net 2.0 framework.  You add this piece of code, add a 'using Moth.Linq;' at the top, and you can use LINQ.  Very cool.  (Disclaimer: this isn't LINQ to SQL or LINQ to Entities, just LINQ -- e.g. lamda expressions in SQL style syntax.)&lt;br /&gt;
&lt;br /&gt;
- Daniel Moth has another awesome trick for using &lt;a href="http://www.danielmoth.com/Blog/2007/05/using-extension-methods-in-fx-20.html"&gt;Extension Methods&lt;/a&gt; in .net 2.0 deployed assemblies.  Since Extension Methods are a compiler trick, not a function of the language, at compile time, the method itself is put back into a static class, and the calls to that method are magically transformed into calls to that static class's method passing in the parameter that the extension method was attached to.  None of this needs the magic System.Core.dll file that adds all the magic C# 3.0 sauce.  Well, to make this compiler trick work requires the ExtensionAttribute inside the System.Runtime.CompilerServices namespace -- Inside System.Core.dll.  What does it do?  I have no idea.  But create this attribute, and extension methods just work.  Very cool.&lt;br /&gt;
&lt;br /&gt;
- I use &lt;a href="http://nant.sourceforge.net"&gt;NAnt&lt;/a&gt; triggered by Cruise Control .NET.  &lt;a href="http://nantcontrib.sourceforge.net"&gt;NAntContrib&lt;/a&gt; has a fabulous task called msbuild that you can pass a solution file to, and it'll build everything in the solution.  &lt;a href="http://codebetter.com/blogs/jeffrey.palermo/archive/2007/11/28/upgrade-nant-for-use-with-vs2008-solutions-and-net-3-5.aspx"&gt;Jeffrey Palermo&lt;/a&gt; has a great trick for enabling NAnt to build .net 3.5 projects.  Combine these, and the standard NAnt build file that's been working forever now works with Visual Studio 2008 projects as well.  Very cool.&lt;br /&gt;
&lt;br /&gt;
- Some developers on the team have VS 2005, some have VS 2008.  Some deployment servers run .net 2.0, some .net 3.5.  So, the code just has to work in both scenarios.  Those of us in VS 2005 hate it when those of us in VS 2008 use the cool C# 3.0 features.  Those of us in VS 2008 hate holding back.&lt;br /&gt;
&lt;br /&gt;
So, the task at hand is clear: create a way that NAnt and Visual Studio can conditionally include things like Moth.Linq and Extension Methods.  The clear solution: pre-processor flags.  I wrap the Extension Method code like so:&lt;br /&gt;
&lt;pre&gt;#if NET_20&lt;br /&gt;namespace System.Runtime.CompilerServices {&lt;br /&gt;  public class ExtensionAttribute : Attribute { }&lt;br /&gt;}&lt;br /&gt;#endif&lt;/pre&gt;
Now if the preprocessor flag is defined, it is compiled in.  If not, it's not.&lt;br /&gt;
&lt;br /&gt;
Well, that's all fine and good, but how to get the target .net framework to trigger defining the preprocessor flag?  Sadly, I haven't found a good solution to that, but I did find this:&lt;br /&gt;
&lt;br /&gt;
The idea is from &lt;a href="http://blogs.msdn.com/karstenj/archive/2005/06/28/passing-a-preprocessor-directive-to-msbuild-via-the-command-line-instead-of-define-in-code.aspx"&gt;Karsten&lt;/a&gt;: define preprocessor flags on the msbuild command line like so:&lt;br /&gt;
&lt;pre&gt;&lt;font face="Courier New"&gt;msbuild /p:DefineConstants=NET_20 /t:Rebuild&lt;/font&gt;&lt;/pre&gt;
Ok, I'm 1/2 way there.  NAnt's syntax for defining the command line args is like so:&lt;br /&gt;
&lt;pre&gt;&amp;lt;arg value="/p:DefineConstants=NET_20" /&amp;gt;&lt;/pre&gt;
I put that inside the &amp;lt;msbuild&amp;gt; task, insure I've defined the framework version NAnt is targeting like so:&lt;br /&gt;
&lt;pre&gt;&amp;lt;property name="nant.settings.currentframework" value="net-2.0" /&amp;gt;&lt;/pre&gt;
and away we go.  This task now defines a perfect .net 2.0 build.&lt;br /&gt;
&lt;br /&gt;
Want a .net 3.5 build?  Set the property nant.settings.currentframework to "net-3.5" and don't set the arg in the msbuild task.  I chose to put both "NET_20" and "net-2.0" into properties that I could set to "" and "net-3.5" based on a task passed into NAnt, and we're good.  We now have Continuous Integration building .net 2.0 compatible code.  Excelent.&lt;br /&gt;
&lt;br /&gt;
How do we get the VS 2005 guys to do the same?  Well, that seems a task for another day.  My vote was to give them all VS 2008.  We'll see how that goes over.  :D  My backup plan is defining project configurations for "Debug 2.0" and "Release 2.0" that define these.  That's likely incredibly fragile though -- add a project and you tank that convention.  Next in line is make them run NAnt to build, but getting out of Visual Studio to build seems very unintuitive.  Make it a menu option in the external tools menu?  That seems ripe for confusion for the new employees stepping onto the scene.&lt;br /&gt;
&lt;br /&gt;
Well, in any event, 1/2 the problem is now solved.  Wicked cool.&lt;br /&gt;
&lt;br /&gt;
Rob&lt;img src="http://robrich.org/aggbug/49.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/05/15/conditional-compile-based-on-.net-framework-version.aspx</guid>
            <pubDate>Fri, 16 May 2008 03:55:58 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/49.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/05/15/conditional-compile-based-on-.net-framework-version.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/49.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Thinking in JavaScript - A-ha!</title>
            <category>Code</category>
            <category>Events</category>
            <link>http://robrich.org/archive/2008/05/15/thinking-in-javascript---a-ha.aspx</link>
            <description>I had the great honor of presenting 'Thinking in JavaScript' at the Java Users' Group last night.  I love leading a discussion of learning, and this was a great example of it.  I was even asked during conversation afterwards if I was a member of 'the club' [the Java Users' Group -- JUG].  Well, do I have to know Java to be part of the JUG?  I guess not.  What a fun and welcoming crowd.&lt;br /&gt;
&lt;br /&gt;
Our premise was thus: you know object-oriented development.  You know C-style syntax from either C, C++, Java, C#, or any of the derivatives.  You're approaching JavaScript, and need to get into the mindset of how JavaScript works.&lt;br /&gt;
&lt;br /&gt;
The majority of JavaScript is very much identical to all C-style languages: curly braces, semi-colons, objects, inheritance, debuggers, etc.  But JavaScript is also different in a few ways we need to wrap our heads around.  During the discussion, we identified 5 points that make JavaScript unique:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;A JavaScript object is like a dictionary
    &lt;ul&gt;
        &lt;li&gt;Roughly like Dictionary&amp;lt;string, object&amp;gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;A JavaScript method is an object
    &lt;ul&gt;
        &lt;li&gt;You can assign and retrieve them&lt;/li&gt;
    &lt;/ul&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;All function parameters are optional
    &lt;ul&gt;
        &lt;li&gt;No function overloading, but no need&lt;/li&gt;
    &lt;/ul&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Constructors declare instance level variables
    &lt;ul&gt;
        &lt;li&gt;They aren't private&lt;/li&gt;
    &lt;/ul&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;All JavaScript objects reference a prototype
    &lt;ul&gt;
        &lt;li&gt;The prototype defines common implementation&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Each one of these points requires more explanation than just that -- thus the 2 hours we spent discussing it.  But once you've wrapped your head around these few ideas, you can effectively code in JavaScript, because you'll know how JavaScript thinks.  You'll be Thinking in JavaScript.&lt;br /&gt;
&lt;br /&gt;
The slides for this evening's discussion can be found &lt;a href="http://robrich.org/content/Thinking_in_Javascript_at_JUG.zip"&gt;here&lt;/a&gt;.  The source code for the evening was mostly pulled either from the slides themselves and copied into &lt;a href="http://www.getfirebug.com"&gt;FireBug&lt;/a&gt;, or we made it up on the spot.  We also discussed &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt; and referenced tutorials available from &lt;a href="http://15daysofjquery.com"&gt;15 days of jQuery&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I asked briefly in the midst of the demo if anyone would like to see more jQuery stuff.  Just about every hand went up, so I've signed up to present a jQuery session at &lt;a href="http://www.desertcodecamp.com"&gt;Desert Code Camp&lt;/a&gt; in 2 weeks.  That promises to be a ton of fun too.&lt;br /&gt;
&lt;br /&gt;
If you have any questions, thoughts, suggestions, gripes, or kudos about 'Thinking in JavaScript' or you'd like some assistance in JavaScript development efforts, don't hesitate to drop me a line.  The more we know about how to code effectively, the less spaghetti code there will be for us to clean up later...  :)&lt;br /&gt;
&lt;br /&gt;
Rob&lt;img src="http://robrich.org/aggbug/48.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/05/15/thinking-in-javascript---a-ha.aspx</guid>
            <pubDate>Thu, 15 May 2008 16:40:56 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/48.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/05/15/thinking-in-javascript---a-ha.aspx#feedback</comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/48.aspx</wfw:commentRss>
        </item>
        <item>
            <title>CSS A complete Journey at Java Users Group</title>
            <category>Code</category>
            <category>Events</category>
            <link>http://robrich.org/archive/2008/04/10/css-a-complete-journey-at-java-users-group.aspx</link>
            <description>I was asked on short-notice to fill in for the Java Users Group, and to present CSS.  I have so much fun speaking, teaching, and learning with fellow developers that it was a no-brainer to say yes.  However, what was so unique to me is I'm not a Java developer.  I'm a C# / ASP.NET developer.  It really emphasized to me one of the really cool truths of internet development: there are 1000 server-side technologies and web servers you can use to host your content, but at the end of the day, there are just 3 types of content that get rendered through the web to the client's browser: HTML, JavaScript, and CSS.  (Granted, browser plugins allow for other things, but not natively.)&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="All your base are belong to Gates" src="/content/allyourbase-gates.jpg" style="float: left; margin-right: 10px; margin-bottom: 10px; width: 195px; height: 133px;" /&gt; So, after the full disclosure disclaimer, we from opposite sides of the technical globe were able to discuss Web 2.0 very effectively.&lt;br /&gt;
&lt;br /&gt;
I've presented "CSS - A complete journey" before, and it just keeps getting better and better.  CSS has some quirks, but it's by no means hard.  Once you understand how to reference CSS from the page, how to attach styles to elements, and a bit about order of precedence, everything else is just futzing with browser incompatibilities.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://robrich.org/content/CSS-at-JavaUsersGroup.zip"&gt;Here&lt;/a&gt; are the slides and sample code we used during our discussion on CSS.  Included is the page from CSS Zen Garden that we adjusted using the Firefox Web Developer Toolbar plugin.  Included as well is the Box Model discussion from Brain Jar's site.  I wish I had created each of these brilliant works, but alas, credit is due to their authors.  Included as well is the positioning mini-site I built to show the effect of float, position, and overflow.  And as with HTML and JavaScript, this is a client technology.  You can view source on any page you can see, look through their CSS, and discover how their solutions work.  Thus every page on the internet can be a learning tool.&lt;br /&gt;
&lt;br /&gt;
I look forward to next month's Java Users Group, where they've invited me back to discuss "Thinking in JavaScript".  We'll look at how we can leverage our knowledge of C-style syntax, OO principals, and html DOM to become instantly productive in JavaScript.  I can't wait.&lt;img src="http://robrich.org/aggbug/47.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/04/10/css-a-complete-journey-at-java-users-group.aspx</guid>
            <pubDate>Thu, 10 Apr 2008 16:49:29 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/47.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/04/10/css-a-complete-journey-at-java-users-group.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/47.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Validator Callout doesn't display on second control after fixing first control</title>
            <category>Code</category>
            <link>http://robrich.org/archive/2008/03/27/validator-callout-doesnt-display-on-second-control-after-fixing-first.aspx</link>
            <description>There's a bug in the Validator Callout in the AJAX Control Toolkit documented by bugs &lt;a target="_blank" href="http://www.codeplex.com/AtlasControlToolkit/WorkItem/View.aspx?WorkItemId=10900"&gt;10900&lt;/a&gt;, &lt;a target="_blank" href="http://www.codeplex.com/AtlasControlToolkit/WorkItem/View.aspx?WorkItemId=12342"&gt;12342&lt;/a&gt;, &lt;a target="_blank" href="http://www.codeplex.com/AtlasControlToolkit/WorkItem/View.aspx?WorkItemId=15698"&gt;15698&lt;/a&gt;, and &lt;a target="_blank" href="http://www.codeplex.com/AtlasControlToolkit/WorkItem/View.aspx?WorkItemId=11701"&gt;11701&lt;/a&gt; on the Code Plex site.  All 4 bugs describe the following undesired behavior:&lt;br /&gt;
&lt;ol&gt;
    &lt;li&gt;Pull up the AJAX Control Toolkit Sample site's Validator Callout example (&lt;a target="_blank" href="http://asp.net/AJAX/AjaxControlToolkit/Samples/ValidatorCallout/ValidatorCallout.aspx"&gt;here&lt;/a&gt;)&lt;/li&gt;
    &lt;li&gt;Push submit&lt;/li&gt;
    &lt;li&gt;Note that both fields are invalid, and the first field shows the Validator Callout&lt;/li&gt;
    &lt;li&gt;Add text to the first TextBox&lt;/li&gt;
    &lt;li&gt;Push submit&lt;/li&gt;
    &lt;li&gt;The Validator Callout for the top text field is gone, the Validator Callout for the second TextBox is not shown but should be&lt;br /&gt;
    &lt;/li&gt;
&lt;/ol&gt;
This is the symptom identified by these 4 bug reports.&lt;br /&gt;
&lt;br /&gt;
The problem?  The Validator Callout set this._isOpen at the top of the show() method, but actually did the showing at the bottom of the method -- after checking a few more things.  So, when you push submit in step 2 above, it actually sets this._isOpen = true on both Validator Callouts even though only one is actually visible.  Once you fix TextBox 1, and push submit, it runs through the validators again, notes #1 is now valid, and #2 is still invalid.  It also notes that #2 says it's visible, and doesn't bother showing it.&lt;br /&gt;
&lt;br /&gt;
The solution is uber-simple:&lt;br /&gt;
&lt;br /&gt;
- Replace the get_isOpen() function at the bottom of ValidatorCalloutBehavior.js with this one, which actually checks if the pop-up is visible:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;get_isOpen : function() {&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;    return $common.getVisible(this._popupTable);&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;/div&gt;
&lt;br /&gt;
- Delete all lines that assign something to this._isOpen (e.g. &lt;span style="font-family: Courier New;"&gt;this._isOpen = false;&lt;/span&gt;)&lt;br /&gt;
&lt;br /&gt;
- Replace all lines that use &lt;span style="font-family: Courier New;"&gt;this._isOpen&lt;/span&gt; with &lt;span style="font-family: Courier New;"&gt;this.get_isOpen()&lt;/span&gt;.  By my count, there are two such lines: one in show() and one in hide().&lt;br /&gt;
&lt;br /&gt;
That's it.  It now no longer guesses if the validator is visible, it checks the table it created to see if it's actually visible.&lt;br /&gt;
&lt;br /&gt;
I've submitted the patch to the 4 bugs on CodePlex, and hopefully it'll get into the next release.  If you're anxious to have this bug fixed as much as I, you can just download the modified file from CodePlex &lt;a href="http://www.codeplex.com/AtlasControlToolkit/WorkItem/AttachmentDownload.ashx?WorkItemId=10900&amp;amp;FileAttachmentId=6068"&gt;here&lt;/a&gt; including the JavaScript unit test that proves the problem existed and is now solved.&lt;br /&gt;
&lt;br /&gt;
Rob&lt;img src="http://robrich.org/aggbug/46.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/03/27/validator-callout-doesnt-display-on-second-control-after-fixing-first.aspx</guid>
            <pubDate>Thu, 27 Mar 2008 09:34:33 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/46.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/03/27/validator-callout-doesnt-display-on-second-control-after-fixing-first.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/46.aspx</wfw:commentRss>
        </item>
        <item>
            <title>LINQ to SQL Visualizer isn't in the transaction it is visualizing</title>
            <category>Tools</category>
            <link>http://robrich.org/archive/2008/02/29/linq-to-sql-visualizer-isnt-in-the-transaction-it-is.aspx</link>
            <description>&lt;p&gt;The LINQ to SQL Visualizer is a phenomenal tool.  This is how debugging should be done.  &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx"&gt;Scott Guthrie&lt;/a&gt; introduced it in the Visual Studio 2008 Beta 2 timeframe, and I've been hooked ever since.  It's now bundled in the Visual Studio 2008 RTM samples, though it's not installed by default.  Instructions of how to install it are &lt;a href="/archive/2007/12/22/Linq-to-Sql-Query-Visualizer.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Well, I'm splunking along in some code that happens to be in a transaction.  I've just inserted a row, and I'm about to execute the select that refreshes the business object with generated content including the primary key.  I open up the Visualizer, and push the Execute button.  Nothing happens, and the window freezes.&lt;/p&gt;  &lt;p&gt;It dawns on me that the unit test's transaction has locked the row in question, and the Visualizer can't get to it.  Well, that's all fine and good, but why wouldn't it be in the same transaction and/or join the transaction and/or create a rollback point in the transaction in process so the "execute" button can be undone once the window is closed?&lt;/p&gt;  &lt;p&gt;I emailed Scott Gu, and he passed on my question.  (Scott is phenomenally awesome with email, by the way.  I can only imagine how many emails he gets from users across the globe, and each time I email, I get a personal response.  I hope I can be that awesome when I grow up and get an office with a window.)  The answer came from a tech that Visualizers don't use the same app domain as Visual Studio, so reusing the connection was impossible, making subscribing to the transaction also impossible.&lt;/p&gt;  &lt;p&gt;Since this is sample code, and thus the code is provided, I'd like to take a stab on an off hour changing the sample to store the SqlConnection (or IDbConnection) rather than the ConnectionString and see if it works.  I expect it won't, but if it did, wouldn't it be cool?&lt;/p&gt;  &lt;p&gt;In the mean time, I'll just remember to look in the LINQ to SQL Visualizer but not execute if I'm inside a transaction.  If I'm that curious, I'll grab the query, finish the transaction, and execute it inside Sql Management Studio or &lt;a href="http://www.linqpad.net"&gt;LinqPad&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Rob&lt;/p&gt;&lt;img src="http://robrich.org/aggbug/45.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/02/29/linq-to-sql-visualizer-isnt-in-the-transaction-it-is.aspx</guid>
            <pubDate>Fri, 29 Feb 2008 07:20:32 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/45.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/02/29/linq-to-sql-visualizer-isnt-in-the-transaction-it-is.aspx#feedback</comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/45.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Compile time reminders</title>
            <category>Code</category>
            <category>Tools</category>
            <link>http://robrich.org/archive/2008/02/29/compile-time-reminders.aspx</link>
            <description>&lt;p&gt;For ages I've wanted to be able to put a comment of some kind in my code that I could get to come up during a build.  "Hey, you haven't finished this" or "This is an assumption we need to run by the suits" or "you dork, how could you even think to do it this way" or similar -- notes to myself and others that there is work left to be done here.&lt;/p&gt;  &lt;p&gt;Well, after trying unsuccessfully to look towards subclassing or hacking the Obsolete attribute the answer was handed to me:&lt;/p&gt;  &lt;p&gt;1. I build comments in the form &lt;font face="Courier New"&gt;// TODO:&lt;/font&gt; or &lt;font face="Courier New"&gt;// ASSUME:&lt;/font&gt; or &lt;font face="Courier New"&gt;// BROKEN:&lt;/font&gt; or similar, I choose the View menu, and choose Task List.  Ok, granted, that's been there since the beginning of time, but who put that there and why didn't they tell me?  Holy cow, that's cool.  I can even configure it with my own set of commentaries like &lt;font face="Courier New"&gt;// DORK_MOVE:&lt;/font&gt; or &lt;font face="Courier New"&gt;// INSECURE:&lt;/font&gt; or &lt;font face="Courier New"&gt;// WHAT_WERE_YOU_THINKING:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;2. There's a pre-processor directive called &lt;font face="Courier New"&gt;# warning&lt;/font&gt;.  Put what ever message you want after, and it shows up in the normal error list.&lt;/p&gt;  &lt;p&gt;With these two tools now in the arsenal, I can capture my thoughts in the place most relevant to the task at hand -- in the code.  And I can be reminded of them in the place most relevant to the task at hand -- the next tab over from the build output window.  Very nice.&lt;/p&gt;  &lt;p&gt;Rob&lt;/p&gt;&lt;img src="http://robrich.org/aggbug/44.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/02/29/compile-time-reminders.aspx</guid>
            <pubDate>Fri, 29 Feb 2008 07:01:21 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/44.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/02/29/compile-time-reminders.aspx#feedback</comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/44.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Filter Sql Server Profiler by Database</title>
            <category>Tools</category>
            <link>http://robrich.org/archive/2008/02/28/filter-sql-server-profiler-by-database.aspx</link>
            <description>&lt;p&gt;Ok, I stumbled with this one enough times to log it here.  I want to tune a database I'm working with.  I dutifully fire up Sql Server's Profiler, and no where in the options do I see "filter by database".&lt;/p&gt;  &lt;p&gt;Ok, the option is there, but it takes some doing to get there.  When you're building the profile, in the events selection tab, choose "show all columns", then you'll find the "Database Name" column.  Pop in the database name in question, and you're golden.&lt;/p&gt;  &lt;p&gt;source: &lt;a title="http://sqljunkies.com/Forums/ShowPost.aspx?PostID=14078" href="http://sqljunkies.com/Forums/ShowPost.aspx?PostID=14078" rel="nofollow"&gt;http://sqljunkies.com/Forums/ShowPost.aspx?PostID=14078&lt;/a&gt;&lt;/p&gt;&lt;img src="http://robrich.org/aggbug/43.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/02/28/filter-sql-server-profiler-by-database.aspx</guid>
            <pubDate>Fri, 29 Feb 2008 06:47:27 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/43.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/02/28/filter-sql-server-profiler-by-database.aspx#feedback</comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/43.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Thinking in JavaScript for the C# Developer</title>
            <category>Code</category>
            <category>Events</category>
            <link>http://robrich.org/archive/2008/02/28/thinking-in-javascript-for-the-c-developer.aspx</link>
            <description>&lt;p&gt;I had the great privilege and honor of presenting "Thinking in JavaScript" at the SouthEast Valley .NET Users Group this evening.  All in all, I had a ton of fun.  If anyone else got anything out of it, all the better.&lt;/p&gt;
&lt;p&gt;The main point of my discourse was that JavaScript isn't hard by any means, it just takes an introduction to how it thinks.  Microsoft's ASP.NET AJAX has made it feel much more like the .net languages we're used to.  But there are still some inherent differences between a compiled language and a dynamic language.&lt;/p&gt;
&lt;p&gt;The main focus of the discussion is these few points:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Every object is a Dictionary.  In C#, think of Dictionary&amp;lt;string,object&amp;gt;. &lt;/li&gt;
    &lt;li&gt;Functions assigned into the object's 'dictionary' are like methods. &lt;/li&gt;
    &lt;li&gt;Functions are objects, and can be assigned like variables.  In C#, think of delegates. &lt;/li&gt;
    &lt;li&gt;Every parameter in a function is optional, allowing for uber-easy "function overloading". &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We also covered incredibly cool tools for working with JavaScript:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;FireBug -- &lt;a href="http://www.getfirebug.com"&gt;getfirebug.com&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;Web Developer Toolbar for Firefox -- &lt;a href="http://addons.mozilla.org/firefox/addon/60"&gt;addons.mozilla.org/firefox/addon/60&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;Visual Studio 2008's JavaScript Intelisense &lt;/li&gt;
    &lt;li&gt;JSView plugin for Firefox -- &lt;a href="http://addons.mozilla.org/firefox/addon/2076"&gt;addons.mozilla.org/firefox/addon/2076&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;IETab plugin for Firefox -- &lt;a href="http://addons.mozilla.org/firefox/addon/1419"&gt;addons.mozilla.org/firefox/addon/1419&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;YSlow plugin for FireBug that evaluates your code based on &lt;a href="http://developer.yahoo.com/performance/rules.html"&gt;Yahoo's Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can open up MicrosoftAjax.debug.js file by cruising to C:\ Program Files\ Microsoft ASP.NET\ ASP.NET 2.0 AJAX Extensions\ v1.0.61025\ MicrosoftAjaxLibrary\ System.Web.Extensions\ 1.0.61025.0\ *.debug.js (spaces added for clarity)&lt;/p&gt;
&lt;p&gt;And the coolest thing of all -- anything built in JavaScript is available for download by choosing "View Source".  When you publish anything in JavaScript, you don't publish a compiled assembly, you publish your source.  Thus anything created in JavaScript becomes awesome reference material -- bonus!&lt;/p&gt;
&lt;p&gt;The slides for this are in Powerpoint 2007 format and available &lt;a href="http://robrich.org/content/Thinking_in_Javascript.zip"&gt;here&lt;/a&gt;.  The code we walked through was from Rob Bagby's webcast series on the ASP.NET AJAX Client Libraries available from his blog: &lt;a href="http://blogs.msdn.com/bags/archive/2007/06/07/latest-asp-net-client-libraries-webcast-sample-code-and-links-to-all-sessions.aspx"&gt;blogs.msdn.com/bags/archive/2007/06/07/latest-asp-net-client-libraries-webcast-sample-code-and-links-to-all-sessions.aspx&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/bags/archive/2007/06/07/links-to-remaining-asp-net-ajax-client-libraries-webcasts.aspx"&gt;blogs.msdn.com/bags/archive/2007/06/07/links-to-remaining-asp-net-ajax-client-libraries-webcasts.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks to all who came -- you got some cool swag, and thanks to our sponsor who bought the pizza and showed us just how much we love LINQ. :D&lt;/p&gt;
&lt;p&gt;Rob&lt;/p&gt;&lt;img src="http://robrich.org/aggbug/42.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Richardson</dc:creator>
            <guid>http://robrich.org/archive/2008/02/28/thinking-in-javascript-for-the-c-developer.aspx</guid>
            <pubDate>Fri, 29 Feb 2008 06:39:12 GMT</pubDate>
            <wfw:comment>http://robrich.org/comments/42.aspx</wfw:comment>
            <comments>http://robrich.org/archive/2008/02/28/thinking-in-javascript-for-the-c-developer.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://robrich.org/comments/commentRss/42.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>