<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>JavaScript</title>
        <link>http://www.nimblecoder.com/blog/category/2.aspx</link>
        <description>JavaScript</description>
        <language>en-US</language>
        <copyright>Ryan Van Slooten</copyright>
        <generator>Subtext Version 2.1.1.1</generator>
        <item>
            <title>Constant Prototyping and Design</title>
            <link>http://nimblecoder.com/blog/archive/2008/07/31/constant-prototyping-and-design.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/ConstantPrototypingandDesign_885D/BalletDancer_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" alt="Ballet" src="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/ConstantPrototypingandDesign_885D/BalletDancer_thumb.png" width="188" align="left" border="0" /&gt;&lt;/a&gt;A co-worker gave a presentation on a project we worked on a long time ago and he asked me to update an feature in the web application. The web app was originally programmed in ASP and I had almost forgotten how painful it was to work in that environment. The new request was to enable live presence information in a web part using the new &lt;a href="http://msdn.microsoft.com/en-us/library/ms931946.aspx" target="_blank"&gt;RTC&lt;/a&gt; libraries. Fortunately, another developer had a component to perform all of the calls using the RTC libraries, but I needed to retrieve the group members for the selected group and cross-reference the group members with online presence.&lt;/p&gt; &lt;p&gt;The actual details involved opening "MTSAdmin.Catalog.1" object and looking for a specific COM+ package, enumerating the "RolesInPackage", and then getting the "UsersInRole". There were several layers of filtering going on and I wanted an elegant solution. Unfortunately I kept trying to be too elegant and I was getting hung up on how to make it more elegant. I wanted to have a "before", "item", and "after" callback functions at each of the function depth levels where the "item" function would occur in the iteration loop. This would allow for scenarios where items might need to be collected after iteration, particularly to avoid making multiple unnecessary calls to the lower filtering methods.&lt;/p&gt; &lt;h3&gt;Small example from jQuery&lt;/h3&gt;&lt;pre class="js" name="code"&gt;ajax: function( s ) {
  &lt;span class="rem"&gt;// Extend the settings, but re-extend 's' so that it can be&lt;/span&gt;
  &lt;span class="rem"&gt;// checked again later (in the test suite, specifically)&lt;/span&gt;
  s = jQuery.extend(&lt;span class="kwrd"&gt;true&lt;/span&gt;, s, jQuery.extend(&lt;span class="kwrd"&gt;true&lt;/span&gt;, {}, jQuery.ajaxSettings, s));

  &lt;span class="rem"&gt;// ... snip, snip, snip ...&lt;/span&gt;

  &lt;span class="rem"&gt;// Allow custom headers/mimetypes&lt;/span&gt;
  &lt;span class="kwrd"&gt;if&lt;/span&gt; ( s.beforeSend &amp;amp;&amp;amp; s.beforeSend(xhr, s) === &lt;span class="kwrd"&gt;false&lt;/span&gt; ) {
    &lt;span class="rem"&gt;// cleanup active request counter&lt;/span&gt;
    s.global &amp;amp;&amp;amp; jQuery.active--;
    &lt;span class="rem"&gt;// close opended socket&lt;/span&gt;
    xhr.abort();
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
  }
&lt;/pre&gt;
&lt;p&gt;The example above from jQuery only uses the "before" concept that I mentioned above, but it shows a very nice implementation where the 's' object is based on jQuery.ajaxSettings. Just before the AJAX call is about to be made, jQuery checks for any custom headers and calls the 'beforeSend' function if it exists.&lt;/p&gt;
&lt;h3&gt;Start Simple and Add Progressive Elegance&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ableman/234145236/"&gt;&lt;img height="160" alt="BaseballHomerun" src="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/ConstantPrototypingandDesign_885D/BaseballHomerun_3.jpg" width="240" align="right" border="0" /&gt;&lt;/a&gt; I did manage to get the function working correctly, but I had to take a step back and start simple and progressively build additional functionality into the component. Sometimes you have inspiration and you can just design and code and everything is great. Other times it can take a while before the inspiration comes. It is better to start coding and have something you can refine rather than wait and lose valuable time.&lt;/p&gt;
&lt;p&gt;To use a baseball analogy: Don't try to hit a homerun every time; sometimes you need to play "&lt;a href="http://en.wikipedia.org/wiki/Small_Ball"&gt;small ball&lt;/a&gt;" and get people in scoring position and just try to make contact. A similar soccer (futból!) analogy would be don't just try to dribble down the field and score every time, but you need to pass and set up the players around you to maximize the scoring opportunity.&lt;/p&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/70.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid>http://nimblecoder.com/blog/archive/2008/07/31/constant-prototyping-and-design.aspx</guid>
            <pubDate>Thu, 31 Jul 2008 16:28:32 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/70.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/07/31/constant-prototyping-and-design.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/70.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/70.aspx</trackback:ping>
        </item>
        <item>
            <title>Just the facts, ma'am</title>
            <link>http://nimblecoder.com/blog/archive/2008/04/21/just-the-facts-maam.aspx</link>
            <description>&lt;p&gt;I was looking at &lt;a href="http://www.crockford.com/" target="_blank"&gt;Douglas Crockford's&lt;/a&gt; &lt;a href="http://blog.360.yahoo.com/douglascrockford" target="_blank"&gt;360 blog&lt;/a&gt; today and came across a &lt;a href="http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?p=814" target="_blank"&gt;hilarious quote&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Do you write regularly for any publications in this field? &lt;/em&gt; &lt;/p&gt;&lt;p&gt;Just the blogs.  &lt;/p&gt;&lt;p&gt;&lt;em&gt;In researching the book, did you come across any surprising facts, figures, or statistics that the press might be interested in?&lt;/em&gt;  &lt;/p&gt;&lt;p&gt;&lt;span style="background-color: #e0e0e0"&gt;Surprisingly, facts have very little to do with web development.&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Douglas Crockford is simply amazing and is the original author of &lt;a title="expat XML parser" href="http://expat.sourceforge.net/" target="_blank"&gt;expat&lt;/a&gt; (one of the first XML parsing libraries), as well as &lt;a title="JavaScript verifier" href="http://www.jslint.com/" target="_blank"&gt;JSLint&lt;/a&gt;, &lt;a title="JavaScript Minifier" href="http://javascript.crockford.com/jsmin.html" target="_blank"&gt;JSMin&lt;/a&gt;, and &lt;a title="JavaScript Object Notation" href="http://www.json.org/" target="_blank"&gt;JSON&lt;/a&gt; (one of the primary components of AJAX).&lt;/p&gt; &lt;p&gt;P.S. Bonus points for any one identifying the blog post title source.&lt;/p&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/64.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid>http://nimblecoder.com/blog/archive/2008/04/21/just-the-facts-maam.aspx</guid>
            <pubDate>Mon, 21 Apr 2008 15:15:15 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/64.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/04/21/just-the-facts-maam.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/64.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/64.aspx</trackback:ping>
        </item>
        <item>
            <title>SVG Building Map (Part 1)</title>
            <link>http://nimblecoder.com/blog/archive/2007/12/06/svg-building-map-part-1.aspx</link>
            <description>&lt;p&gt;&lt;a href="/blog/Samples/svg/building01/building.html"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="188" alt="SVG Building Map Sample 01" src="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SVGBuildingMapPart1_14B47/buildmapsample01.png" width="244" align="left" border="0" /&gt;&lt;/a&gt;Due to blog restrictions, the sample is located on a separate page.&lt;/p&gt; &lt;p&gt;&lt;a href="/blog/Samples/svg/building01/building.html"&gt;building.html&lt;/a&gt;: SVG sample&lt;/p&gt; &lt;p&gt;&lt;a href="/blog/Samples/svg/building01/BuildingSample01.zip"&gt;BuildingSample01.zip&lt;/a&gt;: source (6KB)&lt;/p&gt; &lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: In my &lt;a href="/blog/archive/2007/12/04/svg-building-map-part-0.aspx" target="_blank"&gt;previous blog entry&lt;/a&gt;, I stated that SVG is a technology with diminishing support and that ultimately I plan to convert this building map to &lt;a href="http://silverlight.net/"&gt;SilverLight&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The first example is a very basic building map. I created a simple SVG file to represent a building and then created occupants for the building (as if you could keep these &lt;a href="http://www.looneytunes.com" target="_blank"&gt;crazy rascals&lt;/a&gt; in a building -- look at the names and you should know what I mean).&lt;/p&gt; &lt;p&gt;For simplicity this sample does not dynamically load the occupant information nor does it have multiple floors. Instead the occupants are specified in a static JavaScript file although this is identical to the Adobe sample where the occupants are static. Future enhancements will include these features as well as additional functionality.&lt;/p&gt; &lt;h3&gt;Step 1: Define the Building Map&lt;/h3&gt; &lt;p&gt;I used &lt;a href="http://inkscape.org/"&gt;Inkscape&lt;/a&gt; to create the SVG image, but ultimately ended up changing the SVG/XML by hand to create the simplest case for this example.&lt;/p&gt; &lt;h3&gt;Step 2: Define a "Room"&lt;/h3&gt; &lt;p&gt;This example will only make use of a "room" although future examples will have the concept of a "resource" (printer, conference room, etc.). In order to handle the JavaScript events (well technically &lt;a href="http://en.wikipedia.org/wiki/Ecmascript" target="_blank"&gt;ecmascript&lt;/a&gt; events), the script handlers need to be able to identify a room and so I simply used added the class "room" to the SVG element:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/css"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/* snip, snip... */&lt;/span&gt;
