<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>DevelopMENTAL Madness</title>
        <link>http://www.developmentalmadness.com/Default.aspx</link>
        <description>The musings, frustrations and epiphanies of a common web programmer.</description>
        <language>en-US</language>
        <copyright>Mark J. Miller</copyright>
        <generator>Subtext Version 2.1.2.2</generator>
        <image><link>http://creativecommons.org/licenses/by-nc-nd/2.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/DevelopmentalMadness" /><feedburner:info uri="developmentalmadness" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>40.988347</geo:lat><geo:long>-111.888476</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/</creativeCommons:license><item>
            <title>Java: using BigDecimal instead of double</title>
            <link>http://feedproxy.google.com/~r/DevelopmentalMadness/~3/9TwlohoBk-0/java-using-bigdecimal-instead-of-double.aspx</link>
            <description>&lt;p&gt;For the last two months I've been using Linux and Java exclusively. For the times I still need to do .NET development, my laptop is setup to dual-boot into Windows 7. But since I'm learning a lot, I really want to try and catalog my experience of transitioning from Windows/.NET developer to Linux/Java developer.&lt;/p&gt;&lt;p&gt;Am I giving up on .NET and Windows? No, but because I've been moved to a Java project deployed on Linux I decided to jump in with both feet. I'm enjoying how much I'm learning and hopefully as I get back in the habit of blogging, I'll include stuff I'm doing with .NET as well.&lt;/p&gt;&lt;p&gt;However, I first started playing with .NET during it's beta stage and have been using it on a daily basis since v1.1. So, at least for the time being, I'm likely to include comparisons with .NET when I post about Java in as much as I see it will benefit .NET developers who are making the same transition I am. Who knows, maybe my perspective will also be interesting to some Java developers as well.&lt;/p&gt;&lt;h2&gt;Primitive Java Types&lt;/h2&gt;&lt;p&gt;I've been working on a test harness that publishes rates and at the moment all it does is publish a rate and check to see if the same value comes out the other end. I have a instance of a log4j Logger that I'm using to output debug info to the console as I develop this and I was noticing that when I would add two doubles together the results were imprecise. For example, the following:&lt;/p&gt;&lt;p&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: Consolas, "Courier New", Courier, Monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } --&gt;&lt;/p&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;
