Reading List

The most recent articles from a list of feeds I subscribe to.

Tip: Multi-step form handling

First of all, sorry for my long absence! I haven’t abandoned this blog, I was just really, really busy. I’m still busy, and this probably won’t change soon. However, I will still blog when I get too fed up with work or studying (this is one of these moments…). Now, let’s get to the meat.

The situation

In most web applications, even the simplest ones, the need for form handling will arise. There will be forms that need to be submitted, checked, processed or returned to the user informing them about any errors. A good empirical rule I try to follow is “Try not to produce URLs that don’t have a meaning if accessed directly”. It sounds simple and common-sense, doesn’t it? However, as Francois Voltaire said, “common sense is not so common”. I’ve seen variations of the following scenario several times, in several websites or even commercial web application software:

Lets assume we have a two step process, like a registration form with an arguably¹ bad usability. The hypothetical script is called register.php (PHP is just an example here, the exact language doesn’t matter, it could be register.jsp or anything else). The user fills in the information required for the first step, and if they get it right, they advance to something like register.php?step=2 to complete the rest of the information. They fill in their information there as well, and submit the form. Everything is fine.

Or is it?

What we have done this way is that we have effectively created a completely useless URL. If someone tries to access register.php?step=2 directly (via their history for instance), we don’t have the POST data from the first step, so we either have to redirect them to the first step or, even worse, assume they are actually coming from the first step and present it to them full of errors telling them they got everything wrong. In both cases we have duplicate content, and in the second one, usability suffers a great deal.

So, the right way is to pass step=2 via POST as well. This way, the URL stays as it was (register.php) and we avoid all the problems mentioned above. So, we end up doing something like this:

... form fields here ...
<input type="hidden" name="step" value="2" />
<input type="submit" value="Create my account" />

Now we’re done. Or not?

This works fine. However, there’s still room for improvement. We could get rid of the extra input element by utilizing the submit button. Yeah, it’s a form element too, even though we often overlook that and just focus on styling it. If we give it a name, it will get sent along with the other form fields. So instead of the html above, we can do that:

... form fields here ...
<input type="submit" name="step" value="2" />

But wait! What the f*ck is that ???

Now usability suffers! Instead of our nice “Create my account” button, the user now sees a cryptic “2”. Who cares if it works or if it requires less code, if nobody understands how to register, right? Luckily for us, we don’t have to use the <input /> tag to create submit buttons. A better (in terms of styling, semantics, markup clarity etc), albeit less known, alternative exists: The <button /> tag. When using the <button /> tag, the label of the button is derived from the markup within the start and end tags (yeah, we can also have html elements in there, not only text nodes, in case you’re wondering), not from the value attribute. So, we can set it’s name and value attributes to whatever we want, and the user won’t notice a thing:

... form fields here ...
<button type="submit" name="step" value="2">Create my account</button>

It’s really simple, although not done often. I guess it’s one of these “OMG how come I’ve never thought about this??” kind of things. :P

¹ I firmly believe we should eliminate the number of steps required in any procedure and especially in registration forms that users are bored to fill in anyway. However, there’s an exception to that: If the form has to be big for some reason, breaking it into steps actually makes it more usable, since the user is not overwhelmed with all these fields. Another situation when this approach is favorable is when the second step is determined according to the data from the first, although thanks to JavaScript and Ajax, this is becoming obsolete nowadays.

9 reasons why I prefer MySQL to MS SQL Server

In the past, I used MySQL for any of my DBMS needs. It wasn’t really an informed decision based on solid facts, actually I had never really given it any thought. It was what most developers used, it was what vBulletin used (one of the main projects of my company is based on vBulletin), it was what most hosts had pre-installed, in other words, it was the popular choice and I went with the crowd.

