ColdFusion CFChart woes - converting from CFGraph

February 22nd, 2007 by Ryan Stille

I was working on converting an application from ColdFusion 5 to CFMX 7 last week, and ran into some problems converting cfgraph (CF5) to cfchart (CF7). The graphs that looked nice in 5 weren’t coming out so good in 7.

Original chart in CF5, using the CFGraph tag:
CF5 chart

How the chart looks after converting to CFChart in CF7
CF7 chart
Notice the problem with the y-axis labels.
Read the rest of this entry »

Self-signing your secure certificate - SSL for free

February 11th, 2007 by Ryan Stille

Usually to setup an SSL-enabled website (a website available via the secure, https protocol), you purchase a certificate from a trusted authority such as Verisign or Thawte. This costs anywhere from $150-400 per year. But this cost is not always necessary.
Read the rest of this entry »

My GreaseMonkey Script: craigslist spam buttons

February 8th, 2007 by Ryan Stille

Last weekend I wrote my first GreaseMonkey script. If you are unfamiliar with GreaseMonkey, its a FireFox extension that lets you run specific JavaScripts on specifc webpages. This is incredibly cool, you can basically bend websites to whatever you want. Everything from changing the look and feel to adding new functionality. GreaseMonkey puts you back in control of your browsing experience. A neat example is the GM script that, when you are browsing Amazon, will put a link to the book at your local library and indicate if its available there.

The GreaseMonkey script I wrote works with Craigslist.org. Craigslist is a popular free classifieds site. Craigslist’s posts are not moderated, so anyone can post an ad. That includes spammers. Craigslist spam is mostly controlled by craigslist users themselves. See an ad thats spam? Click the spam button. If enough people mark it as such, it automatically gets taken down. I really like CL, so I do my part by flagging any spam I see. To do this you must click on the item title from the list, then click the spam button on the detailed listing. But I can often identify spam just from the title. Posts like “FREE 4gb ipod nano!!” and “Take Your New Pair of Uggs!” are obvious spam.
Read the rest of this entry »

Animated in-progress indicator for long running pages

February 4th, 2007 by Ryan Stille

On pages that take more than a few seconds to complete, its a good idea to show some type of in-progress meter. Things like bulk email processing and large file uploads are good candidates. Often this doesn’t need to be as complicated as a real progress meter, where you show the actual percentage complete. Instead, an “in progress” meter just gives feedback to the user to let them know that something is going on.
Read the rest of this entry »

Preventing multiple form submissions

January 30th, 2007 by Ryan Stille

Here’s a small snippet to help prevent users from clicking the submit button more than once. When this happens you can end up with duplicate data, or even multiple charges on the user’s credit card. This trick uses JavaScript, and degrades nicely if JS is turned off.

<input type="submit" value="Place Order"
onclick="if (this.value == 'Place Order') { this.value = 'Please Wait...'; return true;} else return false;">

On some applications it is also a good idea to redirect the user to a success page, instead of just displaying a success message. That way they can’t accidentially refresh their browser and POST the form again. This is complicated if you’re displaying a receipt or similar, where you need the data from the form post to create the success message. You could stuff those values in the session in that case.

No more reset buttons, please!

January 26th, 2007 by Ryan Stille

One thing I often notice about novice developer’s web forms is that they usually contain a RESET button. You know, <input type="reset">. I think this is because a lot of books that talk about creating forms always use them in their examples.

But who really uses a reset button? Have you ever filled out a form, then realized you made a typo in your phone number? Did you correct your typo or did you think “gee, I’ll just use this reset button to clear the whole form, then I’ll put in the right phone number!”

I’m sure somewhere there is a legitimate use of a reset button. Maybe to reset a form that was pre-filled back to its original values. But 99% of the time they are not needed. Take a look at the forms on any well designed site, you won’t find any reset buttons. Not on Google, Yahoo, Microsoft, A List Apart, etc.

And its not just that they’re not needed, they are actually detrimental. Having two buttons at the bottom of a form clutters the interface and makes it harder for the user to clearly see the path to the next step. Trust me, I’m not the only person who has filled out a lengthy signup form, only to be too quick on the mouse (or tab key) when clicking the ‘obvious’ submit button on the bottom of the form. Only its not the submit button, its the reset button. And unfortunately there is no undo for that action.

So please, no more reset buttons!

Comparing dates without times in SQL Server