.room {
    fill:#c0c0ff;
    stroke:#222277;
    stroke-width:1;
}
&lt;span class="rem"&gt;/* snip, snip... */&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;&amp;lt;!-- more snip, snip... --&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;g&lt;/span&gt;
        &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="room101"&lt;/span&gt;
        &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;="room"&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;rect&lt;/span&gt;
            &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="rect101"&lt;/span&gt;
            &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;="room"&lt;/span&gt;
            &lt;span class="attr"&gt;width&lt;/span&gt;&lt;span class="kwrd"&gt;="150"&lt;/span&gt;
            &lt;span class="attr"&gt;height&lt;/span&gt;&lt;span class="kwrd"&gt;="100"&lt;/span&gt;
            &lt;span class="attr"&gt;x&lt;/span&gt;&lt;span class="kwrd"&gt;="0"&lt;/span&gt;
            &lt;span class="attr"&gt;y&lt;/span&gt;&lt;span class="kwrd"&gt;="0"&lt;/span&gt;
        &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;text&lt;/span&gt;
            &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="text101"&lt;/span&gt;
            &lt;span class="attr"&gt;x&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt;
            &lt;span class="attr"&gt;y&lt;/span&gt;&lt;span class="kwrd"&gt;="55"&lt;/span&gt;
            &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;="label"&lt;/span&gt;
            &lt;span class="attr"&gt;xml:space&lt;/span&gt;&lt;span class="kwrd"&gt;="preserve"&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tspan&lt;/span&gt;
                &lt;span class="attr"&gt;x&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt;
                &lt;span class="attr"&gt;y&lt;/span&gt;&lt;span class="kwrd"&gt;="55"&lt;/span&gt;
                &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="tspan101"&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;101&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tspan&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;text&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;g&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Notice that the room is defined as a group: { rect, text { tspan } }. The JavaScript handler will assume this definition will be consistent for all rooms.&lt;/p&gt;
&lt;h3&gt;Step 3: Add the Room handler to JavaScript&lt;/h3&gt;
&lt;p&gt;The JavaScript handler identifies a "room" to avoid processing elements that are "rooms." The line that contains: if (className != "room") will prevent the script from processing non-rooms.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// get room name and ID&lt;/span&gt;
&lt;span class="rem"&gt;///////////////////////&lt;/span&gt;
&lt;span class="kwrd"&gt;function&lt;/span&gt; getRoom(target)
{
    &lt;span class="kwrd"&gt;var&lt;/span&gt; svgElem = getNodeOrParent(target, &lt;span class="str"&gt;"g"&lt;/span&gt;);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (svgElem)
    {
        &lt;span class="kwrd"&gt;var&lt;/span&gt; thisRm = svgElem;
        &lt;span class="kwrd"&gt;var&lt;/span&gt; thisType = thisRm.tagName;
        &lt;span class="kwrd"&gt;var&lt;/span&gt; id = thisRm.getAttribute(&lt;span class="str"&gt;'id'&lt;/span&gt;);
        &lt;span class="kwrd"&gt;var&lt;/span&gt; className = thisRm.getAttribute(&lt;span class="str"&gt;'class'&lt;/span&gt;);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (className != &lt;span class="str"&gt;"room"&lt;/span&gt;)
            &lt;span class="kwrd"&gt;return&lt;/span&gt;;

        &lt;span class="kwrd"&gt;var&lt;/span&gt; num;
        &lt;span class="kwrd"&gt;var&lt;/span&gt; rect = getChildElem(svgElem, &lt;span class="str"&gt;"rect"&lt;/span&gt;);
        &lt;span class="kwrd"&gt;var&lt;/span&gt; text = getChildElem(svgElem, &lt;span class="str"&gt;"tspan"&lt;/span&gt;);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (text)
            num = text.firstChild.data;

        &lt;span class="kwrd"&gt;return&lt;/span&gt; { &lt;span class="str"&gt;'num'&lt;/span&gt;:num, &lt;span class="str"&gt;'id'&lt;/span&gt;:id, &lt;span class="str"&gt;'rect'&lt;/span&gt;:rect, &lt;span class="str"&gt;'group'&lt;/span&gt;:svgElem };
    }
}
&lt;/pre&gt;
&lt;h3&gt;Step 4: Handle the mouse events&lt;/h3&gt;
&lt;p&gt;The base group specifies the event handlers for the entire SVG.&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;g&lt;/span&gt;
        &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="room-layer"&lt;/span&gt;
        &lt;span class="attr"&gt;onclick&lt;/span&gt;&lt;span class="kwrd"&gt;="selector(evt);"&lt;/span&gt;
        &lt;span class="attr"&gt;onmouseover&lt;/span&gt;&lt;span class="kwrd"&gt;="onImg(evt);"&lt;/span&gt;
        &lt;span class="attr"&gt;onmouseout&lt;/span&gt;&lt;span class="kwrd"&gt;="offImg(evt);"&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The local SVG functions are just references to JavaScript functions in the hosted page:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&amp;lt;script type=&lt;span class="str"&gt;"text/ecmascript"&lt;/span&gt;&amp;gt;&amp;lt;![CDATA[
&lt;span class="kwrd"&gt;function&lt;/span&gt; onImg(evt)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (top &amp;amp;&amp;amp; top.onImg)
        top.onImg(evt);
}

&lt;span class="kwrd"&gt;function&lt;/span&gt; offImg(evt)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (top &amp;amp;&amp;amp; top.offImg)
        top.offImg(evt);
}

