2009/12/06

Simple things are hard to achieve

A very important part of easyUpload is that it must be easy, it should protect the user against unexpected behavior, it should be straight forward and simple, let's see two details:

Tabs

There are no tabs in the dialog. If no image is selected in the editor then it starts with a screen asking the user to select the image that he wants to use, and the options are quite clear: upload from the computer, browse the server, use an url.

In order to hide the tab bar (because in reality the code is splitted in two tabs, but only one of them is visible each time) I had to find a workaround because as I said only one tab is visible, but the code checks for the number of tabs and then it decides to make the tab bar visible.

So this is one possible solution (in the onShow method of the dialog)

this.parts.tabs.hide();

This does indeed hide the tab bar, but the spacing remains there, a better solution is to mark the dialog as "single paged":

this.parts.dialog.addClass("cke_single_page");

This little trick adds the class used by CKEditor to mark a dialog as single paged, so the tabs bar is gone as well as the spacing.

Ok button

If the user browses the server, as soon as he has picked the image the first screen dissapears and then the image properties are shown. The other two options have a button each one to confirm the selection, but there's a problem: the big "OK" button at the end. Users might click on it instead of using the one besides its option, so we need to listen to this button.

That's easy, you just need to add an event listener on the dialog for the 'ok' event.
But wait, it doesn't work!
The dialog keeps showing the dreaded "Some of the options have been changed", not our event handler!

Fortunately the Event system in CKEditor has a nice feature: The ability to specify a priority for our listener so we just need use a priority lower than the default (10) to get the event first. But if you look at the code you'll find that the dialog constructor adds its listener for this event (the one that later will show the alert) with a priority of 0. Oh, no.

Why does it needs to specify 0 as its priority? If it's the first listener that it's being added (and we are talking about the constructor) it should get fired first by default without the need to specify anything and saving those little bytes in the code.

What can we do now?
If we add the listener also with 0 it will be called later anyway :-(
But...
We are talking about javascript, in javascript there are no unsigned integers, just numbers, so this little trick is enough

    this.on( 'ok', function( evt ) {
...
    }, this, null, -1 );

Exactly, by setting our listener with priority -1 we get over the default one and no unexpected prompts will be shown :-)
 

Making options simple for the plain users usually requires a significant ammount of time to find the right parts to tweak, so it isn't strange that as the software becomes bigger there are some rough edges and only by focusing on some narrow part it's possible to improve it at the cost of not working on other improvements.

No comments: