Custom parsers for YUI DataTable



Recently, I was working on a project where the team had created a page with a table of data. Each row in the table represented a recod in a database. Each row was a form and some of the cells could be edited.

We wanted to convert the table to a grid in an onubtrusive manner. We used the YUI DataTable and set the DataSource responseType to an HTML Table.

this.myDS.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;

One of the challenges was in parsing the data out of the cells that contained input boxes.

After some wrangling, we determined an approach. We created custom parsers intended to pull data out of cells with input boxes.

These functions are examples of what we started with. Obviously, you may want to account for things such as spaces between the word "value" and the "=". You'll probbaly eliminate the indexOf entirely.

Our functions are put into their own namespace. For the sake of example, we'll say the namespace is myNS.

First, we created a simple function that can be used as a formatter to pull the value:

YAHOO.myNS.parseValueFromInput = function(s) {
var intLocation = s.indexOf("value=");
if ( intLocation == -1 ) {
s = "";
}
else {
s = s.substring(intLocation+6);
if ( s.substring(0,1) == "\"" ) {
s = s.substring(1);
s = s.substring(0, s.indexOf("\""));
}
else {
s = s.substring(0, s.indexOf(" "));
}
};
return s;
};

This is sufficient for many cases, but we later discovered that column sorting in the grid did not always work as desired, so we added a couple more functions that ensure the proper datatype is returned.

// Parse a String from an input field
YAHOO.myNS.parseStringFromInput = function(s) {
s = YAHOO.myNS.parseValueFromInput(s);
return YAHOO.util.DataSource.parseString(s);
}

// Parse a Number from an input field
YAHOO.myNS.parseNumberFromInput = function(s) {
s = YAHOO.myNS.parseValueFromInput(s);
return YAHOO.util.DataSource.parseNumber(s);
}


We take advantage of the existing YAHOO.util.DataSource parse functions to get the proper return type. This gives us assurance the returned value will work as intended.

Use of these parsers is very straightforward. You use them just as you would one of the built-in parsers.

this.myDS.responseSchema = {
fields: [{key:"orderItemId"},
// YUI parser
{key:"line", parser:YAHOO.util.DataSource.parseNumber},
// Custom parser
{key:"memo", parser:YAHOO.myNS.parseStringFromInput},
// Custom parser
{key:"qty", parser:YAHOO.myNS.parseNumberFromInput},
{key:"label"},
{key:"uom"},
{key:"price"}
]
};


One additional tip; you don't want to create a parseCurrencyFromInput parser as the sorting will not work correctly. If you need currency, parse as a number and use a formatter to present the currency as desired.

The Handler - are you serious?


I subscribe the BNET Alerts; interesting and often useful tips and tidbits about small business and general survival in the workplace. Although I don't read it as often as I'd like, I enjoy the email periodical.

But today, they sent me a "tip" I found absolutely ridiculous:

Protect Yourself from Germs with The Handler

This has got to be a joke!

Have we really become this germophobic? Germ avoidance at this level does not help you stay healthier. It weakens your natural defense mechanisms and makes you that much more succeptable to the very thing you were trying so hard to avoid.

Go ahead and "open a door, push a button, lift or lower a toilet seat, scratch your bum, and so on." As far as I'm concerned, the only item on the list you should consider using it for is scratching your bum. And have you looked at this thing? It's a hook. I'd avoid the bum area....

Suck it up. Be a human (hu-person) and get a few germs on you now and then. You'll survive. You'll even thrive.

Surf the product site. I warn you the introduction music may not be your taste and may get you busted at work. They tell us there is a researcher who is "better known in the science world as 'Dr. Germ'." I find that hard to believe. But I am also poorly educated on the germ fighting affects of Silver Nano Particles....

Don't be like "Ted"



I have a friend; Let's call him "Ted".

Ted's place is a mess. Frankly, it's a disgusting, blatant, offensive, inexcusable mess. I visit Ted on occassion. He has a nice family. They're good people. Yet they live in near squalor and seem to be relatively unbothered by it. Ted complains regularly, but knows that sometimes there are circumstances beyond our personal control.

Allow me to share with you a few of Ted's household issues.

Scented candles are always burning in the kitchen, covering the smell of the garbage spilling over the bin and onto the floor. The trash overflows because nobody wants to carry it out to the garage where heaps of garbage bags sit cooking in the heat, producing flies, and attracting vermin.

Ted explains that they cannot take out the garbage because more trash in the garage will just make the problem worse. And they cannot clean the garage because they don't have the time it would require and cannot afford the dumpster or the fees the city would impose. The little money they could have used was spent last month when Ted got ticketed for putting trash in the clubhouse dumpster.

The appliances in the kitchen are all on one circuit. Ted cannot microwave food and run the toaster at the same time. Nothing else can be used while the oven is on. The garbage disposal regularly trips the CGI behind the refrigerator. Ted has grown accustomed to these inconveniences. They simply don't run the disposal and the microwave is only allowed to be used in the evening. Ted is the second owner of the house and the family that owned it before him did a terrible job of wiring the kitchen when they remodeled. Ted certainly wouldn't have done it that way, but there is nothing he can do now, no matter how much it annoys him.