Unlike most decisions taken that way, this one turned out to be correct (so far at least). In the university where I study (yeah, I do that too occasionally :P ), there is a great and extremely useful class on Database Systems offered in my semester. The only drawback is that it’s done on MS SQL Server. Consequently, I had to work with it quite a lot, and my conclusion was that MySQL is far superior (mostly syntax-wise as I don’t have the deep knowledge required to judge them fairly for other things, so don’t expect a deep analysis about performance or security - as far as I’m concerned, they are equally good at those). Here are a few reasons:

  1. No ENUM datatype. Yeah, of course I can define a column with a char/varchar type and add a constraint to only allow for particular strings, but this kinda defeats the purpose of memory saving that the ENUM datatype in MySQL offers.
  2. No INSERT IGNORE. Instead you have to go through hell to simulate that in MS SQL Server.
  3. I hate it that I can’t use “USING(columnlabel)” in a JOIN query and I have to use “ON(table1.columnlabel = table2.colmnlabel)” all the time. Yeah, I know that the first one isn’t standard, but it’s shorter, cleaner, more elegant, and …you can still use “ON(…)” if you don’t like it. Having more options is never bad, is it?
  4. With MySQL you may insert multiple rows at once elegantly (“INSERT INTO tablename (…), (…), …”), without using the “INSERT INTO tablename SELECT (…) UNION ALL SELECT (…) UNION ALL …” hack. Moreover, the elegant MySQL way also happens to be the standard, a standard that SQL Server doesn’t follow.
  5. Triggers can only run per statement, and not per row. This isn’t really important, since for most cases, it’s more efficient to define a per statement trigger anyway, but it doesn’t do any harm to have an extra option, does it?
  6. Paging is dead-easy on MySQL: SELECT * FROM foo LIMIT 10,20 . With MS SQL Server you have to jump through hoops to do the same thing, especially if your query is not trivial.
  7. In MySQL, when you want to convert an integer to a hex string, you just call HEX(). In SQL Server you have to call an undocumented function and do some string manipulation to do the exact same thing.
  8. MySQL runs on every platform, whereas with MS SQL Server you’re stuck with Windows.
  9. Last but not least, MySQL is free (and when it’s not free, it’s at least cheap) and opensource :-)

9 reasons why I prefer MySQL to MS SQL Server

In the past, I used MySQL for any of my DBMS needs. It wasn’t really an informed decision based on solid facts, actually I had never really given it any thought. It was what most developers used, it was what vBulletin used (one of the main projects of my company is based on vBulletin), it was what most hosts had pre-installed, in other words, it was the popular choice and I went with the crowd.

Unlike most decisions taken that way, this one turned out to be correct (so far at least). In the university where I study (yeah, I do that too occasionally :P ), there is a great and extremely useful class on Database Systems offered in my semester. The only drawback is that it’s done on MS SQL Server. Consequently, I had to work with it quite a lot, and my conclusion was that MySQL is far superior (mostly syntax-wise as I don’t have the deep knowledge required to judge them fairly for other things, so don’t expect a deep analysis about performance or security - as far as I’m concerned, they are equally good at those). Here are a few reasons:

  1. No ENUM datatype. Yeah, of course I can define a column with a char/varchar type and add a constraint to only allow for particular strings, but this kinda defeats the purpose of memory saving that the ENUM datatype in MySQL offers.
  2. No INSERT IGNORE. Instead you have to go through hell to simulate that in MS SQL Server.
  3. I hate it that I can’t use “USING(columnlabel)” in a JOIN query and I have to use “ON(table1.columnlabel = table2.colmnlabel)” all the time. Yeah, I know that the first one isn’t standard, but it’s shorter, cleaner, more elegant, and …you can still use “ON(…)” if you don’t like it. Having more options is never bad, is it?
  4. With MySQL you may insert multiple rows at once elegantly (“INSERT INTO tablename (…), (…), …”), without using the “INSERT INTO tablename SELECT (…) UNION ALL SELECT (…) UNION ALL …” hack. Moreover, the elegant MySQL way also happens to be the standard, a standard that SQL Server doesn’t follow.
  5. Triggers can only run per statement, and not per row. This isn’t really important, since for most cases, it’s more efficient to define a per statement trigger anyway, but it doesn’t do any harm to have an extra option, does it?
  6. Paging is dead-easy on MySQL: SELECT * FROM foo LIMIT 10,20 . With MS SQL Server you have to jump through hoops to do the same thing, especially if your query is not trivial.
  7. In MySQL, when you want to convert an integer to a hex string, you just call HEX(). In SQL Server you have to call an undocumented function and do some string manipulation to do the exact same thing.
  8. MySQL runs on every platform, whereas with MS SQL Server you’re stuck with Windows.
  9. Last but not least, MySQL is free (and when it’s not free, it’s at least cheap) and opensource :-)

