Hashrocket.com / blog

Bg default article large

jQuery Tips: Adding Filter Expressions

posted on and written by Shane Riley in

Image 100x100 shane riley

Are you writing complex filter methods like this to get at the elements you need?

$("form").find(":input").filter(function() {
  return this.value === "active";
});

Then it might be time to start writing your own jQuery expressions. They're really simple to make and are, in most cases, easier for others to read because it hides the DOM element inspection behind the expression filter.

Here's a quick example: just like the example code above, you want to find only inputs with a given value. To convert this to an expression, you'd write something like this:

$.expr[":"].value = function(el, idx, selector) {
  return el.value === selector[selector.length - 1];
};

Then you can find an input with a value of active using a selector like this:

$(":input").filter(":value(active)");

In the method you create for any jQuery expression, you are given three arguments. The first is the DOM element for that particular iteration. Second is the index of the DOM element relative to the original collection the expression was called on. Last is an array similar to what you'd get from a RegExp exec method call. The full expression is the first array position, second is the text from the selector between the colon and opening paren, and the last is the string that occurs within the parens. Let's take a look at another example to illustrate how this selector array is structured.

Here's an expression that will return you any elements with a particular data attribute that equals a specific value.

$.expr[":"].data = function(el, idx, selector) {
  var attr = selector[3].split(", ");
  return el.dataset[attr[0]] === attr[1];
};

If you had a div with a data attribute of data-default="Hello world" and you wanted to get at it in a single selector, you could write:

$("div:data(default, Hello world)")

If you want to create multiple expression filters, it's best to use jQuery's extend method to combine a new object with your filter methods and the $.expr[":"] object.

$.extend($.expr[":"], {
  data: function(el, idx, selector) {
    var attr = selector[3].split(", ");
    return el.dataset[attr[0]] === attr[1];
  },
  value: function(el, idx, selector) {
    return el.value === selector[selector.length - 1];
  }
});

Posted in Development and tagged with Javascript