January 20th, 2007 by Ryan Stille

Sometimes you have the need in an application to compare dates without the time component. For example, a user signs up for a free 30-day trial of a client’s site. The user’s ‘expire_date’ will be set for 30 days from today, probably using something like DateAdd(”d”,30,getdate()). At some point you need to compare the expire_date against the current date. Maybe its a report of current free trial users, or a query to see if the user is allowed to login. Your query will look something like

... WHERE expire_date >= getdate()

The problem with this is that both values contain a time component. What you are really comparing is something like

... WHERE 2007-1-20 10:44:22.717 >= 2007-1-20 10:30:28.287

So a user may be considered still in their free trial at 10:30am, but when they try to login again 20 minutes later, they may be told their trial has expired. In reality the free trial should continue throughout the last day of the trial period. If you signed up for a free two week gym membership, would you expect to be allowed in before lunch on the last day but not after because of what time you initially signed up?

This is not a problem in MySQL, as it has a simple DATE type (in addition to the common DATETIME type) that does not store any time data. So what we need to do in SQL Server is strip off the time component. I typically do this when I store the date, but you could do it at compare time, too.

SQL Server datetimes are stored internally as floating point numbers. You can see this by CASTing the value of getdate to a float.

SELECT CAST( getdate() AS float)

When I ran this just now I got 39100.964272067904. That indicates 39100 days after 1/1/1900 (SQL Server’s base date), and 96/100ths of a fractional day (it’s almost midnight). We can use this to modify the float value and then CAST it back as a datetime type. The FLOOR function will strip off any decimal portion of a number. Thus:

SELECT CAST(FLOOR(CAST( getdate() AS float)) AS datetime)

returns “2007-01-20 00:00:00.000″ - the date without the time.

There are other ways to do this, using the day, month and year functions or the CONVERT function. I find the above method to be more straight forward (although only by a little - its a pain no matter how you do it). You could add that code to a trigger so whenever that field is set or updated the time portion is automatically stripped off.

Now when we compare the field, we’ll need to do the same conversion to the current day:

... WHERE expire_date >= CAST(FLOOR(CAST( getdate() AS float)) AS datetime)

Keep in mind that queries with functions in the search condition are expensive. If you are going to run this often or on a lot of data, you may want to pass in the date from your application language:

... WHERE expire_date >= '2007-01-20'

Hey Eclipse - Call me when you grow up

January 8th, 2007 by Ryan Stille

Ok - I think I’m done with Eclipse, the promising Java-based editor for ColdFusion, PHP, Java, you name it. I tried to like it, I really did. It has many promising features. The Who’s Who of the ColdFusion world all use it. I like the idea of Subversion plugins, fusebox plugins, etc. There’s a plugin for almost anything! I would like to be intimately familiar with this editor, and be able to easily use it for Java or Flex development, should the need ever arise. I’ve completely abandoned Homesite, my old editor of choice, for the last month to really get used to CFEclipse. I’ve setup a number of shortcuts to my liking (Ctrl+F6 to switch through open documents - who decided that should be the default?). I’ve been using it everyday for a number of client sites. I’ve been using it at home for PHP development.

But it feels like I’ve been fighting it the whole time. Read the rest of this entry »

Drag and drop sort order with Scriptaculous

December 31st, 2006 by Ryan Stille

We had a need at work this week to create an interface that allows users to change the sort order of items using a drag-n-drop interface. Drag-n-Drop is one thing that Adobe’s Spry library is missing. But with the help of the Scriptaculous JavaScript library, this is a pretty easy task.

Scriptaculous is an add-on to the Prototype JavaScript framework. Start by downloading Scriptaculous and linking to it on your page. You don’t need to download Prototype separately, its included.

Read the rest of this entry »

Snapshot backups

December 9th, 2006 by Ryan Stille

I’ve been wanting a way to easily recover a file that is accidentally deleted from one of our websites, either by us or by a client. Also, it would be useful to be able to get back to the state your code was in X number of days ago. For example when the client changes his mind about the current direction you’ve been developing. Source control can offer a solution to some degree, but won’t help you if the client has access to the website and they’ve changed a file. And some shops just don’t use source control for all their projects.

Tape backups also offer a partial solution, I’ve had to pull a file off yesterday’s tape several times. But restoring from tape is a hassle, especially if its stored off site (which it should be!).

Enter rsnapshot. Read the rest of this entry »