We've learned all of the available jQuery's filters. In some cases you may need a shortcut to collect elements for which jQuery doesn't provide a specific filter. This is exactly where custom filters come into play.
Our goal is to print the length of the elements having the placeholder attribute set, taking advantage of a previously created custom filter. In addition, to see all of the available options in action, we'll create a second filter to collect all of the elements having a name with less than a given number of characters.
To complete the task, follow these steps:
Create a copy of the
form-filters.html
file and rename it ascustom-filters.html
.Edit the
<head>
section of the page, replacing the previous custom JavaScript code with this one:<script> $.expr[':'].placeholder = function(elem) { return $(elem).attr('placeholder') !== undefined; }; $.expr[':'].nameLengthLessThan = $.expr.createPseudo(function(filterParam) { var length = parseInt(filterParam); return function(elem, context, isXml) { return $(elem).attr('name') !== undefined && $(elem).attr('name').length < length;} }); $(document).ready(function() { console.log($(':placeholder').length); console.log($('input:nameLengthLessThan(5)').length); }); </script>
Save the file and open it with your favorite browser.
At the very beginning of our JavaScript instructions for this page, we've added a property, or more specifically a function called placeholder
to the :
(yes, it's a property called colon, you read it right) attribute that belongs to the jQuery's expr
attribute. :
is a property containing jQuery's native filters and you can use it to add your own at runtime. Inside the function definition, we just have a single statement that checks if the current element has the placeholder
attribute set, and if so, it returns true to keep the element.
As you can see from the example, in this basic version, a filter is nothing but a function that accepts as an argument the current DOM element to process and needs to return true
to keep it in the collection, and false
to discard it. You should use this method when the following are true:
you're interested only in the element to process itself
the filter doesn't accept an argument
the context to which the selection is applied doesn't matter
The second custom filter, called nameLengthLessThan
, is slightly more complicated and uses the method introduced (and encouraged) starting from jQuery 1.8. To the createPseudo
function we pass an anonymous function having a parameter that represents the argument passed to the filter when you use it. Inside it, we create another function that will be returned and that is responsible to perform the filtering. To the latter, jQuery passes the element to be processed (elem
parameter), the DOMElement or DOMDocument from which selection will occur (context
parameter), and a Boolean that tells if you're operating on an XML document. As you may guess, for this filter we need this pattern because our filter needs to know the limit of characters the name
attribute of the element must comply with. In other words, we need to pass the number of characters the value of the name
attribute must respect.
Inside the inner-most function, we write the code to test if the element should be kept or not, for our example, this means checking whether the name
attribute is set and its length is not less than the given length (stored using a closure inside the length
variable).
Now that we've created the filters, we need to use it. Inside the handler for the document.ready
event, there are two statements. The first calls the placeholder
filter without parameters and using implicitly the Universal selector. The second uses the nameLengthLessThan
filter passing 5
as parameter and using the Element selector. Using the Element selector in the second call will result in a performance improvement. The execution of our code will result, as expected, in the following lines printed on the console:
4
1