Ted has an enormous water spot on the livingroom ceiling. The guest bath is immediately above the spot. The spot it turns out, is from an overflowing bucket. The bucket is placed under the sink to catch the drips from the trap. The leaky trap was discovered when Ted was repairing a faucet. As Ted explains, "I wasn't in there fixing the trap. I was in there fixing the faucet. When I get around to it, I'll fix the trap. I told the kids to check that bucket, but they never do."

These are only a few examples, but I expect you have a clear picture of Ted and his home life.

Unacceptable, isn't it?

So why, then, do so many developers work like this?

We don't cull out old dead code. We comment it or leave it abandoned in directories. The argument for not getting rid of it is that it would take too long to figure it all out. Or what about that four-year-old test data that never got removed from the system? Or all those transaction records that are nolonger needed? This stuff rots and stinks all over our system.

We know of a fundamental flaw in the application. Bad transaction scoping, for example. Or abuse of globals. Or any other obvious and painful flaw. But we learn to live with it. We actually adapt our behavior to the flaws in the system. I once worked with a team who lost momentum half-way through a version upgrade. Amazingly, when the differences between development and production became problematic, they accepted the inability to perform certain testing and figured out ways to get around compile issues. Meanwhile, they complained about the inconvenience they had to endure.

And the water-spot? How many times has someone on your team (maybe you) been in a piece of code doing some "surgical" work and then announced that they found another issue that will need to be fixed in the future?

Don't be like "Ted". You wouldn't live like this at home. Don't live like this at work.

Agile Methodologies for Non-Developers?


This is just a thought right now. More of a mental note; possibly not yet worthy of a blog post. But I think putting it out there will help it grow.

I've been working with teams and implementing Agile methodologies since before I knew there was a phrase for it. I used to call it "getting it done development". I was going to call my original company "JDI Software" for "Just Do It", but then Nike came out with that damn ad campaign...

Anyway, I digress.

In every large non-development specific organization that I have worked for, Agile has met resistence from the operational folks. You know, those people who control the servers, routers, and wires that connect them all. And I've always worked to accomodate their needs. I get it - they have a job to do and they have a way of doing it. And while it has been a few years, I was once one of "them". This isn't a developers versus operations rant. I have great respect and understanding for all of my extended team.

But lately, I've been wondering if Agile can be applied to "them". Can/would/do agile practices apply to server management, security, and networking?

What are your thoughts?

YUI.util.KeyListener



I had an interesting challenge today. I have a screen that has multiple text fields and multiple inputs that are actually images (default to submit). There was, by the way, not a single form on this page.

Internet Exploder Explorer was doing me the favor of ASSUMING I wanted the form submitted when a user pressed the enter key in a text field. So IE kicked off the onclick event of the FIRST submit/image on the page.

I decided to trap the enter key and use it for good rather than evil.

The YUI.util has a KeyListener that seemed to be what I was looking for. Yes, I could have just trapped the keypress event myself, but I LIKE to use YUI.

Turns out the documentation on this one is pretty good, but there are no straightforward examples. So, I'll just note here that you want to make sure you declare your KeyListener and then call the enable() method. Otherwise, it dosn't do anything for you.

myListener = YAHOO.util.KeyListener("watchNode", {keys:13}, functionToDo);
myListener.enable();


For some reason, this was not entirely apparent to me. Took me a while to figure it out. Hopefully, I just saved you some time.

Using YUI OverlayManager


I spend a pretty good amount of time on the YAHOO Developer Network, especially on the YUI documentation pages. And I don't recall having seen a prominent link to or a much of a mention of the YUI Overlay Manager. I stumbled across it when looking at example uses for the YUI Panel.

What is the Overlay Manager?
The Overlay Manager is used to manage the focus and state of multiple Overlays on a page. This includes Overlay subclasses such as Dialog, SimpleDialog, Tooltip, and Panel. In short; Overlay Manager makes sure the Overlay in focus is on top of the others.

I've been working on a B2B application that heavily leverages Panels for a better presentation and user experience. I was wrangling with how to allow multiple panels to be open at the same time. Early attempts left me frustrated.

Implementing OverlayManger
It took me no more than 5 minutes to get the OverlayManager working on the page. And "presto!", all registered Panels are managed with ease (and best of all no code from me).

First, you instantiate the Overlay Manager.
YAHOO.ns.myOM = new YAHOO.widget.OverlayManager();

Then, you register each rendered panel (myP) with the manager.
YAHOO.ns.myP.render();
YAHOO.ns.myOM.register(YAHOO.ns.myP);

I chose to do late registration because I saw no point in having the Manager know about every panel that MIGHT be rendered on the page. Besides, I don't instantiate the panel until the user indicates a desire to use it.

Overlay Manager works like a champ. No more than 10 lines of code later, and all of the registered panels play nice with one another!