A few months ago I threw together a quick redesign of the Learning jQuery site. It's nothing fancy, mind you, but I was itching to retire the thin veil covering the tired old WordPress Kubrick theme, so something had to be done.
Almost immediately upon changing the font-family and font-size of the blog post titles, I noticed a few unsightly widows (just to clarify, we're talking about typographical widows. My mother already suspects me of avoiding her; I don't want to add to her anxiety.
).
Here is an example of one such widow:

See how the last word, "plugin," appears on its own line? According to a couple designerly friends of mine, that's a no-no. So, I considered for half a minute how to get that title to look more like this:

The lowly yet lovely non-breaking space ( ) would do the trick, but how to replace it for the regular, breaking space? I certainly wasn't about to manually edit all of the entries' titles. Not only would it take too long, but it would also pollute the markup with something that really shouldn't be there. No, what I needed was a little JavaScript.
On this site, entry titles are wrapped in <h2><a href="foo"></a></h2>, which can be selected in jQuery with $('h2 a'). Easy. Now, because I want to manipulate the text of each title independently, I'll need to use the .each() method, which is basically a chainable for loop. Inside the .each() is where I substitute the last breaking space with the non-breaking variety. Here are three ways I came up with to achieve this.
The first approach was to convert the title string into an array of words and then stitch the array items back together, dealing with the last one specially.
A couple things to note about line 5 above: (a) the variable is actually being declared (with a "var") because it's separated from the previous variable declaration by a comma rather than a statement-ending semicolon. (b) The JavaScript .pop() array method "pops" the last item off the array and returns it; so it's no longer part of h2Array, but its value is stored in the h2Last variable. This is especially handy for us, because we don't want the last word to appear twice.
Line 6 joins the remaining array items with a space between them and then appends the non-breaking space and the popped last item. Line 7 dumps that concatenated string back into the title, inside <h2><a></a></h2>.
The next approach involved working solely with strings, using the slice and lastIndexOf methods to split the the string into two pieces — one leading up to the last space, and one immediately following the last space.
As line 7 demonstrates, the two sliced strings are stitched back together to keep the last two words on the same line.
The final technique is the one I ended up sticking with, partly because it's the tersest and partly because I have a fondness for regular expressions:
The distinguishing feature here is line 4, which uses the replace regular-expression method. This method takes two arguments, a pattern to match against and a replacement value. For the pattern, which appears between the two slashes, we first match a space and then match one or more "word characters" (letters, numerals, or underscores). The parentheses capture all but that initials space, and the "$" at the end ensures that the match appears at the end of the string. The replacement argument starts with the non-breaking space and follows with $1, which refers to the first (and in our case, only) parenthetical "capture group." (Please forgive me if I've provided too much detail about the regular expression. I'm never quite sure how much of this stuff is worth mentioning, but since this entry is targeting beginners, I suppose it's better to err on the side of too much.)
A few people pointed out in the comments that my regular expression could be improved, and I agree. In particular, as noted by Art Lawry, the \w can be changed to \S (that's an uppercase S) to match any non-whitespace character. That way it'll match characters such as ö and ç as well.
By the way, all three of these code examples can be reduced in length quite a bit. For example, the regular expression example can be pared down from 7 to 5 lines if we don't bother with the h2Text variable and instead do something like this:
$(this).html($(this).text().replace(/ (\w+)$/,' $1'));
However, the code is usually easier to read and maintain (for me, at least) if the value is first stored in a variable.
Any suggestions for improvement here? Any other approaches that you would recommend instead? Leave a comment.
Recently I have been getting a real buzz out of developing with jQuery. I've been using the library since 2006, releasing sporadic bits of code. In April of this year, I released the third revision of my most complex plugin, jMaps, and updated several other plugins, which are available in my mercurial repository.
This was also the same month I discovered a new plugin which has dramatically changed how I develop applications with jQuery. The plugin in question is Dan Webb's Low Pro for jQuery, a port of the plugin of the same name for Prototype.
So what is Low Pro? It's a plugin that provides a way of making more object-oriented JavaScript through event delegation. jQuery's plugin architecture provides a really simple way of extending the core functionality, but there is no easy way of making macros of code that do several types of events on one element. Until now!
Probably the simplest way to explain how Low Pro works is to build a quick demonstration. Sometimes I find that too many tutorials out there expect prior knowledge, so with that in mind, I will try to make the tutorial as simple as possible. However, this example does use another couple of plugins that are outside the scope of this tutorial:
Both these plugins already have excellent documentation, so if you wish to extend this example, please check them out.
For this example we'll build a simple user registration form. This is something that is common enough on the web, but a nice advantage of this example is that it
can be used over and over again with little or no modification. Hopefully once you have learned this pattern, you will be able to see lots
of other applications that can be reused over and over again in the same fashion.
Our first step is to create our basic form:
Now, we create our JavaScript file called reg-form.js. In here, we will create our class that we'll attach to the form. Inside this class, we'll create some functions that trigger on specific events. Every class created with Low Pro takes the form of $.klass({...});. Inside the curly braces, we use JavaScript prototype nature to create a pseudo-class. We will call our example RegisterForm.
If you have developed in languages like PHP, Python, or Java, you've probably seen something like this before. This first function, initialize, is a reserved function in Low Pro that accepts one parameter—an options parameter (we'll discuss that later). This function is always called whenever you bind a class to an element. Because it does not require any event to trigger, it is very useful for setting up initial data or events on dynamic DOM elements.
The first thing we'll do is create our JavaScript validation rules. This tutorial does not cover the creation of these rules; however, they should be reasonably understandable. If you would like more information, please check out the excellent documentation.
Notice that I am using this.element instead of $('#lowpro-form') inside the function. Low Pro provides this handy alias so you always work with the correct object. If you are going to be writing a complex function, it's always a good idea within the function to assign it to another variable.
But this code isn't actually doing anything yet. This is because we now need to bind the class to the form. Here is where we go back to the good old jQuery we know and love. Below the class, put this in the file:
Now, open up the page in your browser and start to type into the fields. You should start to see the validation rules apply to the fields. Congratulations, you've written your first re-usable class with Low Pro!
Now that we have our validation rules, let's start to make the form a bit more sexy. First, something simple. Let's make sure that the first field (the username field) is always selected first, so the user can easily tab down the form. After the validation method inside the initalize function, add this:
Refresh the page, and your username field should now get the focus.
Now let's introduce another event into the mix. When the user submits the form, we want to let the user know that it's being sent to the server. To do this, we could notify the user by changing the text on the button from "Register" to "Submitting".
So there we have it: A reusable, fully functional Ajax registration form with validation. You can check out a demo here and also grab the source code of this example from my repository.
One final thing I should touch on in this first tutorial is the initialize function's options parameter. When attaching any Low Pro class, the initialize function accepts an object containing any options you want to pass into the function:
In our above example, we'll add a tag to display a message of the day. In the HTML, create a div with a class of motd. Next, add the following code into the initalize function:
Now, when we attach our class to the form, we use the following:
When you now refresh the form, you should see a message on the screen.
Well, that wraps it up for this tutorial. I hope I've given you a small idea of the power that Low Pro contains. In conjunction with LiveQuery, you can really create some dynamic and interesting applications.
If anyone would be interested in more tutorials like this, then please leave a comment and let me know what you think.
CSS and JavaScript are different in many ways, almost all of which are too obvious to mention. However, one difference between the two bears explanation, because it is often the cause of confusion and consternation, especially among those who are making the transition from CSS guru to jQuery novice. In fact, it was one of the first things I asked about on the jQuery mailing list back in 2006. Since then, I've seen at least one question on the subject every week, and sometimes as many as one per day—despite an FAQ page and these three plugins to help users deal with it.
So, what's this important difference?
In CSS, style rules are automatically applied to any element that matches the selectors, no matter when those elements are added to the document (DOM).
In JavaScript, event handlers that are registered for elements in the document apply only to those elements that are part of the DOM at the time the event is attached. If we add similar elements to the DOM at a later time, whether through simple DOM manipulation or ajax, CSS will give those elements the same appearance, but JavaScript will not automatically make them act the same way.
For example, let's say we have "<button class="alert">Alert!</button>" in our document, and we want to attach a click handler to it that generates an alert message. In jQuery, we might do so with the following code:
Here we are registering the click handler for the button with a class of "alert" as soon as the DOM has loaded. So, the button is there, and we have a click function bound to it. If we add a second <button class="alert"> later on, however, it will know nothing about that click handler. The click event had been dealt with before this second button existed. So, the second button will not generate an alert.
Let's test what we've just discussed. I've added a script with the above three lines of jQuery code so that the following button will produce an alert message when clicked. Try it: Alert!
Now, let's create a new button (if we don't already have a second one) using jQuery code like this:
Have you clicked the link to create the second button? Great. Now click that button. It does nothing. Just as expected.
Now let's take a look at another example. In this one, we have three list items—two plain items and one with a class of special:
Press the "I am special" button to create a new list item with a class of "special":
Notice that, like the first special li, the new one has the yellow background. The CSS has come through for us. But press the newly created "I am new" button and, just as with the second alert above, nothing happens. The jQuery code we're using to add the new item says that upon clicking a button inside a list item with a class of "special" (which itself is inside an element with id of "list1") a new list item with class="special" should be inserted after the list item in which the button was clicked:
So, how can we get the events to carry over to the new elements? Two common approaches are event delegation and "re-binding" event handlers. In this entry, we'll examine event delegation; in part 2, we'll explore ways to re-bind.
The general idea of event delegation is to bind the event handler to a containing element and then have an action take place based on which specific element within that containing element is targeted. Let's say we have another unordered list: <ul id="list2"> ... </ul>. Instead of attaching the .click() method to a button — $('#list2 li.special button').click(...) — we can attach it to the entire surrounding <ul>. Through the magic of "bubbling," any click on the button is also a click on the button's surrounding list item, the list as a whole, the containing div, and all the way up to the window object. Since the <ul> that gets clicked is the same one each time (we're only creating items within the <ul>), the same thing will happen when clicking on all of the buttons, regardless of when they were created.
When we use event delegation, we need to pass in the "event" argument. So, in our case, instead of .click(), we'll have .click(event). We don't have to name this argument event. We can call it e or evt or gummy or whatever we want. I just like to use labels that are as obvious as possible because I have a hard time keeping track of things. Here is what we have so far: