The jQuery Templates API and JavaScript’s Future
On October 4th (two days ago) jQuery announced that they had promoted three Microsoft projects as official jQuery plugins: The jQuery Templates Plugin, the jQuery Data Link Plugin and the jQuery Globalization Plugin. See the announcement here. It’s definitely worth a read if you use jQuery at all.
Now, in my opinion the new Data Link and Globalization APIs have yet to prove themselves. They really seem like Microsoft steering jQuery-style JavaScript towards the way ASP.NET Web Forms works, and time will tell whether that ends up making sense in JavaScript’s evolution. What I’m really excited about is the jQuery Templates API, and that’s what I think makes this a significant milestone for how we’ll be doing JavaScript in the future.
For Context…
The jQuery Templates Plugin allows you to generate HTML to represent data stored in JavaScript objects, similarly to PHP or ASP. For example, if your page contains the following template…
<script id="resultsTemplate" type="text/x-jquery-tmpl">
<li>
<a href="${Url}" target="_none">
${Description}
</a>
</li>
</script>
…This template can be selected by jQuery, rendered with data and then appended to the page. For example…
// Data stored in an object:
var resultsData = [
{
Url:"http://www.google.com/",
Description:"Google Search"
},
{
Url:"http://blog.thatscaptaintoyou.com/",
Description:"Wyatt Allen's Blog"
}
];
// Select the template,
// render it with the data (making it a bunch of LIs),
// and stick it in the page:
$("#resultsTemplate")
.tmpl(resultsData)
.appendTo("#myDivId");
… Very easy and maintainable.
What This Means…
Part of the significance of this is that templates mean we can build more interface into the browser’s language. We won’t need the server to render all our HTML for us, and, with the weight of many Ajax applications, we shouldn’t have to. This API is a wonderfully clean and manageable way of accomplishing this.
The other half of the significance here is has to do with how we build GUI frameworks. Sometimes I compare building web interfaces to building native interfaces on something like Windows. Early on, we’d build Windows programs by talking directly to the Windows API – using something like “windows.h”. Progressively, however, frameworks were built to make this process a lot cleaner and reasonable such as the MFC library. This transition really signifies ironing away the hard parts of an API using an object-oriented abstraction; complete with inheritance, polymorphism and the whole collection of OOP ideas. It’s an age-old, tried-and-tested, Gang-of-Four design-pattern, and we love it.
The way I see JavaScript DOM programming and the current state of HTML is that it’s still in the early “windows.h” stage of evolution. A good, strong object-oriented abstraction for programming web interfaces would meaningfully improve the development process, maintenance, security and richness of the web. The reason that I feel nobody’s build something like this yet is because JavaScript’s OOP approach is so unusual. Tools like inheritance and polymorphism as they’re implemented in JavaScript simply don’t lend themselves well to frameworks.
I believe that this new jQuery Templates API is a BIG push in the right direction. It will allow us to deal with interface components with varying degrees of abstraction and join data to markup in a responsible, semantic fashion. I encourage every JavaScripter to try jQuery Templates out for themselves. I’m going to be using them and closely watching how they’re being used in expectation that it will lead to an emergent, more properly-abstracted approach to our web applications.
Haskell’s foldr in JavaScript
Most people who work with me know that I’m a great fan of the Haskell programming language. I believe (as do most fans of the language) that a firm grasp of Haskell will help you become a better programmer generally. I feel, furthermore, that one of the contexts where this benefit is most pronounced is in JavaScript programming.
foldr in JavaScript:
And so, for use in my scripts, I’ve implemented Haskell’s famous foldr function in JavaScript. Source below:
function foldr(fn, ult, xs) {
if (xs.length == 0) {
return ult;
}
if (xs.length == 1) {
return fn(
xs[0],
ult
);
}
else {
return fn(
xs.splice(0, 1)[0],
foldr(
fn,
ult,
xs
)
);
}
}
What, in Haskell we might write as:
foldr (\x y -> (x+y)/2) 54 [12,4,10,6] -- Output: 12.0
In JavaScript we can write:
foldr (function(x, y){ return (x+y)/2; }, 54, [12,4,10,6])
// Output: 12
So, there it is. I hope you like it.
Further Pondering:
But before I go, I want to write some philosophical thoughts on Haskell and JavaScript.
The similarities between the two are more than passing. They are both functional languages. As Douglas Crawford points out, JavaScript was the first popular “lambda-language”. Both languages have proven to be highly expressive tools for programmers despite being occasionally unforgiving in syntax.
Aside: Curiously, some of the most clever programs have be written in the most austere environments. I’m reminded of the quote:
“More good code has been written in languages denounced as bad than in languages proclaimed wonderful — much more.”
— Bjarne Stroustrup
End aside.
However, the differences between Haskell and JavaScript become conspicuous. Whereas Haskell is statically typed and strictly functional, JavaScript is quite dynamic and is generally written procedurally. These features lead to common pitfalls in JavaScript, where scripts can turn into “spaghetti-code” or soupy variable messes of “side-effects“. Haskell itself is sheltered from these dangers by virtue of strong typing and restriction to the functional paradigm.
For these reasons, it’s my belief that taking experiences from Haskell programming into JavaScript algorithms results in safer, more reliable, more verifiable code. In the realm of JavaScript and the problems particular to it, these qualities are of paramount value.
In this spirit, I may find myself porting more of the Haskell prelude functions in the future.
Big.js version 0.8.0 Released
Big.js is now in version 0.8.0! Support for addition and subtraction for positive and negative numbers is now included. There are also new methods for cloning and negating numbers.
Expect multiplication, division and more in the next release.
Example using v0.8.0:
var pi = new Big(
"3.14159265358979323846264338327950288" +
"4197169399375105820974944592307816406" +
"2862089986280348253421170679821480865"
);
var twicePi = pi.plus(pi);
twicePi.toString() // -> "6.2831853071795864769252867665590057683943387987502116419498..."
// Actual: "6.2831853071795864769252867665590057683943387987502116419498"
Introducing Big.js: Arbitrary Precision Math for JavaScript
Numbers in the JavaScript language are inherently limited to 64-bit floating-point precision. In most programming scenarios this is ample precision, but some applications need something more. For those applications, programmers typically make use of an arbitrary-precision math library. However, a complete library of this type for JavaScript does not exist.
The wonderful jsbin.js tool by Tom Wu is a step in the right direction. It is essentially a port of the BigInteger API included in the Sun Java programming language. However, it sadly does not have support for fractional numbers (only integers).
For me, in my development of jQuery.validity, it is necessary for me to be able to check the mathematical inequality of numbers of any length. Particularly as a result of this bug report, it became clear that parsing strings as floats was not a viable way of checking inequalities. The report provides the following example:
// The validation rule is that the number // represented by a string should not be // greater than twelve. So, if a string // housed the value... var str = "12.00000000000000005"; // ... I should be able to detect whether it is // less than or equal to the number 12. // But to do so, parsing as a float does not do. parseFloat(str) <= 12 // Evaluates to true, should be false. 12.00000000000000005 <= 12 // Also, true. // JavaScript is truncating the number. // In fact... 12.00000000000000005 // ...itself evaluates to 12.
In a client-side validation framework (such as validity), this is not acceptable, because the web-application may deal with numbers which have greater precision than JavaScript can process. (The server may be programmed with higher precision or an arbitrary-precision library.)
The conclusion is that an arbitrary-precision library, capable of processing fractional numbers, is needed in the client-side JavaScript code. For this, I’ve written Big.js.
At the moment, Big.js is only able to perform inequality operations on numbers (i.e. lessThan, lessThanOrEqualTo, greaterThan, greaterThanOrEqualTo and equals) on positive and negative numbers.
For example:
// Numbers in Big.js are called with the Big() constructor:
var number1 = new Big("12.00000000000000005");
var number2 = new Big("12");
number1.lessThanOrEqualTo(number2); // False, like it should be.
// To boot...
number1.lessThan(number2); // False
number1.greaterThan(number2); // True
number1.greaterThanOrEqualTo(number2); // True
number1.equals(number2); // False
Inequality is all that is needed, technically, for the library to be useful in validation. Big.js is therefore in version 0.7.* (beta) at the time of writing this article. Version 0.8.* will have addition and subtraction support, and 0.9.* will have support for other mathematical operators. Finally culminating in version 1.0.* which will be considered “out of beta”.
The 0.7.0 beta is available on Github now under an MIT licence. More operators to be implemented soon!
JSMandelbrot: Exploring Fractals with HTML5
I recently wrote a JavaScript toy to explore the Mendelbrot fractal set using JavaScript and the HTML5 Canvas API.
Visit it here. (Warning: loading the page is CPU intensive. You’ll want to wait until it says “Done” in the lower-right corner until you can zoom in.)
From a web developer’s standpoint, JSMandelbrot is a pretty interesting demonstration of the power of the Canvas API and explores the limits to which mathematical computation can be safely deferred to the client.
From a geekier standpoint, fractals are just plain cool. I’ve spent close to hours zooming in on various sections of the set. The infinite vastness of the fractal is mindboggling and wonderful.
From my personal standpoint, since high school I’ve had an interest in Mandelbrot fractals. I can remember watching a public television documentary on them. I was so excited by the show that I asked my AP Calculus teacher (who actually took a class on fractal geometry when she was in college) to help me figure out how to make them on my own. She told me that they were too complex for me to learn. This fanaticized my interest in them and a few weeks later, just based on my own online research, I had a Mandelbrot generator on my TI-83 Plus graphing calculator and shortly thereafter I implemented one in QBasic on my computer. It was through this experience that I came to know for a certainty that I wanted to be a programmer.
I hope you enjoy it!
Updates to Validity and Roadmap
I’ve gone through and updated the Validity documentation plus plenty of tweaks here and there to the whole site. Check it out!
The next steps for Validity itself are:
- Improved support for radio buttons.
It seems like most of the problems I’m helping people with have to do with radio-buttons. Consequently, we’ll be adding tools to validity to make this validation as straightforward and helpful as possible.
We feel that it’s important for using Validity to feel natural, and radio-buttons are an area that can be improved a bit.
- Improved support for password validation.
We’re planning to introduce a
semanticPasswordvalidator. This will allow you to specify the complex validation parameters needed for passwords (such as minimum non-alphanumeric characters, password strength, etc.) in a manner that makes sense.The goal is to make the way you validate a password on the server the same as the way you do so on the client. If, on the server you specify the minimum number of non-alphanumeric characters with an integer value (such as commonly in ASP.NET) you won’t have to translate that into a regex for validity. A regex would be less manageable. Less manageable is bad.
They’re exciting times for Validity. Look for a new version soon!
Give Your Page Subtle Style With Ligature.js
Although I’m not very good at it, I’ve always enjoyed typography. A few years ago, a very good math professor at Portland Community College got me started in LATEX programming. Ever since then I’ve sort of had an appreciation of the subtler side to good type.
One of my favorite parts of LATEX is how it automatically converts normal text into ligatures. Ligatures, if you don’t know, are essentially two letters that get typographically mashed together into a single glyph. For example, a ligature exists for the letters f and i, forming fi. (Check it out. That fi is a single character. Try selecting just the f.)
Most printed books use ligatures when they’re typeset. Most computer text (for instance a document typed out in Microsoft Word) however, would not use ligatures. The result of this, at least the way I perceive things, is that ligatures grant text gravitas. My eyes are trained to take text with ligatures more seriously.![]()
Enter Ligature.js, the fruit of less than an hour of JavaScript hacking. Easy to write as it may have been, I’m proud of this little script.
You might have already guessed what this script does. Ligature.js will crawl over an HTML Document and insert ligatures where it finds corresponding character sequences. In fact, it’s already been run on this blog page! (If JavaScript is enabled in your browser, that is.)
The implementation is nothing fancy. There’s a recursive node-crawler algorithm which will use regular-expression find-replace logic to insert the ligatures. See the code page (liked above) for all the usage info.
In fact: Ligature.js is so compact, it can even be stored as a bookmarklet so that you can bring the wonder of typography to any website! Just bookmark this link, and you’re good to go!
Enjoy!
Strange Behavior of the Global Regex Flag
So, for some time I’ve been building a jQuery plugin called jQuery.validity. I’ll post more on that later, but suffice it to say for now that the plugin uses regexes to examine the format of strings. A few days ago, Jeff (another of the Validity developers) caught Validity acting strangely when he used it with some custom regexes.
What was happening was the regex would give seemingly random results testing whether the the same string with the same regex. This would result in Validity allowing invalid inputs and disallowing valid ones: pretty much the opposite of what it’s supposed to do.
Eventually, we discovered that the problem was related to the the global flag that he was applying to his regexes. Removing the global flag caused the regexes to act the way we would expect them to.
Validity worked again. I added notes to the documentation entreating developers not to use regexes with global flags. This is okay, I guess for a temporary solution, but I wanted to actually solve the problem and understand where it was coming from.
The following code snippet illustrates this strange behavior:
var
// Regex to search for the word duck
// without the global flag set.
nonGlobal = /duck/,
// The same regex,
// except with the global flag set.
global = /duck/g,
string = "duck duck goose";
// Use the regex to test the string:
nonGlobal.test(string); // True.
// We can test these two as many times as we like.
// This regex tested against this string
// will always return true.
nonGlobal.test(string); // True.
nonGlobal.test(string); // True.
nonGlobal.test(string); // True.
// However:
global.test(string); // True.
global.test(string); // True, again.
global.test(string); // False!?!?
global.test(string); // True again!
global.test(string); // True.
global.test(string); // Now we're back to false.
// This global regex,
// tested many times against the same string
// will not always yield the same result.
To Jeff and I, this behavior seemed like JavaScript was misbehaving (even though we got the same strange behavior in all browsers). It seemed to us that one regex tested against one string should elicit the same result every time.
I set forth to research the topic. When I finally figured out what was going on, it turned out that we both had incomplete understandings of how regexes were supposed to work in JavaScript.
(Well, we won’t take all the blame. My feelings are that good, complete documentation on how JavaScript handles the global flag is hard to find and confusing when you do find it. In this article, I’ll try to lay it out as clear as possible.)
What Exactly is the Global Flag For?
Simply put, the global flag tells regexes to find and capture all possible matches in a string (not just the first one). The global flag is only useful when you attempt to capture matches out of a string, not when you’re testing a string’s format.
(Really, JavaScript only supports three regex flags. Before doing research on this problem I didn’t really know exactly what they did. I’ll cover them in what I believe to be plain terms in this article’s appendix.)
What Does JavaScript Do With a Global Regex
Normally, the global flag is useful for the “regex.match(string)” method, which will return an array of matches. However, if one is not attempting to locate matches, the global flag will still affect the “regex.test(string)” method!
If the regex is global, then “regex.test(string)” will only examine the string so far as the conditions of the regex are satisfied, and then return true. But, it will also set the “regex.lastIndex” property to the character index of where the examination stopped. When “regex.test(string)” is run a second time, it will examine the string starting at “lastIndex”. This will happen even if you’re testing of a totally different string, of any length!
What Happened in the Example
As you can see in the code example above, the first time “global.test(string)” is run, the global regex found the word “duck” within the string, then saved the “global.lastIndex” property to “4”.
The second time the test is run, JavaScript started from position four and found the word “duck” a second time returning true. At this point “global.lastIndex” is equal to “9”.
The third time the regex is run, JavaScript started from the ninth position and encountered the word “goose” followed by the end of the string. Since “goose” does not match the regex, false is returned. However, since the end of the string was reached without satisfying the regex, “regex.lastIndex” was set to “0” effectively restarting this unpleasant ordeal at the beginning of the string.
As you might have guessed, the next two tests would return true, followed by a false on the third.
It’s possible that this mechanism was meant for iterating over matches within a string, but that functionality would seem to make more sense in the “regex.exec(string)” method than in “test”.
(It’s my opinion that the test method shouldn’t be doing this. Test means test! It’s testing! Not iterating or finding matches. Testing!)
The Solution
The solution to this dilemma is painfully simple, if the regex is global just set the “lastIndex” property to zero before you test. Observe:
if (regex.global) {
regex.lastIndex = 0;
}
That was easy. I put this code into Validity so that it will execute this before it uses a regex for testing a string. In this way Validity will be able to make use of regexes that have global flags.
Conclusion
The morals of this story are:
- Only use the global flag (“/g”) on your regexes if you’re actually going to be finding several matches within a string.
- If you use a global regex for testing anyway, enclose it with the anchors (“^” and “$”) so that either the whole regex will be satisfied or not.
- If you don’t use the anchors, at the very least, set the “lastIndex” to zero before you use a global regex to test as string.
Appendix
I feel that most of the documentation and tutorials that cover regexes in JavaScript don’t explain flags terribly well. Here, I’ll attempt to explain them concisely and clearly.
The three regex flags that are supported by JavaScript’s regex engine are:
- /g: As we’ve seen, this flag will instruct the regex engine to search for all possible matches within a string. In some cases, it will cause the engine to behave iteratively.
- /i:This flag enables case-insensitivity. Using this flag is a simpler way of allowing upper and lower case than using bracketed groups.
- /m: This flag enables multiline searching. Specifically, what it will do is cause the “^” and “$” anchors represent the start and end of the entire string rather than just the start and end of the first line.