In this app, we’ve used the term utility function to describe functions defined as properties of jQuery (and therefore $). These functions are usually intended to act on non-element JavaScript objects or to perform some other operation that doesn’t specifically operate on any objects. Some examples of utility functions you’ve seen are $.each() and $.noConflict(). In this section, you’ll learn how to add your own custom utility functions.
Adding a function as a property to an object or a function is as easy as declaring the function and assigning it. Creating a trivial custom utility function should be as easy as
$.say = function(what) {
alert('I say ' + what);
};
And, in truth, it is that easy. But this manner of defining utility functions isn’t without pitfalls. If some developer includes this function on a page that uses Prototype and has called $.noConflict(), rather than adding a jQuery extension the developer would create a method on Prototype’s $() function. (Get thee to the appendix if the concept of a method of a function makes your head hurt.) As you can see, unlike plug-ins that operate on a set of matched elements, a utility function is assigned to $ and not to $.fn.
We’ve already described this issue and its solution in section 12.3.2 (hint: create an IIFE). Discussing a utility function like the one just shown isn’t a big deal, so let’s implement and examine a nontrivial one.
Writing a date formatter
If you’ve come to the world of client-side programming from the server, one of the things you may have longed for is a simple date formatter, something that the JavaScript Date object doesn’t provide. Because such a function would operate on a Date instance rather than any DOM element, it’s a perfect candidate for a utility function. Let’s write one that uses the following syntax.
Function syntax: $.formatDate | |
---|---|
$.formatDate(date, pattern) | |
Formats the passed date according to the supplied pattern. The tokens that are substituted in the pattern are as follows:yyyy: the 4-digit yearyy: the 2-digit yearMMMM: the full name of the monthMMM: the abbreviated name of the monthMM: the month number as a 0-filled, 2-character fieldM: the month numberdd: the day of the month as a 0-filled, 2-character fieldd: the day of the monthEEEE: the full name of the day of the weekEEE: the abbreviated name of the day of the weeka: the meridian (AM or PM)HH: the 24-hour clock hour in the day as a 2-character, 0-filled fieldH: the 24-hour clock hour in the dayhh: the 12-hour clock hour in the day as a 2-character, 0-filled fieldh: the 12-hour clock hour in the daymm: the minutes in the hour as a 2-character, 0-filled fieldm: the minutes in the hourss: the seconds in the minute as a 2-character, 0-filled fields: the seconds in the minuteS: the milliseconds in the second as a 3-character, 0-filled field | |
Parameters | |
date | (Date) The date to be formatted. |
pattern | (String) The pattern to format the date into. Any characters not matching pattern tokens are copied as is to the result. |
Returns | |
The formatted date. |
The implementation of this function is shown in the following listing. We’re not going to go into too much detail regarding the algorithm used to perform the formatting because that isn’t the point of this lesson. We’ll use this implementation to point out some interesting tactics that you can use when creating a somewhat complex utility function.
Listing 12.6. Implementation of the $.formatDate() utility function


The most interesting aspect of this implementation, aside from a few JavaScript tricks used to keep the amount of code in check, is that the anonymous function assigned to $.formatDate needs some ancillary arrays, objects and functions to do its job. In particular:
- A regular expression used to match tokens in the pattern
- A list of the English names of the months
- A list of the English names of the days
- A set of subfunctions designed to provide the value for each token type, given a source date
- A private function that formats the passed value as a fixed-width field of the specified length
In this utility function you define several variables and functions. Some of them are private (declared using the var keyword), whereas others are exposed to the external world (defined as property of $.formatDate). The patternParts variable is only needed by your function so it’s nonsense to expose it, and it’s kept private. On the other hand, monthNames and dayNames
may be overwritten to provide the names of the months and the days in another language, so you allow accessing them from outside the function. Remember, JavaScript functions are first-class objects, and they can have their own properties like any other JavaScript object.
Your utility function relies on a support function called toFixedWidth(). The passed value to this function is converted to its string equivalent, and the fill character is determined either from the passed value or the default of 0 . Then you compute the amount of padding needed
.
If you end up with negative padding (the result is longer than the passed field length), you truncate from the beginning of the result to end up with the specified length ; otherwise, you pad the beginning of the result with the appropriate number of fill characters
prior to returning it as the result of the function
.
And the formatting algorithm itself? In a nutshell, it operates as follows:
1. Creates an array to hold portions of the result.
2. Iterates over the pattern, supplied as the second argument to the utility function, consuming identified token and non-token characters until the string has been completely inspected.
3. Resets the regular expression (stored in patternParts) on each iteration by setting its lastIndex property to 0.
4. Tests the regular expression for a token match against the current beginning of the pattern.
5. Calls the function in the patternValue collection of conversion functions to obtain the appropriate value from the Date instance if a match occurs. This value is pushed onto the end of the results array, and the matched token is removed from the beginning of the pattern.
6. Removes the first character from the pattern and adds it to the end of the results array if a token isn’t matched at the current beginning of the pattern.
7. Joins the results array into a string and returns it as the value of the function when the entire pattern has been consumed.
You’ll find this extension in the file js/jquery.jqia.formatDate.js and a simple page to test it at lesson-12/jqia.formatDate.html.
Leave a Reply