Aiming for elegance, one thought at a time

Javascript Form Validation

Posted: May 23rd, 2010 | Author: | Filed under: IT | No Comments »

This is an incredibly common problem, and there’s really no reason to reinvent the wheel. That said, yesterday I thought of (what I think is) a rather neat way of solving the problem. So I’ve deliberately not looked in-depth at how others have solved this particular problem, and instead made a quick sketch of my solution. When I do look, I think I’ll be looking at the jQuery Validation Plugin.

In short, this model is inspired by jQuery’s ability to chain queries together, to give succinct, powerful syntax. There are two essential things that I want to be able to do:

  1. Check if a condition is present
  2. Assert that something should be so

My aim is to be able to do this with code that looks like this:

vl.ifEqual("detailrequired","Full")
  .assertNotEmpty("If full details are required,"
                  + "contributions must be entered",
                  "contributions");

But let’s start at the beginning. Form validation: there are many levels. Let me enumerate some:

  1. Required fields
  2. Fields having the correct format
  3. Inter-field validation (eg a start date falling before an end date)

In this sketch, I’m particularly thinking of the third level of form validation. In the example of a start and end date, all I want to do is check that the start date falls before the end date, and it it does, throw an error. I can do that with this code (error handling removed for brevity):

var startdate = Date.parse(document.getElementById("startdate").value);
var enddate = Date.parse(document.getElementById("enddate").value);
if (startdate > enddate) {
    alert("Start date must fall before the end date");
}

Simple enough, but rather wordy – particularly when you get in to handling errors and unexpected input. A more complex example might be to check the value of one field, and depending on its value, apply a particular rule. For example, if a field detailsrequired equals full, then a number of other fields are required. This could be achieved with this Javascript:

if (document.getElementById("detailsrequired").value=="Full") {
    if (document.getElementById("contribututions").value=="") {
        alert("If full details are required, "
               + "contributions must be entered");
    }
}

These individual samples aren’t very complex, but once you add code to handle exceptions, then they blow out a little bit. It’s also quite verbose. To achieve the syntax outlined above, where I can chain the checks and assertions together, I need to create an object that returns a reference to itself when you call any of its methods – the same way as jQuery works.

In the following code excerpt, I create two functions, and then bind them to a function object, ValidationLibrary. First a word on the function object: it has a single property, ‘check’, that is set by its single parameter. This parameter is used by the function assertEmpty. If this.check is true, then it will apply the assertion. If not, it doesn’t do anything.

The ifEqual function takes two parameters and compares them. If they are equal, it returns the parent object unaltered. On the other hand, if it they are unequal, it returns a new ValidationLibrary with check set to false – thus disabling any subsequent assertions.

function ifEqual(a, b) {
    if (a!=b) {
        return new ValidationLibrary(false);
    }
    return this;
}

function assertNotEmpty(msg, a) {
    if (this.check) {
        if (a=="") {
            this.error(msg);
        }
    }
    return this;
}

function ValidationLibrary(check) {
     this.check = check;
     this.assertNotEmpty = assertNotEmpty;
     this.ifEqual = ifEqual;
} 

With this framework, the example above becomes:

var vl = new ValidationLibrary(true);
vl.ifEqual(f("detailsrequired"),"Full")
  .assertNotEmpty("If full details only are required, "
                    + " contribution must be provided",
                  f("contribution"));

Note: I’ve created a function f(id) that returns the value of a form field, given a particular ID. If the form field contains a date, a Date object will be returned. If the form field contains a number, a Number object will be returned. Otherwise, a string will be returned.

With this framework, there’s a lot less boilerplate in order to get the same effect, and behind the scenes there is (or is in theory) a lot more error checking.

As above, this is only a rough sketch to capture the idea. I’m still to go and look at how other people have solved this same problem. And to be usable, a lot more would need to be done on this framework: the way assertions are reported in particular would need a lot of work, and even a cursory glance shows the the jQuery Validation plugin does a much better job of simple validations like making a field mandatory.

That said, the main idea I wanted to jot down was a way of handling more complex validations in an elegant way: I’m curious to see what other options are already in use.

In the meantime, please feel free to check out the rough demo and peruse the full javascript files, ValidateLibrary.js and FormValidations.js.

Tags: , , , , , ,

Wish I’d read this first

Posted: April 2nd, 2010 | Author: | Filed under: IT | No Comments »

I’ve been partially responsible for the creation of a new XML format for use at work. We’ve been working on it for around six months. It does the job- but it sure is ugly. A lot of that is because we didn’t have a nice set of standards to begin with. I wish I’d known about Google’s XML Document Format Style Guide six months ago.

The major things that leap out at me:

  • Consistency. This is really grinding on me at the moment. Parts of the format are camelCase, parts are all lowercase, others just random. In parts we use venetian blind design, other places Russian doll.
  • The build versus design argument: we built part, and borrowed a large chunk at the ninth hour (big part of the reason behind the inconsistency.)