&lt;span class="kwrd"&gt;function&lt;/span&gt; selector(evt)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (top &amp;amp;&amp;amp; top.selector)
        top.selector(evt);
}
]]&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;h3&gt;Step 5: Handle the onmouseover event&lt;/h3&gt;
&lt;p&gt;The mouseover event displays the occupant information. If the user has clicked on a room and selected that room, the mouseover event will not update the display information.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// room mouseovers&lt;/span&gt;
&lt;span class="kwrd"&gt;function&lt;/span&gt; onImg(mouseEvt)
{
    &lt;span class="rem"&gt;// No highlighting when an item is selected&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (selection &amp;amp;&amp;amp; selection.room)
        &lt;span class="kwrd"&gt;return&lt;/span&gt;;

    &lt;span class="rem"&gt;// get the room name and ID&lt;/span&gt;
    &lt;span class="kwrd"&gt;var&lt;/span&gt; target = mouseTarget(mouseEvt);
    &lt;span class="kwrd"&gt;var&lt;/span&gt; room = getRoom(target);
    
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (room &amp;amp;&amp;amp;
        highlighted &amp;amp;&amp;amp; 
        highlighted.room &amp;amp;&amp;amp;
        highlighted.room.id == room.id)
    {
        &lt;span class="rem"&gt;// Same item as before highlighted&lt;/span&gt;
        &lt;span class="kwrd"&gt;return&lt;/span&gt;;
    }
    
    &lt;span class="rem"&gt;// save the style object for the rolloff&lt;/span&gt;
    &lt;span class="kwrd"&gt;var&lt;/span&gt; oldStyle = updateStyle(room, rollStyles.rollOver);
    &lt;span class="rem"&gt;// show the occupant info&lt;/span&gt;
    displayRoom(room);
    highlighted = { room: room, oldStyle: oldStyle } ;
}
&lt;/pre&gt;
&lt;h3&gt;Step 6: Handle the onmouseout event&lt;/h3&gt;
&lt;p&gt;When the user moves the mouse off of a room, the display will clear the occupant information. If a user is selected, the display will keep the selected occupant.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; offImg(mouseEvt)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (highlighted)
    {
        resetStyle(highlighted);
        highlighted = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    }
}
&lt;/pre&gt;
&lt;h3&gt;Step 7: Handle the room selection (onclick event)&lt;/h3&gt;
&lt;p&gt;When the user clicks on a room, the page will select that room and stop the automatic display of other information during mouseover and mouseout events.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; selector(mouseEvt) {
    &lt;span class="rem"&gt;// Turn off any highlighting&lt;/span&gt;
    offImg(mouseEvt);

    &lt;span class="rem"&gt;// get the room name and ID&lt;/span&gt;
    &lt;span class="kwrd"&gt;var&lt;/span&gt; target = mouseTarget(mouseEvt);
    &lt;span class="kwrd"&gt;var&lt;/span&gt; room = getRoom(target);

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (room &amp;amp;&amp;amp;
        selection &amp;amp;&amp;amp; 
        selection.room &amp;amp;&amp;amp;
        room.id == selection.room.id)
    {
        &lt;span class="rem"&gt;// Deselect the item&lt;/span&gt;
        resetStyle(selection);
        selection = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
        &lt;span class="kwrd"&gt;return&lt;/span&gt;;
    }

    resetStyle(selection);
    &lt;span class="rem"&gt;// save the style object for the rolloff&lt;/span&gt;
    &lt;span class="kwrd"&gt;var&lt;/span&gt; oldStyle = updateStyle(room, rollStyles.selected);

    &lt;span class="rem"&gt;// show the occupant info&lt;/span&gt;
    displayRoom(room);
    selection = { room: room, oldStyle: oldStyle } ;
}
&lt;/pre&gt;
&lt;h3&gt;Step 8: Handle the style changes to the SVG elements&lt;/h3&gt;
&lt;p&gt;A lot of the challenge to get this sample to work in FireFox was with the setProperty function. When I added the last "null" parameter, it started working.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; rollStyles = {
    rollOver: {
        fill            : &lt;span class="str"&gt;'cyan'&lt;/span&gt;
       ,&lt;span class="str"&gt;"stroke-width"&lt;/span&gt;  : &lt;span class="str"&gt;'3'&lt;/span&gt; }
   ,selected: {
        fill            : &lt;span class="str"&gt;'blue'&lt;/span&gt;
       ,&lt;span class="str"&gt;"stroke-width"&lt;/span&gt;  : &lt;span class="str"&gt;'3'&lt;/span&gt; }
};
&lt;span class="rem"&gt;/* snip, snip... */&lt;/span&gt;
&lt;span class="kwrd"&gt;function&lt;/span&gt; updateStyle(elem, styleType) {
    &lt;span class="kwrd"&gt;var&lt;/span&gt; svgElem = elem ? elem.rect: &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (svgElem &amp;amp;&amp;amp; styleType)
    {
        &lt;span class="kwrd"&gt;var&lt;/span&gt; svgStyle = svgElem.style;
        &lt;span class="kwrd"&gt;var&lt;/span&gt; oldStyle = { };
        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; name &lt;span class="kwrd"&gt;in&lt;/span&gt; styleType) {
            oldStyle[name] = svgStyle.getPropertyValue(name);
            &lt;span class="kwrd"&gt;try&lt;/span&gt; {
            svgStyle.setProperty(name, styleType[name], &lt;span class="kwrd"&gt;null&lt;/span&gt;);
            } &lt;span class="kwrd"&gt;catch&lt;/span&gt; (e) {
                window.alert(&lt;span class="str"&gt;'Error '&lt;/span&gt; + e.number + &lt;span class="str"&gt;": "&lt;/span&gt; + e.message);
            }
        }
        elem[&lt;span class="str"&gt;"oldStyle"&lt;/span&gt;] = oldStyle;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; oldStyle;
    }
}

&lt;span class="kwrd"&gt;function&lt;/span&gt; resetStyle(elem) 
{
    &lt;span class="kwrd"&gt;var&lt;/span&gt; svgElem = (elem &amp;amp;&amp;amp; elem.room) ? elem.room.rect : &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    &lt;span class="kwrd"&gt;var&lt;/span&gt; oldStyle = elem ? elem.oldStyle : &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (svgElem &amp;amp;&amp;amp; oldStyle)
    {
        &lt;span class="kwrd"&gt;var&lt;/span&gt; svgStyle = svgElem.style;
        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; name &lt;span class="kwrd"&gt;in&lt;/span&gt; oldStyle) 
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; ( !oldStyle[name] )
                svgStyle.removeProperty(name);
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
                svgStyle.setProperty(name, oldStyle[name], &lt;span class="kwrd"&gt;null&lt;/span&gt;);
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;Step 9: Display the occupant information&lt;/p&gt;
&lt;p&gt;When the onmouseover event fires on a room, the page displays the occupant information:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// display room info&lt;/span&gt;
&lt;span class="kwrd"&gt;function&lt;/span&gt; displayRoom(room)
{
    &lt;span class="kwrd"&gt;var&lt;/span&gt; found = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (room &amp;amp;&amp;amp; room.num)
    {
        &lt;span class="kwrd"&gt;var&lt;/span&gt; id = &lt;span class="str"&gt;"Rm_"&lt;/span&gt; + room.num;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (g_rmData &amp;amp;&amp;amp; g_rmData[id]) 
        {
            &lt;span class="kwrd"&gt;var&lt;/span&gt; person1 = g_rmData[id];
            document.getElementById(&lt;span class="str"&gt;"tdRoom"&lt;/span&gt;).innerHTML = person1.room;
            document.getElementById(&lt;span class="str"&gt;"tdName"&lt;/span&gt;).innerHTML = person1.name;
            document.getElementById(&lt;span class="str"&gt;"tdPhone"&lt;/span&gt;).innerHTML = person1.phone;
            document.getElementById(&lt;span class="str"&gt;"tdEmail"&lt;/span&gt;).innerHTML = &lt;span class="str"&gt;"&amp;lt;a href='mailto:"&lt;/span&gt; + person1.email + &lt;span class="str"&gt;"'&amp;gt;"&lt;/span&gt; + person1.email + &lt;span class="str"&gt;"&amp;lt;/a&amp;gt;"&lt;/span&gt;;
            found = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }
    }
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!found) 
    {
            document.getElementById(&lt;span class="str"&gt;"tdRoom"&lt;/span&gt;).innerHTML = &lt;span class="str"&gt;"&amp;amp;nbsp;"&lt;/span&gt;;
            document.getElementById(&lt;span class="str"&gt;"tdName"&lt;/span&gt;).innerHTML = &lt;span class="str"&gt;"&amp;amp;nbsp;"&lt;/span&gt;;
            document.getElementById(&lt;span class="str"&gt;"tdPhone"&lt;/span&gt;).innerHTML = &lt;span class="str"&gt;"&amp;amp;nbsp;"&lt;/span&gt;;
            document.getElementById(&lt;span class="str"&gt;"tdEmail"&lt;/span&gt;).innerHTML = &lt;span class="str"&gt;"&amp;amp;nbsp;"&lt;/span&gt;;
    }
}
&lt;/pre&gt;
&lt;h3&gt;Step 10: Define the occupant information&lt;/h3&gt;
&lt;p&gt;For this sample, the data is defined in a static javascript file.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; g_rmRawData = [
 { room : &lt;span class="str"&gt;'100'&lt;/span&gt;, name : &lt;span class="str"&gt;'Bugs Bunny'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0100'&lt;/span&gt;, email : &lt;span class="str"&gt;'bugs.bunny@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'101'&lt;/span&gt;, name : &lt;span class="str"&gt;'Marvin the Martian'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0101'&lt;/span&gt;, email : &lt;span class="str"&gt;'marvin.the.martian@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'102'&lt;/span&gt;, name : &lt;span class="str"&gt;'Tweety'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0102'&lt;/span&gt;, email : &lt;span class="str"&gt;'tweety@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'103'&lt;/span&gt;, name : &lt;span class="str"&gt;'Taz'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0103'&lt;/span&gt;, email : &lt;span class="str"&gt;'taz@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'104'&lt;/span&gt;, name : &lt;span class="str"&gt;'Daffy Duck'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0104'&lt;/span&gt;, email : &lt;span class="str"&gt;'daffy.duck@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'105'&lt;/span&gt;, name : &lt;span class="str"&gt;'Foghorn Leghorn'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0105'&lt;/span&gt;, email : &lt;span class="str"&gt;'foghorn.leghorn@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'106'&lt;/span&gt;, name : &lt;span class="str"&gt;'Miss Prissy'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0106'&lt;/span&gt;, email : &lt;span class="str"&gt;'miss.prissy@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'107'&lt;/span&gt;, name : &lt;span class="str"&gt;'Chickenhawk'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0107'&lt;/span&gt;, email : &lt;span class="str"&gt;'chickenhawk@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'108'&lt;/span&gt;, name : &lt;span class="str"&gt;'Dawg'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0108'&lt;/span&gt;, email : &lt;span class="str"&gt;'dawg@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'109'&lt;/span&gt;, name : &lt;span class="str"&gt;'Wile E Coyote'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0109'&lt;/span&gt;, email : &lt;span class="str"&gt;'wile.e.coyote@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'110'&lt;/span&gt;, name : &lt;span class="str"&gt;'Road Runner'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0110'&lt;/span&gt;, email : &lt;span class="str"&gt;'road.runner@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'111'&lt;/span&gt;, name : &lt;span class="str"&gt;'Speedy Gonzalez'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0111'&lt;/span&gt;, email : &lt;span class="str"&gt;'speedy.gonzalez@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'112'&lt;/span&gt;, name : &lt;span class="str"&gt;'Pepe Le Pew'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0112'&lt;/span&gt;, email : &lt;span class="str"&gt;'pepe.le.pew@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'113'&lt;/span&gt;, name : &lt;span class="str"&gt;'Penelope'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0113'&lt;/span&gt;, email : &lt;span class="str"&gt;'penelope@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'114'&lt;/span&gt;, name : &lt;span class="str"&gt;'Porky Pig'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0114'&lt;/span&gt;, email : &lt;span class="str"&gt;'porky.pig@looneytunes.null'&lt;/span&gt; }
,{ room : &lt;span class="str"&gt;'115'&lt;/span&gt;, name : &lt;span class="str"&gt;'Elmer Fudd'&lt;/span&gt;, phone : &lt;span class="str"&gt;'1-800-555-0115'&lt;/span&gt;, email : &lt;span class="str"&gt;'elmer.fudd@looneytunes.null'&lt;/span&gt; }
];

&lt;span class="kwrd"&gt;var&lt;/span&gt; g_rmData = [];

&lt;span class="kwrd"&gt;function&lt;/span&gt; loadRoomData()
{
    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; i = 0; i &amp;lt; g_rmRawData.length; ++i)
        g_rmData[&lt;span class="str"&gt;'Rm_'&lt;/span&gt; + g_rmRawData[i].room] = g_rmRawData[i];
}

