fun with modal popups

At work, we frequently use the ModalPopupExtender from the Ajax Control Toolkit in our projects. I’ve got mixed feelings about this control, and about the ACT in general, but for better or worse, I do use it a lot. I discovered some functionality in the control this week that I was previously unaware of, so I thought I’d write up a blog entry on it, along with some related stuff that I stumbled across.

I needed to attach some JavaScript to the show and hide events for the popup, but wasn’t sure how to do that. It turns out that there are add_shown() and add_hiding() events that you can hook into, as described here. I initially found out about add_shown() at this StackOverflow page.

I then tried to hook up the event in the pageLoad() routine as shown in an example there. What I didn’t realize was that you can only have one pageLoad() function, and there was another one in a master page that was in my hierarchy, so my version didn’t get called. I then found out that I should change both of those to use Sys.Application.add_load() via this SO page.

Then, I followed up by learning a bit about the differences between pageLoad() and $(document).ready() at Encosia, which is one of the best sites out there for figuring out some of the trickier stuff when working with ASP.NET and JavaScript.

P.S. I just noticed that this is post # 1500 on my blog. There’s no real importance to that, but it’s always nice to hit a milestone.

Fractions!

I haven’t posted much code to my blog lately, so I thought I’d pass along some general-purpose C# code that I recently used in a project. I’m working on a system right now where the original author made some, shall we say, interesting decisions about how to store data in SQL. Specifically, he used varchar fields for most of the numeric data. And, in those fields, he sometimes stores the data in decimal format (e.g. “1.5”), sometimes as fractions (e.g. “1 1/2”) and sometimes as explicitly-signed fractions (“+1 1/2”).  I, of course, need to do LOTS of math on these numbers. The decimal fields can be dealt with using good old TryParse and ToString of course, but there’s no obvious parse routine for fractions, nor is there an obvious way to turn a decimal number back into a fraction string.

The internet, of course, provides. Here is a VB.NET function to turn a fraction string into a decimal and there is some C# code to convert a decimal into a fraction string in this thread. I converted the VB.NET to C#, and cleaned both of them up and put them in a utility class.  Here it is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace MySuit.MySuitV2.BLL
{
    public class Utility
    {
        public static decimal FractionToDecimal(string frac)
        {
            // this method should convert a fraction, e.g. "12 1/4" to a decimal, e.g. 12.25.
            // based on http://amrelgarhytech.blogspot.com/2008/03/fraction-to-decimal.html
            // TODO: not sure how best to handle exceptions here. (parse errors, div by zero, null/empty string input...)
            decimal rv;
            int numerator, denominator, wholePart = 0;
            int sign = 1;

            if (string.IsNullOrEmpty(frac))
                return 0m;

            // deal with signs
            frac = frac.Trim().TrimStart('+');
            if (frac[0] == '-')
            {
                frac = frac.TrimStart('-');
                sign = -1;
            }
            frac = frac.Trim();

            if (frac.IndexOf("/") > 0)
            {
                if (frac.IndexOf(" ") > 0)
                {
                    wholePart = int.Parse(frac.Substring(0, frac.IndexOf(" ")));
                    frac = frac.Substring(frac.IndexOf(" "));
                }
                numerator = int.Parse(frac.Substring(0, frac.IndexOf("/")));
                denominator = int.Parse(frac.Substring(frac.IndexOf("/") + 1));
                rv = sign * (wholePart + ((decimal)numerator / denominator));
            }
            else
            {
                rv = decimal.Parse(frac);
            }
            return rv;
        }

        public static string DecimalToFractionSigned(decimal value)
        {
            // always put a sign (+/-) in front
            string rv = DecimalToFraction(value);
            if (rv[0] != '-')
                rv = string.Format("+{0}", rv);
            return rv;
        }

        public static string DecimalToFraction(decimal value)
        {
            // taken from here: http://bit.ly/tHaKrK and modified to work with negative numbers too.

            int sign = 1;
            if (value < 0)
            {
                value = Math.Abs(value);
                sign = -1;
            }

            // get the whole value of the fraction
            decimal mWhole = Math.Truncate(value);

            // get the fractional value
            decimal mFraction = value - mWhole;

            // initialize a numerator and denominator
            uint mNumerator = 0;
            uint mDenominator = 1;

            // ensure that there is actually a fraction
            if (mFraction > 0m)
            {
                // convert the value to a string so that you can count the number of decimal places there are
                string strFraction = mFraction.ToString().Remove(0, 2);

                // store the number of decimal places
                uint intFractLength = (uint)strFraction.Length;

                // set the numerator to have the proper amount of zeros
                mNumerator = (uint)Math.Pow(10, intFractLength);

                // parse the fraction value to an integer that equals [fraction value] * 10^[number of decimal places]
                uint.TryParse(strFraction, out mDenominator);

                // get the greatest common divisor for both numbers
                uint gcd = GreatestCommonDivisor(mDenominator, mNumerator);

                // divide the numerator and the denominator by the greatest common divisor
                mNumerator = mNumerator / gcd;
                mDenominator = mDenominator / gcd;
            }

            // create a string builder
            StringBuilder mBuilder = new StringBuilder();

            // add the whole number if it's greater than 0
            if (mWhole > 0m)
            {
                mBuilder.Append(mWhole);
            }

            // add the fraction if it's greater than 0m
            if (mFraction > 0m)
            {
                if (mBuilder.Length > 0)
                {
                    mBuilder.Append(" ");
                }

                mBuilder.Append(mDenominator);
                mBuilder.Append("/");
                mBuilder.Append(mNumerator);
            }

            if (sign == -1)
                mBuilder.Insert(0, '-');

            return mBuilder.ToString();
        }


        private static uint GreatestCommonDivisor(uint valA, uint valB)
        {
            // return 0 if both values are 0 (no GSD)
            if (valA == 0 && valB == 0)
            {
                return 0;
            }
            // return value b if only a == 0
            else if (valA == 0 && valB != 0)
            {
                return valB;
            }
            // return value a if only b == 0
            else if (valA != 0 && valB == 0)
            {
                return valA;
            }
            // actually find the GSD
            else
            {
                uint first = valA;
                uint second = valB;

                while (first != second)
                {
                    if (first > second)
                    {
                        first = first - second;
                    }
                    else
                    {
                        second = second - first;
                    }
                }

                return first;
            }
        }

    }
}

