Tuesday, August 14, 2012

jQuery Function of the Week: grep

This week's jQuery function of the week is grep.  According to the jQuery docs grep:
Finds the elements of an array which satisfy a filter function. The original array is not affected.
There is only a single signature for the grep function: $.grep(array, function(element, index) [,invert]). The function being passed in should return a truthy value or a falsy value based on the input argument.  If the invert parameter is left out, or is false then the grep function will return a new array with all the items that the satisfy the truth test function that was passed in.  If invert is set to true, grep will return a new array with all the items that do not satisfy the truth test function.

Lets take a look at looping through an array of text and removing the word "the":

JS Bin demo

Now lets take a look at the same code, but with the invert parameter set to true:

JS Bin demo

You'll see that only the word "the" is returned.

Check out the all of the jQuery function's of the week.

Thursday, August 9, 2012

jQuery Function Of The Week: nextAll

I'm super busy this week so this week's jQuery function of the week is going to be an easy one: nextAll.  According to the jQuery Documentation use nextAll to:
Get all following siblings of each element in the set of matched elements, optionally filtered by a selector.
Lets say we had a list of items, and we wanted to highlight every vegetable  Using nextAll would look like this:

JS Bin demo

Optionally a selector can be passed into nextAll to further filter the results.  Here we'll only select the even vegetables that are after our original selector:

JS Bin demo

Wednesday, August 1, 2012

jQuery Function Of The Week: proxy

In my JavaScript fundamentals presentations I have a section that talks about scope and how it can become confusing when using jQuery.  The reason for this is becuase jQuery normalizes the this scope in its function calls.  In other words when inside a jQuery method call this usually refers to the DOM elements in the jQuery set.

This can be clearly illustraed in a simple jQuery event callback (note use your browsers console, not jsbin's for the meantime):

JS Bin demo

This can become a problem when we try to write reusable code. Lets say we want to put our event handler into a object and then call it when a user clicks on a link:

JS Bin Demo

If you run the code you'll see that you get "Hello, undefined" instead of "Hello, Homer Simpson". The reason is simple, jQuery used the link as the context of this where no myName property exists. Enter jQuery.proxy.

According to the jQuery Documentation, the proxy function:
Takes a function and returns a new one that will always have a particular context.
This means that by using the $.proxy function we can make our callback run in the proper context, in this case itself:

JS Bin Demo

The change is subtle, but the result is exactly what we want.   Now, at this point you might be asking yourself, "isn't this the same thing as using the apply() or call() methods (mdn apply documentation)?   The answer is yes...and no.  Lets look at how to get the desired result using apply():

JS Bin Demo

If you look closely you'll notice a slight difference, the callback is now invoked in an anonymous function instead of passed directly to the on() method.  This is because the apply method invokes the function immediately whereas jQuery's proxy function only returns a reference function for later invocation.   This is a bit nicer because it makes for slightly more terse code.

In addition the proxy() function does a few more things:

  • it makes sure that the function passed in is actually a function
  • it assignes a unique ID to the function.  This is very important because when trying to unbind a function you may not be unbinding the proper function if you are passing in the function to the off() method.  Its best to always use namespaced events when using on() and off() with $.proxy().

Friday, July 27, 2012

Solving JavaScript Async Issues the Easy Way, With Events

By now we all know that JavaScript is asyncronous and what that means, right?  If not the following code will help explain the concept in 30 seconds:


This code will run function a() then b(), even if the ajax request in a() has not yet completed.

There are a lot of approaches that can be used to make sure that b only runs when a is done.  One approach would be to use jQuery deferreds like so:


We can also use a async library, such as q, if we need a bit more power.  Or we can use JavaScript's setTimeout(func, delay) function to continuously check for a variable the function a() sets when it is done before we call b(), how awful does that sound? In some cases there is a quite simple way to achieve this, by using events.  I might even argue that using events is the more JavaScripty way to do things in the right situation.  Lets take a look at the a/b example, this time using events:


Lets take take a look at a real world example of using events to make sure things happen in the proper order.  Here we will use a backbone collection as a wrapper for a one or more Contact objects that will be reused in multiple places in an application:


Let say we want to use this collection to populate a drop down when a view is initialized like so:


Using this code there is a good chance that the models will be an empty array when we try to add them to the dropdown.  Also, when the collection's fetch() completes the app.contacts.models array will be reset, meaning that the reference to the contacts in your view likely will not reference the current app.contacts.models array.

To fix this, lets first update our collection to trigger an event when the contacts are loaded.  In this example I'm going to use jQuery's trigger(eventName) function to keep things easy:


The last step is to make sure we are adding the carriers to the drop down after they have been added to the collection. To do this we just need to add an event listener to our initialize function:



Now we will always be working with a populated collection in our addContacts method.

Monday, July 23, 2012

jQuery Function Of The Week: one

jQuery's one function is an extremely useful function when you want an event to fire exactly one time.   According to the official jQuery documentation use one to, "Attach a handler to an event for the elements. The handler is executed at most once per element"  One is a much more terse way of setting an event handler and calling unbind() or off() in the handler function.

The easiest use of one is to pass it an event and a handler like so:



Click Here to Demo on JS Bin

You can click the link as many times as you wish, however the event will only fire once.

You can pass in more than one event handler to the one function by passing in a list of events separated by a space.  When you do this each event will fire once.  In this example the event will fire 3 times, one time for each event:



Click Here to Demo on JS Bin

You can also  pass in custom data to the event handler, the data comes attached to the event.data object like so:



Click Here to Demo on JS Bin

One additional thing you can do with the one function is use an additional selector to pass into the one event that will attach the event to exactly one of the descendants of the matched set. In the following example click on any of the li elements, then click on another, you'll see the event only fires for the first element selected.



Click Here to Demo on JS Bin

Check out the all of the jQuery function's of the week.


Fork me on GitHub