loadRoomData();
&lt;/pre&gt;
&lt;p&gt;For those who are interested, I copied the names of the characters from the Looney Tunes site and ran this Python script:&lt;/p&gt;&lt;pre class="csharpcode"&gt;def makeemail(s):
    &lt;span class="kwrd"&gt;return&lt;/span&gt; s.lower().replace(&lt;span class="str"&gt;' '&lt;/span&gt;,&lt;span class="str"&gt;'.'&lt;/span&gt;) + &lt;span class="str"&gt;'@looneytunes.null'&lt;/span&gt;
    
def makedict(name, num):
    &lt;span class="kwrd"&gt;return&lt;/span&gt; { &lt;span class="str"&gt;'name'&lt;/span&gt;:name, &lt;span class="str"&gt;'room'&lt;/span&gt;:str(num), &lt;span class="str"&gt;'email'&lt;/span&gt;:makeemail(name) }
    
def makedata(names, num, f):
    &lt;span class="kwrd"&gt;for&lt;/span&gt; name &lt;span class="kwrd"&gt;in&lt;/span&gt; names:
        print f % makedict(name, num)
        num = num + 1

n = [&lt;span class="str"&gt;"Bugs Bunny"&lt;/span&gt;,
    &lt;span class="str"&gt;"Marvin the Martian"&lt;/span&gt;,
    &lt;span class="str"&gt;"Tweety"&lt;/span&gt;,
    &lt;span class="str"&gt;"Taz"&lt;/span&gt;,
    &lt;span class="str"&gt;"Daffy Duck"&lt;/span&gt;,
    &lt;span class="str"&gt;"Foghorn Leghorn"&lt;/span&gt;,
    &lt;span class="str"&gt;"Miss Prissy"&lt;/span&gt;,
    &lt;span class="str"&gt;"Chickenhawk"&lt;/span&gt;,
    &lt;span class="str"&gt;"Dawg"&lt;/span&gt;,
    &lt;span class="str"&gt;"Wile E Coyote"&lt;/span&gt;,
    &lt;span class="str"&gt;"Road Runner"&lt;/span&gt;,
    &lt;span class="str"&gt;"Speedy Gonzalez"&lt;/span&gt;,
    &lt;span class="str"&gt;"Pepe Le Pew"&lt;/span&gt;,
    &lt;span class="str"&gt;"Penelope"&lt;/span&gt;,
    &lt;span class="str"&gt;"Porky Pig"&lt;/span&gt;,
    &lt;span class="str"&gt;"Elmer Fudd"&lt;/span&gt;,
]

s = &lt;span class="str"&gt;"{ room : '%(room)s', name : '%(name)s', phone : '1-800-555-0%(room)s', email : '%(email)s' }"&lt;/span&gt;