(This is also in a Gist.)
I hope this helps anyone who might be looking for something similar. Also, I want to reiterate that I didn’t write this code from scratch. I took two existing functions, one in VB and one in C#, converted the VB to C#, cleaned them both up a bit, and put them together.

Luckily, by the way, all of the fractions I’m dealing with resolve to simple decimal numbers; everything is x/2, x/4, or x/8. I don’t have to deal with converting 1/3 to decimal and back. If you need to do that, you probably want a class that stores the fractions as numerator and denominator, and does math on them, as fractions.  There are a couple of those out there, if you look around.

In praise of impractical programming

Here’s a great little article from Nieman Journalism Lab on impractical programming.

All that matters is that you strike out on journeys without clear destinations in lands you hardly know. Be impractical. Cast spells.

iOS programming

I’m more than half-way through my iOS programming class at NYU. I’ve missed one class due to a flat tire, and I’ve been a bit under the weather during a couple of classes, but I’m definitely getting something out of the class.
I’ve made a Hypotrochoid generator the basis for my previous two homework assignments, so that’s been kind of fun. I didn’t figure out the code for this myself. Rather, I took the C# code found here, and converted it to Objective-C / Cocoa.
All of my homework code is up on my Github page, if anyone wants to look at it for some reason.
And here’s a quick screencast of my app. Not that exciting really, but fun to write.

iOS 5

I haven’t updated either my iPhone or iPad to iOS 5 yet, but, as a programmer, I’m happy to see that they’re finally doing automatic reference counting in Objective-C. I’m wondering if the instructor for my NYU iOS class is going to work any iOS 5 stuff into the class or not.  I could see where it would be hard to update class materials on the fly for this stuff, and our classroom iMacs probably still haven’t been updated to the latest version of XCode, but I’m hopeful.

accessing an IMAP account from .Net

I’ve been working lately on a couple of programs that need to access IMAP e-mail accounts. First, if you need to do this in .Net, MailSystem.NET is a good open source library.  I’ve had a few problems with parts of it, but the basic functionality is solid.

Figuring out how to test and troubleshoot a program that’s reading messages and moving them around in an e-mail account can be a little tricky.  First, it’s useful to know how to do IMAP stuff at a low level.  This page has a great overview of how to access an IMAP account directly over telnet. And, if you want to copy the contents of one IMAP account to another, so you can have an account to test against, then imapsync is a very good thing.

One other random helpful hint: I’m working with both GMail and 1&1 IMAP accounts.  I’ve found that there are some unexpected differences between them.  For instance, GMail generally returns a message containing the word “Success” when a command is successful.  1&1 returns a completely different message, so you need to be careful about what you’re looking for in a response string.

Blogger shenanigans

Hmm, the bit of code I’ve been using to generate a tag cloud stopped working for a bit, then just started working again. Maybe it’s time to review that code and rewrite it.  I know a lot more about JavaScript (and jQuery) now than I did when I took that code from someone’s blog, tweaked it a bit, and pasted it into my template.

