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.
In this article, extracted from my book Instant jQuery Selectors, you’ll learn how to build a custom filter in jQuery. Please note that, to be a complete post, it has some minor adjustment compared to the original recipe titled Custom filters (Become an expert).
This article is extracted from my book Instant jQuery Selectors. Consider buying it on the Packt Publishing website or on Amazon.
Instant jQuery Selectors is a practical guide that will teach you how to use jQuery’s selectors efficiently in order to easily select the elements of your pages to operate upon with jQuery’s methods. You will go through the most common problems that you could face while developing your project and will learn how to solve them with the help of focused examples that Instant jQuery Selectors has to offer.
How to do it…
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 the steps described below.
Step 1
Create a file and rename it as custom-filters.html
.
Step 2
Open the file using a simple text editor, like Notepad++ on Windows, Sublime on Mac, or Gedit on Linux, or with your favourite IDE. In this file, we’ll create a simple form with some typical fields like “Name”, “Surname”, and so on. All these fields have the specification of the type (type
attribute) and the name (name
attribute), but few of them also have a placeholder set (placeholder
attribute).
Now, that you know what we’ll put in the file, just copy the HTML code below and save the changes.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Instant jQuery Selector How-to</title> <style> input, select, textarea { display: block; } </style> <!-- Script will be placed here... --> </head> <body> <form name="registration-form" id="registration-form" action="registration.php" method="post"> <label>Name:</label> <input type="text" name="name" placeholder="Name" /> <label>Surname:</label> <input type="text" name="surname" placeholder="Surname" /> <label>Email:</label> <input type="email" name="email" placeholder="Email" /> <label>Phone:</label> <input type="tel" name="phone-number" placeholder="Phone number" disabled="disabled" /> <label>Privacy:</label> <input name="privacy" type="checkbox" checked="checked" /> <label>Contact me:</label> <input name="contact-me" type="checkbox" /> <label>Sex:</label> <select name="sex"> <option selected="selected" value="m">Male</option> <option value="f">Female</option> </select> <input type="submit" value="Register" /> </form> </body> </html>
Step 3
Replace the comment we put (<!-- Script will be placed here... -->
) with the following code:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> <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>
Step 4
Save the file and open it with your favorite browser. Once the page is loaded, look at the console’s output.
How it works…
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
Conclusions
In this article I explained how you can create a custom filter in jQuery both using the old and the new, introduced in jQuery 1.8, methods. It’s important to know both because while in new projects you’ll hopefully find the latter method, in some projects you may find the former and will be an advantage if you know how to act, especially if the jQuery version can’t be updated.
Note: for those thinking about the best practice of putting the <script>
s before the <body>
tag is closed, instead of inside the <head>
of the page, I want to outline that it’s specified in one of the first pages of the book.
If you liked this article, consider buying my book Instant jQuery Selectors on the Packt Publishing website or on Amazon.
Instant jQuery Selectors is for web developers who want to delve into jQuery from its very starting point: selectors. Even if you’re already familiar with the framework and its selectors, you could find several tips and tricks that you aren’t aware of, especially about performance and how jQuery acts behind the scenes.