makedata(n, 100, s)
&lt;/pre&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This sample demonstrates the simplest case with static data and a very simple building map with a small number of occupants. Part of the challenge I had when I first analyzed the Adobe Visual Building Search sample was the complexity and questionable coding. Hopefully this sample is much simpler.&lt;/p&gt;
&lt;p&gt;Part of the challenge in developing for the web is the differences in the browsers -- occasionally it is because one browser will let you get away with something you shouldn't be able to do. That was the case with this example -- I spent a little extra time making it work with FireFox. The eventing model and JavaScript was a little less forgiving in FireFox than IE.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3A//www.nimblecoder.com/blog/archive/2007/12/06/svg-building-map-part-1.aspx"&gt;&lt;img alt="kick it" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A//www.nimblecoder.com/blog/archive/2007/12/06/svg-building-map-part-1.aspx" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:83e6fb6c-f3e2-4fa1-b1fd-e4ba04553b75" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/svg" rel="tag"&gt;svg&lt;/a&gt;, &lt;a href="http://technorati.com/tags/javascript" rel="tag"&gt;javascript&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/54.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid>http://nimblecoder.com/blog/archive/2007/12/06/svg-building-map-part-1.aspx</guid>
            <pubDate>Fri, 07 Dec 2007 05:33:04 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/54.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2007/12/06/svg-building-map-part-1.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/54.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/54.aspx</trackback:ping>
        </item>
        <item>
            <title>Best Practice for Verbatim String Text Block</title>
            <link>http://nimblecoder.com/blog/archive/2007/11/23/best-practice-for-verbatim-string-text-block.aspx</link>
            <description>&lt;p&gt;I was browsing various blogs today and I came across a good example for using a verbatim string instead of a StringBuilder object. The code I came across looked like this (I mean absolutely no disrespect to the author, so I won't include the original link):&lt;/p&gt;&lt;pre class="c#" name="code"&gt;private void ClientScript()
{
   StringBuilder sb_Script = new StringBuilder();
   sb_Script.Append("&amp;lt;script language=\"javascript\"&amp;gt;");
   sb_Script.Append("\r");
   sb_Script.Append("\r");
   sb_Script.Append("function cb_verify(sender) {");
   sb_Script.Append("\r");
   sb_Script.Append("var val = document.getElementById(document.getElementById"
			+"(sender.id).controltovalidate);");
   sb_Script.Append("\r");
   sb_Script.Append("var col = val.getElementsByTagName(\"*\");");
   sb_Script.Append("\r");
   sb_Script.Append("if ( col != null ) {");
   sb_Script.Append("\r");
   sb_Script.Append("for ( i = 0; i &amp;lt; col.length; i++ ) {");
   sb_Script.Append("\r");
   sb_Script.Append("if (col.item(i).tagName == \"INPUT\") {");
   sb_Script.Append("\r");
   sb_Script.Append("if ( col.item(i).checked ) {");
   sb_Script.Append("\r");
   sb_Script.Append("\r");
   sb_Script.Append("return true;");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("\r");
   sb_Script.Append("\r");
   sb_Script.Append("return false;");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("&amp;lt;/script&amp;gt;");

   //Inject the script into the page

   Page.ClientScript.RegisterClientScriptBlock(GetType(), SCRIPTBLOCK,
					sb_Script.ToString());
   //Registering validator clientside javascript function
   Page.ClientScript.RegisterExpandoAttribute(ClientID, "evaluationfunction",
					"cb_verify");
}
&lt;/pre&gt;
&lt;p&gt;There are many articles on the performance of string concatenation compared to StringBuilder, but this is an example where the verbatim string is significantly better in terms of performance and maintenance. The modified code with the verbatim string looks like this:&lt;/p&gt;&lt;pre class="c#" name="code"&gt;private void ClientScript()
{
   string sb_Script = @"
&amp;lt;script language=""javascript""&amp;gt;
function cb_verify(sender) {
   var val = document.getElementById(document.getElementById(sender.id).controltovalidate);
   var col = val.getElementsByTagName(""*"");
   if ( col != null ) {
       for ( i = 0; i &amp;lt; col.length; i++ ) {
           if (col.item(i).tagName == ""INPUT"") {
               if ( col.item(i).checked ) {
                   return true;
               }
           }
       }
       return false;
    }
}
&amp;lt;/script&amp;gt;";

   //Inject the script into the page
   Page.ClientScript.RegisterClientScriptBlock(GetType(), SCRIPTBLOCK,
                    sb_Script);
   //Registering validator clientside javascript function
   Page.ClientScript.RegisterExpandoAttribute(ClientID, "evaluationfunction",
                    "cb_verify");
}
&lt;/pre&gt;
&lt;p&gt;The indentation is optional if you wish to &lt;a href="http://javascript.crockford.com/jsmin.html" target="_blank"&gt;minimize the javascript&lt;/a&gt;, but the end result is code that is easier to maintain. (I'm still evaluating the &lt;a href="http://code.google.com/p/syntaxhighlighter/" target="_blank"&gt;dp.SyntaxHighlighter&lt;/a&gt; and I see it has an issue with the verbatim string markup.)&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:472d6560-f12e-4bdb-a9b2-03618cba6216" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/c#" rel="tag"&gt;c#&lt;/a&gt;, &lt;a href="http://technorati.com/tags/javascript" rel="tag"&gt;javascript&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/50.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid>http://nimblecoder.com/blog/archive/2007/11/23/best-practice-for-verbatim-string-text-block.aspx</guid>
            <pubDate>Fri, 23 Nov 2007 06:05:51 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/50.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2007/11/23/best-practice-for-verbatim-string-text-block.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/50.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/50.aspx</trackback:ping>
        </item>
        <item>
            <title>Using dpSyntaxHighlighter in Subtext</title>
            <link>http://nimblecoder.com/blog/archive/2007/11/16/using-dpsyntaxhighlighter-in-subtext.aspx</link>
            <description>&lt;p&gt;I finally worked on my blog theme last night and I managed to get the &lt;a href="http://code.google.com/p/syntaxhighlighter/" target="_blank"&gt;dp.SyntaxHighlighter&lt;/a&gt; to work with &lt;a href="http://subtextproject.com/" target="_blank"&gt;Subtext&lt;/a&gt;. I recall seeing someone else use it with Subtext, but I can't locate the blog anymore.&lt;/p&gt; &lt;p&gt;Here are the steps involved:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Create a custom skin for Subtext  &lt;/li&gt;&lt;li&gt;Copy the shCore.js, shBrushCSharp.js, shBrushXxx.js files in the custom skin Scripts directory (~/Skins/YourCustomSkin/Controls)  &lt;/li&gt;&lt;li&gt;Copy the SyntaxHighlighter.css file to the custom skin Styles directory (~/Skins/YourCustomSkin/Styles). If you choose to use the Flash clipboard.swf functionality, place it in the root Scripts directory.  &lt;/li&gt;&lt;li&gt;Create a Skins.User.config file in the ~/Admin directory. Add the following styles:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;SkinTemplates
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
&amp;gt;
  &amp;lt;Skins&amp;gt;
    &amp;lt;SkinTemplate Name="YourCustomSkin"
      TemplateFolder="YourCustomSkin"&amp;gt;
      &amp;lt;Styles&amp;gt;
        &amp;lt;!-- Use an existing skin for a template
          to include a "normal" set of files. In
          this example, I only listed the one
          required style. --&amp;gt;
        &amp;lt;Style href="Styles/SyntaxHighlighter.css" media="all" /&amp;gt;
      &amp;lt;/Styles&amp;gt;
      &amp;lt;Scripts&amp;gt;
        &amp;lt;!-- Same as above. This is only a partial list
          of scripts, and a partial list of the highlighting
          files. There are more styles to include if you
          desire. --&amp;gt;
        &amp;lt;Script Src="Scripts/shCore.js" /&amp;gt;
        &amp;lt;Script Src="Scripts/shBrushCpp.js" /&amp;gt;
        &amp;lt;Script Src="Scripts/shBrushCSharp.js" /&amp;gt;
        &amp;lt;Script Src="Scripts/shBrushJScript.js" /&amp;gt;
        &amp;lt;Script Src="Scripts/shBrushPython.js" /&amp;gt;
        &amp;lt;Script Src="Scripts/shBrushSql.js" /&amp;gt;
        &amp;lt;Script Src="Scripts/shBrushVb.js" /&amp;gt;
        &amp;lt;Script Src="Scripts/shBrushXml.js" /&amp;gt;
      &amp;lt;/Scripts&amp;gt;
    &amp;lt;/SkinTemplate&amp;gt;
  &amp;lt;/Skins&amp;gt;
&amp;lt;/SkinTemplates&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;Modify the custom skin PageTemplate.ascx file to include the following code:&lt;br /&gt;&lt;pre name="code" class="js"&gt;&amp;lt;yourskin:Footer id="Footer" runat="server" /&amp;gt;
&amp;lt;script type="text/javascript"&amp;gt;
  init();
  addLoadEvent(
    function() {
      dp.SyntaxHighlighter.ClipboardSwf = subtextBlogInfo.getScriptsVirtualRoot() + 'clipboard.swf';
      dp.SyntaxHighlighter.HighlightAll('code');
    });
&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;At this point you are ready to use the highlighter. Just to test, here is a little JavaScript:&lt;/p&gt;&lt;pre class="js" name="code"&gt;// Append a new element to an existing element.
// Build the attributes from the attrs object.
function appendElem(elem, value, newNodeType, attrs)
{
  var t = document.createTextNode(value);
  if (newNodeType) {
    if (attrs &amp;amp;&amp;amp; ("name" in attrs))
      newNodeType = "&amp;lt;" + newNodeType + " name='" + attrs["name"] + "'&amp;gt;";
    var n = document.createElement(newNodeType);
    if (attrs)
    {
      for (var attr in attrs)
      {
        var value = attrs[attr];
        if (attr == "class")
          n.className = value;
        else
          n.setAttribute(attr, value);
      }
    }
    n.appendChild(t);
    t = n;
  }
  elem.appendChild(t);
  return elem;
}

var elem = $("some-id"); // need prototype/jQuery...
appendElem(elem, "Testing", "textarea", {'class':'js', name:'code', cols:'40', rows:'5'});

&lt;/pre&gt;
&lt;p&gt;Hopefully this will still work with RSS feeds and readers, otherwise I may be going back to the old method pasting code. &lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:c182bcfe-4302-4b40-bfa3-450100fa4ea8" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/Subtext" rel="tag"&gt;Subtext&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/48.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid>http://nimblecoder.com/blog/archive/2007/11/16/using-dpsyntaxhighlighter-in-subtext.aspx</guid>
            <pubDate>Fri, 16 Nov 2007 18:00:00 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/48.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2007/11/16/using-dpsyntaxhighlighter-in-subtext.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/48.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/48.aspx</trackback:ping>
        </item>
        <item>
            <title>Throw Away Knowledge</title>
            <link>http://nimblecoder.com/blog/archive/2007/11/13/throw-away-knowledge.aspx</link>
            <description>&lt;p&gt;I have spent the past hour trying to modify a VBScript / JavaScript utility to print out my password expiration date and it is driving me a little crazy. I cannot understand why something that should be so simple can be so blasted difficult. I have several account at client sites and the password expires periodically. In order to make sure I don't let the account lapse, I wanted to print the password expiration date. I had a version that worked before but the distinguishedName had to be exact. I used the &lt;a href="http://www.joeware.net/freetools/tools/adfind/index.htm" target="_blank"&gt;adfind&lt;/a&gt; utility to figure out my distinguished name and put it in the script. Today I wanted to remove that limitation but it is proving to be a big waste of time. Every attempt to make this work with either VBScript or JavaScript has been thwarted with malice.&lt;/p&gt; &lt;p&gt;Of couse that doesn't stop me from trying -- oh no! Merely a &lt;a href="http://en.wikipedia.org/wiki/Monty_Python_and_the_Holy_Grail" target="_blank"&gt;flesh wound&lt;/a&gt;. As a programmer determined to make things work, it will bug me until it actually does work! There is silliness involved such as this code to convert an Integer64 to a useable native data type in VBScript:&lt;/p&gt;&lt;pre class="csharpcode"&gt;numDays = CCur((maxPwdAge.HighPart * 2 ^ 32) + _
                maxPwdAge.LowPart) / CCur(-864000000000)

whenPasswordExpires = DateAdd(&lt;span class="str"&gt;"d"&lt;/span&gt;, numDays, oUser.PasswordLastChanged)
&lt;/pre&gt;
&lt;p&gt;JavaScript doesn't have the CCur function so I have to use an alternative (and talk about silly -- using a currency data type to do this!). With both VBScript and JavaScript, I am having trouble searching Active Directory with a query or filter. At this point, I may use C# script where I have full .NET power.&lt;/p&gt;
&lt;p&gt;&lt;a title="C by Dissection" href="http://www.flickr.com/photos/14402141@N00/2006820976/"&gt;&lt;img alt="C by Dissection" src="http://static.flickr.com/2099/2006820976_4758b8d2b4_m.jpg" align="left" border="0" /&gt;&lt;/a&gt;This brings me to the point of this entry. Much of the programming technologies in use are destined for a short lifetime. It is an utter waste to invest time, money, and effort to build complex solutions against technologies and frameworks that will be replaced in two years. It is the dilemma that we find ourselves in though, and sometimes there is no or little choice.&lt;/p&gt;
&lt;p&gt;As I write this entry I am looking at the waste land of books including my original C programming textbook from university, a ancient graphics programming book that describes "&lt;a href="http://en.wikipedia.org/wiki/Mode_X" target="_blank"&gt;Mode X&lt;/a&gt;", some COM and ATL books, and tucked away somewhere I have the Petzold Win95 book and Prosise MFC Win95 book. Then I start thinking about &lt;a href="http://en.wikipedia.org/wiki/Lvalue" target="_blank"&gt;l-values and r-values&lt;/a&gt;, some of the ridiculous MFC hacks I've had to make in the past and I'm glad I don't have to deal with that much anymore. Things have improved especially in the area of dynamic or scripting languages where the power of these languages allow the programmer to accomplish a significant amount of work with less effort. One of the benefits is that is almost forces other languages to add features and streamline for greater efficiency. Unfortunately it is a slow process but I do see progress.&lt;/p&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/46.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid>http://nimblecoder.com/blog/archive/2007/11/13/throw-away-knowledge.aspx</guid>
            <pubDate>Tue, 13 Nov 2007 21:59:16 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/46.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2007/11/13/throw-away-knowledge.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/46.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/46.aspx</trackback:ping>
        </item>
        <item>
            <title>Formatting Exponentials in Javascript</title>
            <link>http://nimblecoder.com/blog/archive/2007/03/01/Formatting-Exponentials-in-Javascript.aspx</link>
            <description>	&lt;p&gt;
		A while back I needed the dashboard for the &lt;a href="http://en.wikipedia.org/wiki/Key_performance_indicators"&gt;
			Key Performance Indicators&lt;/a&gt; (KPI) to display nicely formatted numbers. When
		the KPI values started to get large (millions, billions, etc.) the numbers became
		almost unreadable. In order to simplify the display of the numbers, I ended up converting
		the values to &lt;a href="http://en.wikipedia.org/wiki/Scientific_notation"&gt;scientific
			notation&lt;/a&gt;. However in order to make the numbers even more readable, I converted
		the scientific notation into powers of 10&lt;sup&gt;3&lt;/sup&gt;. I converted the floating
		point number into a string that was still a valid floating point number, but it
		used the exponential notation such as 1.0e6. I then used a regular expression to
		convert the exponent into HTML that the As a general practice, I would also put
		the raw formatted floating point number in the tooltip for the display. The function
		that actually performs the scientific notation grouping and conversion is toTrioExponential().&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// Formats the value as an exponential as a multiple of 3&lt;/span&gt;
&lt;span class="rem"&gt;// NOTE: The result is a string that is still	a valid floating point number&lt;/span&gt;
&lt;span class="kwrd"&gt;function&lt;/span&gt; toTrioExponential(value, fixedDigits)
{
    var mag = &lt;span class="kwrd"&gt;parseInt&lt;/span&gt;(Math.log(Math.abs(value) / Math.LN10);
    var rem = mag % 3;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (rem == 2)
        ++mag;
    &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; ((rem == 1) || (rem == -2))
        --mag;
    &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (rem == -1)
        mag -= 2;
    var coeff = &lt;span class="kwrd"&gt;value&lt;/span&gt; * Math.pow(10, -mag);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (fixedDigits)
        &lt;span class="kwrd"&gt;return&lt;/span&gt; coeff.toFixed(fixedDigits) + &lt;span class="str"&gt;"e"&lt;/span&gt; + mag.toString();
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; coeff.toString() + &lt;span class="str"&gt;"e"&lt;/span&gt; + mag.toString();
};&lt;/pre&gt;
	&lt;p&gt;
		The script supports changing the scaling criteria. Just modify the &lt;span style="font-family: Courier New,Fixed;"&gt;
			sciNot.scaleDigits&lt;/span&gt; and &lt;span style="font-family: Courier New,Fixed;"&gt;sciNot.scaleThreshold&lt;/span&gt;
		or supply the parameters to the function &lt;span style="font-family: Courier New,Fixed;"&gt;
			sciNot.floatAutoScale(elem, floatValue, scaleThreshold, scaleDigits);&lt;/span&gt;.
		The scaleThreshold and scaleDigits parameters are normally optional. To test the
		script, here is sample output using the default scaling parameters.&lt;/p&gt;
	&lt;table&gt;
		&lt;colgroup&gt;
			&lt;col span="3" style="text-align: right;" /&gt;
		&lt;/colgroup&gt;
		&lt;tbody&gt;
			&lt;tr&gt;
				&lt;th&gt;
					Raw number&lt;/th&gt;
				&lt;th&gt;
					Trio Sci Not&lt;/th&gt;
				&lt;th&gt;
					Formatted&lt;/th&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					1000000&lt;/td&gt;
				&lt;td&gt;
					1,000,000.00&lt;/td&gt;
				&lt;td title="1,000,000.00"&gt;
					1,000,000.00&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					10000000&lt;/td&gt;
				&lt;td&gt;
					10,000,000.00&lt;/td&gt;
				&lt;td title="10,000,000.00"&gt;
					10,000,000.00&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					100000000&lt;/td&gt;
				&lt;td&gt;
					100,000,000.00&lt;/td&gt;
				&lt;td title="100,000,000.00"&gt;
					100,000,000.00&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					1000000000&lt;/td&gt;
				&lt;td&gt;
					1,000,000,000.00&lt;/td&gt;
				&lt;td title="1,000,000,000.00"&gt;
					1,000,000,000.00&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					10000000000&lt;/td&gt;
				&lt;td&gt;
					10,000,000,000.00&lt;/td&gt;
				&lt;td title="10,000,000,000.00"&gt;
					10,000,000,000.00&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					100000000000&lt;/td&gt;
				&lt;td&gt;
					0.10e12&lt;/td&gt;
				&lt;td title="100,000,000,000.00"&gt;
					0.10 &lt;span style="font-size: smaller; vertical-align: middle;"&gt; x &lt;/span&gt;10&lt;span style="font-size: smaller; vertical-align: top;"&gt; 12&lt;/span&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					1000000000000&lt;/td&gt;
				&lt;td&gt;
					1.00e12&lt;/td&gt;
				&lt;td title="1,000,000,000,000.00"&gt;
					1.00 &lt;span style="font-size: smaller; vertical-align: middle;"&gt; x &lt;/span&gt;10&lt;span style="font-size: smaller; vertical-align: top;"&gt; 12&lt;/span&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					10000000000000&lt;/td&gt;
				&lt;td&gt;
					10.00e12&lt;/td&gt;
				&lt;td title="10,000,000,000,000.00"&gt;
					10.00 &lt;span style="font-size: smaller; vertical-align: middle;"&gt; x &lt;/span&gt;10&lt;span style="font-size: smaller; vertical-align: top;"&gt; 12&lt;/span&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					100000000000000&lt;/td&gt;
				&lt;td&gt;
					0.10e15&lt;/td&gt;
				&lt;td title="100,000,000,000,000.00"&gt;
					0.10 &lt;span style="font-size: smaller; vertical-align: middle;"&gt; x &lt;/span&gt;10&lt;span style="font-size: smaller; vertical-align: top;"&gt; 15&lt;/span&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					1000000000000000&lt;/td&gt;
				&lt;td&gt;
					1e15&lt;/td&gt;
				&lt;td title="1,000,000,000,000,000.00"&gt;
					1.00 &lt;span style="font-size: smaller; vertical-align: middle;"&gt; x &lt;/span&gt;10&lt;span style="font-size: smaller; vertical-align: top;"&gt; 15&lt;/span&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/tbody&gt;
	&lt;/table&gt;
	&lt;p&gt;
		Here is the javascript source for &lt;a href="http://www.nimblecoder.com/blog/images/nimblecoder_com/blog/ScientificNotation.zip"&gt;
			ScientificNotation&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://nimblecoder.com/blog/aggbug/13.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid>http://nimblecoder.com/blog/archive/2007/03/01/Formatting-Exponentials-in-Javascript.aspx</guid>
            <pubDate>Thu, 01 Mar 2007 18:54:12 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/13.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2007/03/01/Formatting-Exponentials-in-Javascript.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/13.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/13.aspx</trackback:ping>
        </item>
        <item>
            <title>Convert date to UTC format in JavaScript</title>
            <link>http://nimblecoder.com/blog/archive/2007/01/23/Convert-date-to-UTC-format-in-JavaScript.aspx</link>
            <description>A couple of years ago I had to print dates in JavaScript in UTC (ISO-8601) format. Here is the function that I developed. It assumes the date object has the correct time zone offset and uses the time zone offset from the object.&lt;br /&gt;
I also developed server-side C# code for formatting dates in ASP.NET pages which I'll post soon.
&lt;textarea cols="60" rows="20" class="JScript" name="code"&gt;function pad(value, digits, padtext)
{
	if (!padtext) padtext = "00000000";
	if ((digits == null) || (typeof(digits) == "undefined")) return value;
	if ((value == null) || (typeof(value) == "undefined")) return value;
	var length = value.toString().length;
	if ((length &amp;lt; digits) &amp;amp;&amp;amp; (digits &amp;lt; padtext.length))
		return padtext.substr(0, digits - length) + value.toString();
	else
		return value;
}

function toUTCDateTime(date)
{
	var tz = date.getTimezoneOffset();
	var offset = ((tz &amp;lt;= 0) ? "+" : "-");
	tz = Math.abs(tz);
	offset += pad(Math.floor(tz / 60), 2) + ":" + pad(tz % 60, 2);

	var result = date.getFullYear() + "-" +
		pad(date.getMonth() + 1, 2) + "-" +
		pad(date.getDate(), 2) + "T" +
		pad(date.getHours(), 2) + ":" +
		pad(date.getMinutes(), 2) + ":" +
		pad(date.getSeconds(), 2) + "." +
		pad(date.getMilliseconds(), 3) +
		offset;

	return result;
}&lt;/textarea&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/5.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid>http://nimblecoder.com/blog/archive/2007/01/23/Convert-date-to-UTC-format-in-JavaScript.aspx</guid>
            <pubDate>Tue, 23 Jan 2007 16:45:07 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/5.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2007/01/23/Convert-date-to-UTC-format-in-JavaScript.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/5.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/5.aspx</trackback:ping>
        </item>
    </channel>
</rss>