This morning, I found out about a very useful jQuery function going by the unassuming name of data. This fantastic little beast creates a data store for an element, and lets you store just about anything in there.
One of the ways in which this can be used is to attach functions to an element, and using them when required. To demonstrate the usefulness of this feature, I wrote two versions of a simple validation system. In one, we use the data function to assign one or more validators to an input box [Example 1: using $(x).data()]. In the other, we iterate over the inputs and check them against validators as needed [Example 2: not using $(x).data()].
You will notice that the mark-up for the two files is identical – only the validation system is different. In the first case, we’re assigning a validator to a number of fields, based on the CSS classes assigned to it. All validation methods here have the same signature, so we can easily call them without having to check what they are.
The really big difference is in the validation. In example 2, we’re iterating over all the input elements and checking if they need to be validated, and against what. In example 1 however, we’re letting the elements themselves tell us what sort of validation they need – if any:
1: validatorsForField = $(this).data(validators);
2: value = this.value;
3:
4: for (var index in validatorsForField) {
5: validator = validatorsForField[index];
6:
7: if (!validator.validate(value))
8: alert(this.name + validator.message);
9: }
This is desirable for a number of reasons. First, we never have to touch this function in order to add a validation. Big bonus there. Less likely to break it that way.
Secondly, it scales pretty well. Supposing you have a lot of fields, some of which have lots of validations, some of which have very little. Since each field tells you “hey, I need to check this, this and that”, you don’t have to go round each and every one of them and ask them “Do you need to check this? Do you need to check that? Have you gone to the bathroom before we left? etc.” In the second example, we have 3 validators, and the code isn’t that bulky. Yet. Imagine scaling to even 10 or so types of validation though… doesn’t look that friendly now, does it?
Granted, we can replace the series of conditionals with a loop on an array of validators like we had in example 1, but we’d still have to check for what sort of validation each field needs.
Third, the number of if statements is much smaller. That makes it more aesthetically appealing to me for some reason.
Incidentally, example 2 demonstrates the use of another jQuery gem: the is() function, which tells you whether a given element matches a selector.
I’m off to experiment with the live() function now, which looks like fun. And no, that means exactly what it looks it means.