I’m not completely sold that reusing an existing format would have been better. There are existing formats out there to deal with the type of data we’re using (financial services client/account details.) In this case, though, we face some unique constraints.

The schema is directly exposed to users at two levels. Firstly, through automatically generated forms from the off-the-shelf package we’re implementing. And secondly, behind the scenes, to BAs that support that package. The schema that we stole parts of was clearly not designed for this type of exposure. It focussed on machine-readability over human readability. We needed to do a lot of work to clean it up.

Tags: , , , , , ,

Don’t avoid rework

Posted: January 18th, 2010 | Author: | Filed under: IT | No Comments »

I’ve learnt an important lesson over the last few weeks. Don’t avoid rework – make it easy to do instead.

A few months ago, we were working on the foundations for the project I’m on. We knew that if we got the foundations wrong, the potential rework would be time consuming and expensive. Needless to say, we wanted to avoid that, and so we started doing some analysis to make sure we did it right. All fair enough.

But the fear of getting it wrong led to analysis paralysis. In the end, we ran out of time. We’d only got through one tenth of the scope when we needed to deliver. For the rest, we had to guess, and we got it wrong anyway. We went through the expensive and time consuming rework that we were trying to avoid.

It was only after that experience that we sat down and thought: does this rework really need to be time consuming and expensive? It turns out, the answer is no. With couple of hours work, we were able to write a script that did the bulk of the heavy lifting. It’s still a little bit manual, and if we wanted to, we could certainly make substantial additional improvements.

Already, though, we can feel the fear of rework lifting. We’ve now got the confidence to decide, and act, without wasting time chasing an elusive perfection.

Tags: , , , , ,

Test driven design

Posted: November 1st, 2009 | Author: | Filed under: IT | No Comments »

I don’t know quite what it is, but something about test-driven development (TDD) appeals to me. Perhaps it strikes a chord with my fundamental belief that machines should do the work so that people have time to think. Or perhaps it’s because TDD appeals to my anal nature. Whatever the case is, I like any opportunity to automate things, and although I’ve never done any, TDD seems to an absolutely brilliant way to spend one’s days.

Only down side is – I’m on an integration project at the moment, and so the opportunity for TDD is limited, right? Well, it might be a wee bit harder, but we shouldn’t let that stand in the way. ThoughWorks have a whitepaper (written by Gregor Hohpe and Wendy Istvanick) that talks about their approach to TDD in enterprise integration projects.

It lays out really clearly all the component pieces needed to overcome the challenges in creating automated tests for enterprise integration solutions, and gives some pretty good advise on designing for testability – which is probably not on our radar at the moment.

Might just drop this on the test analysts desk come Monday.

Tags: , , , , , , ,

Pheonix

Posted: July 31st, 2009 | Author: | Filed under: IT | No Comments »

Almost everything we come in to contact with is designed to be thrown away. Toasters, couches, computers, buildings, public transport systems – almost everything we use will eventually end up in land fill. When we design things, we normally don’t think about what will happen once it’s served its purpose. If we do, it’s only to plan how we can manage getting rid of it. Often we don’t even do that. Most of us are guilty of hoarding some useless thing or other, simply because we never thought about what we’d do with it once we were done with it.

IT systems are no exception.

A few years ago I read a fascinating book called Cradle to Cradle: Remaking the Way We Make Things by McDonough and Braungart. The normal approach to design – the one we experience every day – is cradle to grave design. We design a product or service to be created, used, maintained, and then thrown away. McDonough and Braungart opened my eyes to a different type of design. Designing things in a way that allows them to be reborn when they’ve reached the end of their current life.

For physical objects, this means designing things to be either recyclable or biodegradable. There are countless examples of what can be done. Phones that simply pop-apart when heated above a certain temperature, making it economical to recycle their component parts. Square carpet ’tiles’, instead of rolls of carpet, that can be replaced individually when they wear, and again be recycled in to new carpet (your office, if it’s been fitted out recently, probably has these.) The ‘renting out’ and re-capture, rather than sale, of industrial chemicals.

Why do these things? Because we’re running out of land fill and resources, and so ultimately we have no choice. But perhaps more relevantly, because it’s often cheaper. In the long term, it’s cheaper to design products and services that create more resources than they use. To design products and services that will be the foundations that tomorrows products are built upon, and the fertile soil that tomorrows services grow within.

Does this have any lessons for IT management? We habitually manage our systems and services on a cradle to grave basis. Indeed, IT management frameworks such as ITIL build in the assumption that systems will be decommissioned-thrown in the bin. We make decisions on the basis that, at some point, the system is going to be replaced. We take shortcuts when developing new processes or capabilities, because we know we won’t have to support them forever. Often, we avoid making necessary changes because a new system is perpetually just around the corner.

Would we make different decisions if we were managing IT cradle to cradle? What would this mean in practice? Stay tuned.

Tags: , , , , , , , ,