&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; doubleOutput(){
&lt;/pre&gt;&lt;pre&gt;
        &lt;span class="kwrd"&gt;double&lt;/span&gt; rate = 1.37000;
&lt;/pre&gt;&lt;pre class="alt"&gt;
        &lt;span class="kwrd"&gt;double&lt;/span&gt; adjustment = 0.00001;
&lt;/pre&gt;&lt;pre class="alt"&gt;
        &lt;span class="kwrd"&gt;try&lt;/span&gt; {
&lt;/pre&gt;&lt;pre&gt;
            &lt;span class="kwrd"&gt;while&lt;/span&gt;(System.&lt;span class="kwrd"&gt;in&lt;/span&gt;.available() == 0){
&lt;/pre&gt;&lt;pre class="alt"&gt;
                rate += adjustment;
&lt;/pre&gt;&lt;pre&gt;
                log.debug(&lt;span class="str"&gt;"The new rate is: "&lt;/span&gt; + rate);
&lt;/pre&gt;&lt;pre class="alt"&gt;
                pause(500);
&lt;/pre&gt;&lt;pre&gt;
            }
&lt;/pre&gt;&lt;pre class="alt"&gt;
        } &lt;span class="kwrd"&gt;catch&lt;/span&gt; (IOException e) {
&lt;/pre&gt;&lt;pre&gt;
            log.error(&lt;span class="str"&gt;"IOException: "&lt;/span&gt; + e);
&lt;/pre&gt;&lt;pre class="alt"&gt;
        }
&lt;/pre&gt;&lt;pre&gt;
    }
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;would give the these results:&lt;/p&gt;&lt;p&gt;2011-06-01 10:56:42,011 DEBUG [Main] The new rate is: 1.3700100000000002&lt;br /&gt;2011-06-01 10:56:42,512 DEBUG [Main] The new rate is: 1.3700200000000002&lt;br /&gt;2011-06-01 10:56:43,012 DEBUG [Main] The new rate is: 1.3700300000000003&lt;br /&gt;2011-06-01 10:56:43,513 DEBUG [Main] The new rate is: 1.3700400000000004&lt;br /&gt;2011-06-01 10:56:44,013 DEBUG [Main] The new rate is: 1.3700500000000004&lt;/p&gt;&lt;p&gt;It's been a while since I've really looked into the issue. In .NET the de facto standard for monetary calculations is the decimal type (System.Decimal). System.Float and System.Double are binary floating types and will result in rounding errors. So in this sense, Java is the same: the double types on both platforms are binary floating types implemented according to the IEEE 754 standard.&lt;/p&gt;&lt;p&gt;So what is the equivalent of System.Decimal in Java?&lt;/p&gt;&lt;h2&gt;BigDecimal&lt;/h2&gt;&lt;p&gt;The Java equivalent of System.Decimal is java.math.BigDecimal. Here's the equivalent of the above method, using BigDecimal:&lt;/p&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;
&lt;span class="kwrd"&gt; private&lt;/span&gt;  &lt;span class="kwrd"&gt; void&lt;/span&gt;  roundingTests(){
&lt;/pre&gt;&lt;pre&gt;
        BigDecimal rate = &lt;span class="kwrd"&gt;new&lt;/span&gt; BigDecimal(&lt;span class="str"&gt;"1.37000"&lt;/span&gt;);
&lt;/pre&gt;&lt;pre class="alt"&gt;
        BigDecimal adjustment = &lt;span class="kwrd"&gt;new&lt;/span&gt; BigDecimal(&lt;span class="str"&gt;"0.00001"&lt;/span&gt;);
&lt;/pre&gt;&lt;pre class="alt"&gt;
        &lt;span class="kwrd"&gt;try&lt;/span&gt; {
&lt;/pre&gt;&lt;pre&gt;
            &lt;span class="kwrd"&gt;while&lt;/span&gt;(System.&lt;span class="kwrd"&gt;in&lt;/span&gt;.available() == 0){
&lt;/pre&gt;&lt;pre class="alt"&gt;
                rate = rate.add(adjustment);
&lt;/pre&gt;&lt;pre&gt;
                log.debug(&lt;span class="str"&gt;"The new rate is: "&lt;/span&gt; + rate.doubleValue());
&lt;/pre&gt;&lt;pre class="alt"&gt;
                pause(500);
&lt;/pre&gt;&lt;pre&gt;
            }
&lt;/pre&gt;&lt;pre class="alt"&gt;
        } &lt;span class="kwrd"&gt; catch&lt;/span&gt;  (IOException e) {
&lt;/pre&gt;&lt;pre&gt;
            log.error(&lt;span class="str"&gt; "IOException: "&lt;/span&gt;  + e);
&lt;/pre&gt;&lt;pre class="alt"&gt;
        }
&lt;/pre&gt;&lt;pre&gt;
    }
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which will give you this output:&lt;/p&gt;&lt;p&gt;2011-06-01 11:19:24,715 DEBUG [Main] The new rate is: 1.37001&lt;br /&gt;2011-06-01 11:19:25,216 DEBUG [Main] The new rate is: 1.37002&lt;br /&gt;2011-06-01 11:19:25,716 DEBUG [Main] The new rate is: 1.37003&lt;br /&gt;2011-06-01 11:19:26,217 DEBUG [Main] The new rate is: 1.37004&lt;/p&gt;&lt;p&gt;This is more what I was expecting. However, BigDecimal has some important differences with System.Decimal. First of all, and what took me the longest to catch on to, is that BigDecimal is immutable. Just like System.String in .NET. So how does this affect you? Look at the first line inside the loop above. What do you notice? Instead of using the standard addition operator, there's an "add" method. Also, I'm assigning the result back to the "rate" variable, just like if I were doing string manipulations.&lt;/p&gt;&lt;p&gt;If you modify the above sample and remove the assignment, and leave just the "add" operation the result you'll see in the console is that the rate is always "1.37000".&lt;/p&gt;&lt;p&gt;The second thing to note is the constructor. Notice how I am passing in a string representation of the values 1.37000 and 0.0001. The reason is (I'm pretty sure about this) because if I were to pass in the values without the quotes I would be passing in double values and my results would be as follows:&lt;/p&gt;&lt;p&gt;2011-06-01 11:26:20,639 DEBUG [Main] The new rate is: 1.3700100000000002&lt;br /&gt;2011-06-01 11:26:21,141 DEBUG [Main] The new rate is: 1.37002&lt;br /&gt;2011-06-01 11:26:21,641 DEBUG [Main] The new rate is: 1.37003&lt;br /&gt;2011-06-01 11:26:22,142 DEBUG [Main] The new rate is: 1.3700400000000001&lt;br /&gt;2011-06-01 11:26:22,642 DEBUG [Main] The new rate is: 1.3700500000000002&lt;/p&gt;&lt;p&gt;All of a sudden I'm back to my original problem. So I pass in my string representation to prevent my values from behaving like binary floating types.&lt;/p&gt;&lt;h2&gt;Performance and Accuracy&lt;/h2&gt;&lt;p&gt;A note about performance. Something I didn't know about System.Decimal (or at least it never occurred to me) was that it is an 128 bit value, capable of storing up to 29 significant digits. System.Double is 64 bits. java.lang.BigDecimal however is represented internally as an array of integers (java.lang.BigInteger) which has no size limit. So the size of it depends upon how large the number is. My assumption is that this also applies to accuracy such that there is no limit on the number of significant digits. I had been wondering why there was just BigDecimal and no Decimal class, my guess is that because it uses BigInteger internally and it really can be BIG, it makes sense to call it BigDecimal and with that, there's really no need for just Decimal since not only can it be really big, but it will also contract (I'm not saying it actually trims the internal array, just that smaller values will result in less memory consumption) for smaller values.&lt;/p&gt;&lt;p&gt;Either way there are implications on performance due to the implementations. If performance is really a concern then there are alternatives, but for most applications BigDecimal (and System.Decimal) should be just fine.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update 6/2/11: &lt;/strong&gt;Looking around some more today I noticed that if you don't want to use BigDecimal if you're just passing values around, but want to use it just when you're doing calculations you can use the static method BigDecimal.valueOf(double); According to javadocs this is the equivelent of new BigDecimal(Double.toString(double)); Either way, as far as I can tell you can do this without running into rounding errors. If you're still worried about possible rounding errors you can use the BigDecimal instance method setScale which allows you to set the scale you want and optionally the RoundingMode. So when doing calculations your API can use "double" while you can use BigDecimal internally. In .NET you could do the same using the explicit IConvertable.ToDecimal(IFormatProvider) on an instace of System.Double (ex: ((IConvertable)rate).ToDecimal(null); ) and the static Decimal.ToDouble(Decimal) to convert back and forth between Double and Decimal.&lt;/p&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;p&gt;For more information on System.Decimal see: &lt;a href="http://csharpindepth.com/Articles/General/Decimal.aspx"&gt;http://csharpindepth.com/Articles/General/Decimal.aspx&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/system.decimal.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.decimal.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;For more information on java.math.BigDecimal see: &lt;a href="http://firstclassthoughts.co.uk/java/traps/big_decimal_traps.html"&gt;http://firstclassthoughts.co.uk/java/traps/big_decimal_traps.html&lt;/a&gt;, &lt;a href="http://download.oracle.com/javase/1.4.2/docs/api/java/math/BigInteger.html"&gt;http://download.oracle.com/javase/1.4.2/docs/api/java/math/BigInteger.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;tags: &lt;a rel="tag" href="http://www.developmentalmadness.com/tags/Java/default.aspx"&gt;Java&lt;/a&gt;, &lt;a rel="tag" href="http://www.developmentalmadness.com/tags/Types/default.aspx"&gt;Types&lt;/a&gt;, &lt;a rel="tag" href="http://www.developmentalmadness.com/tags/BigDecimal/default.aspx"&gt;BigDecimal&lt;/a&gt;, &lt;a rel="tag" href="http://www.developmentalmadness.com/tags/Lost in Translation/default.aspx"&gt;Lost in Translation&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.developmentalmadness.com/aggbug/118.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=9TwlohoBk-0:FNUlDbMAAWY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=9TwlohoBk-0:FNUlDbMAAWY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?i=9TwlohoBk-0:FNUlDbMAAWY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=9TwlohoBk-0:FNUlDbMAAWY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=9TwlohoBk-0:FNUlDbMAAWY:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=9TwlohoBk-0:FNUlDbMAAWY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?i=9TwlohoBk-0:FNUlDbMAAWY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=9TwlohoBk-0:FNUlDbMAAWY:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=9TwlohoBk-0:FNUlDbMAAWY:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentalMadness/~4/9TwlohoBk-0" height="1" width="1"/&gt;</description>
            <dc:creator>Mark J. Miller</dc:creator>
            <guid isPermaLink="false">http://www.developmentalmadness.com/archive/2011/06/01/java-using-bigdecimal-instead-of-double.aspx</guid>
            <pubDate>Wed, 01 Jun 2011 18:12:24 GMT</pubDate>
            <comments>http://www.developmentalmadness.com/archive/2011/06/01/java-using-bigdecimal-instead-of-double.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://www.developmentalmadness.com/comments/commentRss/118.aspx</wfw:commentRss>
            <trackback:ping>http://www.developmentalmadness.com/services/trackbacks/118.aspx</trackback:ping>
        <feedburner:origLink>http://www.developmentalmadness.com/archive/2011/06/01/java-using-bigdecimal-instead-of-double.aspx</feedburner:origLink></item>
        <item>
            <title>jQuery: Highlight table elements when a cell is clicked</title>
            <category>JavaScript</category>
            <link>http://feedproxy.google.com/~r/DevelopmentalMadness/~3/kSOD054DxfM/jquery-highlight-table-elements-when-a-cell-is-clicked.aspx</link>
            <description>&lt;p&gt;In a recent interview I was given an assignment to be completed before the phone interview. The assignment was to highlight the appropriate cell, column and row elements in an HTML table when the table cell was clicked. I was allowed to use any JavaScript framework I wanted. The result was expected to look exactly like this when a cell was clicked:&lt;/p&gt;  &lt;p&gt;&lt;a href="/SampleCode/jQuery/cell-row-column-highlighting.aspx" target="_blank"&gt;Working demo&lt;/a&gt;&lt;/p&gt;  &lt;table style="width: 800px" id="browsers" border="0" cellspacing="0" cellpadding="0"&gt;&lt;thead&gt;     &lt;tr&gt;       &lt;th&gt;Rendering engine&lt;/th&gt;        &lt;th&gt;Browser&lt;/th&gt;        &lt;th&gt;Platform(s)&lt;/th&gt;        &lt;th&gt;Engine version&lt;/th&gt;        &lt;th&gt;CSS grade&lt;/th&gt;     &lt;/tr&gt;   &lt;/thead&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;Gecko&lt;/td&gt;        &lt;td style="background-color: orange"&gt;Firefox 1.0&lt;/td&gt;        &lt;td&gt;Win 98+ / OSX.2+&lt;/td&gt;        &lt;td&gt;1.7&lt;/td&gt;        &lt;td&gt;A&lt;/td&gt;     &lt;/tr&gt;      &lt;tr style="background-color: yellow"&gt;       &lt;td&gt;Gecko&lt;/td&gt;        &lt;td style="background-color: red"&gt;Firefox 1.5&lt;/td&gt;        &lt;td&gt;Win 98+ / OSX.2+&lt;/td&gt;        &lt;td&gt;1.8&lt;/td&gt;        &lt;td&gt;A&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Gecko&lt;/td&gt;        &lt;td style="background-color: orange"&gt;Firefox 2.0&lt;/td&gt;        &lt;td&gt;Win 98+ / OSX.2+&lt;/td&gt;        &lt;td&gt;1.8&lt;/td&gt;        &lt;td&gt;A&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Gecko&lt;/td&gt;        &lt;td style="background-color: orange"&gt;Firefox 3.0&lt;/td&gt;        &lt;td&gt;Win 2k+ / OSX.3+&lt;/td&gt;        &lt;td&gt;1.9&lt;/td&gt;        &lt;td&gt;A&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Gecko&lt;/td&gt;        &lt;td style="background-color: orange"&gt;Camino 1.0&lt;/td&gt;        &lt;td&gt;OSX.2+&lt;/td&gt;        &lt;td&gt;1.8&lt;/td&gt;        &lt;td&gt;A&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Those who know me well (as well as those observant enough to notice) know despite the blogging I’ve done on Silverlight/WPF and ASP.NET MVC and my knowledge of the subject matter I really don’t like working much in the UI layer. So much so that I’ve always been more than willing to let those more interested (and capable) to take the reigns and handle as much of the JavaScript code as I could avoid. I’m not saying I can’t write JavaScript, I’m just saying I make sure I can do what I need to get my job done and no more. As a good friend puts it – I’m lazy (about JavaScript anyway). &lt;/p&gt;  &lt;p&gt;Back to the interview assignment. I was open about my JavaScript skills (or limitations thereof) with the interviewer and maybe that’s why the assignment involved JavaScript – they wanted to see where I was at. Well, I was able to get it done in a reasonable amount of time. Also since I was impressed with the result and the interviewer liked it as well, I thought I’d share it here.&lt;/p&gt;  &lt;p&gt;There’s nothing fancy about it, although this was my first ever attempt at extending jQuery, but I like the result. Here’s the code:&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;$(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(){&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    $(&lt;span style="color: #006080"&gt;"td"&lt;/span&gt;).click(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(){&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; cell = $(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; row = cell.parent();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; col = cell.parents(&lt;span style="color: #006080"&gt;"table"&lt;/span&gt;).find(&lt;span style="color: #006080"&gt;"td:nth-child("&lt;/span&gt; + (cell.index() + 1) + &lt;span style="color: #006080"&gt;")"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// make row yellow&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        row.css({backgroundColor: &lt;span style="color: #006080"&gt;"Yellow"&lt;/span&gt;}).resetBackground();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// make column orange&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        col.css({backgroundColor :&lt;span style="color: #006080"&gt;"Orange"&lt;/span&gt;}).resetBackground();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// make cell red&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        cell.css({backgroundColor: &lt;span style="color: #006080"&gt;"Red"&lt;/span&gt;}).resetBackground();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    });&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;});&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;($){&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    $.fn.resetBackground = &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() { &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        $(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;).stop().animate({ backgroundColor : &lt;span style="color: #006080"&gt;"#fff"&lt;/span&gt; }, 1500, &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(){ &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            $(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;).css({ backgroundColor : &lt;span style="color: #006080"&gt;""&lt;/span&gt; }); &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        });&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    };&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;}(jQuery));&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;First, we’re just registering for the ‘click’ event of the ‘td’ element. Then storing references to the cell and row – easy enough. But then the next line took some digging for me to find. ‘Column’ is not an explicit element in an HTML table. Instead, you have a collection of vertically aligned ‘td’ elements (cells). So in order to get a reference to a ‘column’ you need to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Get a reference to the table element – cell.parents(“table”) &lt;/li&gt;

  &lt;li&gt;Get the index of the td element that was clicked – $(this).index() &lt;/li&gt;

  &lt;li&gt;Use the find() method to get the collection of cells with the same index  - td:nth-child(int) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A couple of caveats, the nth-child selector isn’t zero-based, it’s one-based, so you’ll need to increment #2 by a value of 1. Also, this method does not take the ‘colspan’ attribute into account. But other than that you now have a reference to the cell, row and column that were clicked.&lt;/p&gt;

&lt;p&gt;Next, setting the background color is pretty simple using the css() method. But I wanted the demo to be usable – what application would ever just change the color and leave it? What happens when the next cell is clicked? You could reset the whole table, but I thought it would be fun to have the background fade back to white. So using the jQueryUI animate method I set the background color back to white with a timeout of 1500 milliseconds. &lt;/p&gt;

&lt;p&gt;Lastly, once I had this working I found a weird behavior. The cells I had previously clicked remained white the next time a cell in the same row was clicked. The column background continued to work and didn’t behave this way, but because the cell’s background property overrides the background property of the row I had to reset the background-color property of the cell after the animation was complete. So that’s why I added a function to completely clear out the background color property of the cell to the complete parameter of the animate method.&lt;/p&gt;

&lt;p&gt;Mostly, this is for my own benefit but I hope maybe this helps someone else with their jQuery adventures.&lt;/p&gt;



&lt;p&gt;tags: &lt;a href="http://www.developmentalmadness.com/tags/jQuery/default.aspx" rel="tag"&gt;jQuery&lt;/a&gt;, &lt;a href="http://www.developmentalmadness.com/tags/JavaScript/default.aspx" rel="tag"&gt;JavaScript&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.developmentalmadness.com/aggbug/116.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=kSOD054DxfM:T0HyusFt0sw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=kSOD054DxfM:T0HyusFt0sw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?i=kSOD054DxfM:T0HyusFt0sw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=kSOD054DxfM:T0HyusFt0sw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=kSOD054DxfM:T0HyusFt0sw:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=kSOD054DxfM:T0HyusFt0sw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?i=kSOD054DxfM:T0HyusFt0sw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=kSOD054DxfM:T0HyusFt0sw:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=kSOD054DxfM:T0HyusFt0sw:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentalMadness/~4/kSOD054DxfM" height="1" width="1"/&gt;</description>
            <dc:creator>Mark J. Miller</dc:creator>
            <guid isPermaLink="false">http://www.developmentalmadness.com/archive/2011/02/25/jquery-highlight-table-elements-when-a-cell-is-clicked.aspx</guid>
            <pubDate>Fri, 25 Feb 2011 17:46:22 GMT</pubDate>
            <comments>http://www.developmentalmadness.com/archive/2011/02/25/jquery-highlight-table-elements-when-a-cell-is-clicked.aspx#feedback</comments>
            <wfw:commentRss>http://www.developmentalmadness.com/comments/commentRss/116.aspx</wfw:commentRss>
            <trackback:ping>http://www.developmentalmadness.com/services/trackbacks/116.aspx</trackback:ping>
        <feedburner:origLink>http://www.developmentalmadness.com/archive/2011/02/25/jquery-highlight-table-elements-when-a-cell-is-clicked.aspx</feedburner:origLink></item>
        <item>
            <title>Mid-Senior .Net Services Developer Positon - CLOSED</title>
            <link>http://feedproxy.google.com/~r/DevelopmentalMadness/~3/TlEtjUDaHlA/mid-senior-.net-services-developer-positon.aspx</link>
            <description>&lt;p&gt;We’re looking for a .Net services developer, mid-senior range: &lt;a href="http://tbe.taleo.net/NA8/ats/careers/requisition.jsp?org=INTERBANK&amp;amp;cws=1&amp;amp;rid=86"&gt;http://tbe.taleo.net/NA8/ats/careers/requisition.jsp?org=INTERBANK&amp;amp;cws=1&amp;amp;rid=86&lt;/a&gt;. I’m not interested in hearing from recruiters, and I’d prefer direct contact so if you know someone, have them contact me. The position is for Salt Lake City, UT local applicants only.&lt;/p&gt;&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;THIS POSITION IS CLOSED&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.developmentalmadness.com/aggbug/115.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=TlEtjUDaHlA:814cKKSLJyU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=TlEtjUDaHlA:814cKKSLJyU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?i=TlEtjUDaHlA:814cKKSLJyU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=TlEtjUDaHlA:814cKKSLJyU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=TlEtjUDaHlA:814cKKSLJyU:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=TlEtjUDaHlA:814cKKSLJyU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?i=TlEtjUDaHlA:814cKKSLJyU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=TlEtjUDaHlA:814cKKSLJyU:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopmentalMadness?a=TlEtjUDaHlA:814cKKSLJyU:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopmentalMadness?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentalMadness/~4/TlEtjUDaHlA" height="1" width="1"/&gt;</description>
            <dc:creator>Mark J. Miller</dc:creator>
            <guid isPermaLink="false">http://www.developmentalmadness.com/archive/2010/10/27/mid-senior-.net-services-developer-positon.aspx</guid>
            <pubDate>Wed, 27 Oct 2010 17:39:02 GMT</pubDate>
            <comments>http://www.developmentalmadness.com/archive/2010/10/27/mid-senior-.net-services-developer-positon.aspx#feedback</comments>
            <wfw:commentRss>http://www.developmentalmadness.com/comments/commentRss/115.aspx</wfw:commentRss>
            <trackback:ping>http://www.developmentalmadness.com/services/trackbacks/115.aspx</trackback:ping>
        <feedburner:origLink>http://www.developmentalmadness.com/archive/2010/10/27/mid-senior-.net-services-developer-positon.aspx</feedburner:origLink></item>
    </channel>
</rss>