Cross-browser imageless linear gradients v2

A while ago, I posted a script of mine for creating 2-color cross-browser imageless linear gradients. As I stated there, I needed them for a color picker I have to create. And even though 2-color gradients are sufficient for most components, in most color spaces, I had forgotten an important one: Hue. You can’t represent Hue with a 2-color gradient! So, I had to revise the script, and make it able to produce linear gradients of more than 2 colors. Furthermore, I needed to be able to specify a fully transparent color as one of the gradient colors, in order to create the photoshop-like 2d plane used by the picker (and no, a static image background like the one used in most JS color pickers wouldn’t suffice, for reasons irrelevant with this post). I hereby present you Cross-browser, imageless, linear gradients v2!

The API has stayed just the same, with the following differences:

  • You may specify the keyword “transparent” instead of a #RRGGBB color (that was such a pain to implement btw!).

  • When creating a Gradient object, color strings are now defined in an array. Example:

    var g = new Gradient(200, 100, [‘#000000’, ‘#ff1166’, ‘#23ff46’], true);

  • When calling g.paint() it now takes 2 arguments instead of 3: The new color array (or null if you don’t want that to change) and the direction (true for vertical, false for horizontal). For example:

    g.paint([‘#000000’, ‘#ff1166’, ‘#23ff46’], true);

  • 2 new methods have been added: g.setColorAt(index, color) and g.direction(newDirection). The first allows you to set a particular gradient color (index starting from 0) and the second to alter or toggle the direction (if you specify a direction parameter, you set the direction, if you call it with no parameters, it toggles from horizontal to vertical).

  • The fields g.startColor and g.endColor have been replaced by the array g.colors.

Update: v2.0.1 Fixed a small bug with the ‘transparent’ keyword that affected multi-color gradients in browsers != IE when the transparent color wasn’t first or last.

Enjoy:

gradient.js (5.1 KB)

gradient-min.js (2.7 KB)

Test page

Cross-browser imageless linear gradients v2

A while ago, I posted a script of mine for creating 2-color cross-browser imageless linear gradients. As I stated there, I needed them for a color picker I have to create. And even though 2-color gradients are sufficient for most components, in most color spaces, I had forgotten an important one: Hue. You can’t represent Hue with a 2-color gradient! So, I had to revise the script, and make it able to produce linear gradients of more than 2 colors. Furthermore, I needed to be able to specify a fully transparent color as one of the gradient colors, in order to create the photoshop-like 2d plane used by the picker (and no, a static image background like the one used in most JS color pickers wouldn’t suffice, for reasons irrelevant with this post). I hereby present you Cross-browser, imageless, linear gradients v2!

The API has stayed just the same, with the following differences:

  • You may specify the keyword “transparent” instead of a #RRGGBB color (that was such a pain to implement btw!).

  • When creating a Gradient object, color strings are now defined in an array. Example:

    var g = new Gradient(200, 100, [‘#000000’, ‘#ff1166’, ‘#23ff46’], true);

  • When calling g.paint() it now takes 2 arguments instead of 3: The new color array (or null if you don’t want that to change) and the direction (true for vertical, false for horizontal). For example:

    g.paint([‘#000000’, ‘#ff1166’, ‘#23ff46’], true);

  • 2 new methods have been added: g.setColorAt(index, color) and g.direction(newDirection). The first allows you to set a particular gradient color (index starting from 0) and the second to alter or toggle the direction (if you specify a direction parameter, you set the direction, if you call it with no parameters, it toggles from horizontal to vertical).

  • The fields g.startColor and g.endColor have been replaced by the array g.colors.

Update: v2.0.1 Fixed a small bug with the ‘transparent’ keyword that affected multi-color gradients in browsers != IE when the transparent color wasn’t first or last.

Enjoy:

gradient.js (5.1 KB)

gradient-min.js (2.7 KB)

Test page