Nice jQuery plugins

I’ve been working on a web page for the last couple of days that has to do a bunch of stuff client-side, so I’ve been relying more on JavaScript and jQuery, rather than the usual ASP.NET Web Forms stuff I’m used to.

Here’s a list of three relatively simple jQuery plugins that I’m using. I’ve found that, when looking for a way to do something in JavaScript/jQuery, there are usually several options. There are a lot of plugins out there. Some of them are well-written, cross-browser compatible, small, and quick. Others are a little buggy. These three appear to be in the former category.

Watermark plugin for jQuery — We usually use the Ajax Control Toolkit watermark extender. This seems to work just as well, with minimal effort.

jquery-color — I wanted to do some simple color animations on this page. Basically, I wanted to just briefly highlight a new entry with a color background, then have that background color fade out. This can be done with jQuery UI, but that’s a heavy bit of code to include, if you don’t really need it all. This plugin took a while to track down. The page for this at plugins.jquery.com just has a bunch of dead links on it. And searching for jquery color animation on Google mostly leads you astray. I found links to jquery-color on a couple of Stack Overflow questions.

simplepager — I’m displaying a list of comments on the page, and I needed to have a way to display them 10 at a time and page through them. This, again, is something that would be easy for me to do server-side with a ListView and DataPager, but I hadn’t really had to do it client-side before. There’s one site I worked on recently where the original author had implemented his own custom pager, but I didn’t want to use that code if I could avoid it. (Not that there was anything wrong with it, but it was well-integrated into that specific instance, and would have required work to generalize.) I had to make a minor change to this plugin, and I’m thinking that maybe I should submit it back to the author and see if he’ll merge it into the release version. I probably need to create an account on Github to do that, but that wouldn’t be a bad idea anyway.

truly annoying programming problems

I spent a few hours on Friday working on a problem that’s weird enough that I feel it warrants a blog entry. I made a few changes to one of our systems at work recently, and rolled them out Friday morning. This system is a VS 2008 solution with several projects in it. One of the projects is a bunch of web services, both SOAP and REST, that are deployed as a single DLL. I made a minor change to one of the REST services, but didn’t touch the SOAP services. And I made a minor change to a class in what is essentially a data access layer project that is referenced in the web service project, but nothing that should have affected the SOAP services. I’m saying all this to establish that I did not change anything that should have changed the SOAP services at all.

Returning to the data access project: this project was initially auto-generated through some CodeSmith templates, long before I started working for the company. The idea was that every class was implemented as a partial class broken into two files, with one file that contained auto-generated code, and one that could be used to add custom code. Now, some of these classes are used as output for the SOAP services. And those services just use the default XML serialization. (Some of you may see where this is heading.)

So we’re got a class called, let’s say, “Location,” broken into file X and file Y. File X contains properties A, B, and C, and file Y contains properties D, E, and F. Up until Friday, these properties had always been serialized from file X, then file Y, so they appeared in the output as A, B, C, D, E, and F. For some reason, on Friday, the compiler decided to process file Y before file X, and give me an XML document ordered as D, E, F, A, B, C. And, of course, the C# programs we have that actually call these web services don’t like getting their properties out of order. They expect everything to look exactly like the WSDL that was pulled in when they were last deployed. Oh, and most of them don’t have any useful error-handling or logging, and do a lot of their work in a declarative manner, through controls in the .aspx files rather than in code-behind, where I can see what’s going on step-by-step in the debugger. So figuring out what had gone wrong was interesting.

It had never really occurred to me, though I’m sure I read it at some point, that there is no guarantee as to the order in which the C# compiler will process the individual files that make up a partial class. (See this Stack Overflow question for reference.) I think the reason it changed now is that I moved the project from VSS to Mercurial recently, and that change probably caused enough of a disturbance to muck things up a bit.

I think if I had been the one that had implemented this thing in the first place, I would probably have done custom XML serialization, just because I’m a bit of a control freak, so I wouldn’t have ever had this problem.

Well, anyway, the moral of this story is that you shouldn’t assume that, just because a bit of code has been working for years, and you honestly haven’t touched it at all, that nothing can go wrong with it, and that the compiler will always output the same code given the same source code.

PHP Cookbook

I’m going to be doing some maintenance programming on a PHP/MySQL site pretty soon. I know a little PHP, probably enough to get by on this project, but I’d like to learn more. I have an old introductory PHP book around here somewhere, but I wanted to pick up something more substantial. So I picked up O’Reilly’s PHP Cookbook at Borders on my way home from work today. I have so many programming books that I’ve barely started reading, but this one looks like it’ll be a good reference.