jQuery Tip #6 – Creating a Custom jQuery Selector

Interested in learning more about jQuery? Check out the jQuery Fundamentals course at Pluralsight.com.


Previous Tips:


Selectors are a key part of jQuery and one of the features that have made it so popular over the years. If you've worked with jQuery then you've used different types of native selectors including tag name, ID, class name, and others. jQuery also provides selector extensions that add the ability to search children in a given parent by position, locate input elements, find even or odd elements, and much more. Examples of custom selector extensions in jQuery include :eq(), :hidden, :gt(), :visible, and many more. A complete list of the selector extensions built into jQuery can be found at http://api.jquery.com/category/selectors.

While most jQuery developers know about selector extensions, many aren't aware that you can write your own custom selectors quite easily. Although custom selector extensions certainly aren't required, they can be useful in situations where you find yourself writing the same type of code over and over and you want to simplify things as much as possible. For example, assume that you have the divs shown next defined in a page and you'd like to write code to display all hidden divs (this code is a bit contrived in order to demonstrate a point – I'd stick with consistently using CSS class names in a real app).


<div class="panel hidden">
    Panel 1
</div>
<div class="panel" style="visibility:hidden">
    Panel 2
</div>
<div class="panel" style="display:none;">
    Panel 3
</div>
<div class="panel">
    Panel 4
</div>


If you wanted to show all panels that have the hidden class on them or those that have a style of display:none or visibility:hidden set then you might write code similar to the following. This code gets run as a button in the user interface is clicked.

$('#showPanelsButton').click(function () {
    $('.panel').each(function () {
        var $pnl = $(this);
        if (($pnl.css('display') == 'none') ||
             $pnl.css('visibility') == 'hidden' ||
             $pnl.hasClass('hidden')) {
            $pnl.removeClass('hidden')
                .css({ 'display': '', 'visibility': '' });
        }
    });
});


While there's nothing wrong with this code, if you find yourself needing it in multiple places you'll either refactor it into a function (the preferred approach) or copy it around throughout one or more scripts. Another technique that can be used is to write a custom selector. By creating a custom selector you can encapsulate the code into a re-useable function and use it directly within your jQuery selectors.

Creating a custom selector is accomplished by using jQuery's extend() function, defining the expression that needs to extended (the : character in this case), and then associating a selector name with a function that determines what nodes make it into a set and what nodes are excluded as the custom selector is used. This may sound at little complex at first glance but it's surprisingly simple once you see the pattern. The following code shows how the code shown earlier can be refactored inside of a custom selector.

 

$.extend($.expr[':'], {
    hiddenPanel: function (pnl) {
        if (pnl == null) return false;
        var $pnl = $(pnl);
        return $pnl.css('display') == 'none' ||
               $pnl.css('visibility') == 'hidden' ||
               $pnl.hasClass('hidden');
    }
});


Looking through the previous code you'll see that we start by calling jQuery's extend() function and pass it the expression that we'd like to extend (: in this example) as well as an object literal that defines the custom selector name and the function that will be called once it's executed. In this example the custom selector is named hiddenPanel and when it's used in a jQuery selector the function will check if the node that's passed in has its display set to none, visibility set to hidden, or if it has a CSS class on it named hidden. If any of the conditions are met the node is included in the set and returned to the caller. If the node doesn't meet any of the conditions it will be excluded.

The following code demonstrates how to use the hiddenPanel custom selector:


$('#showPanelsButton').click(function () {
    $('.panel:hiddenPanel')
       .removeClass('hidden')
       .css({ 'display': '', 'visibility': '' });
});


Live Example

If you’re interested in learning more about jQuery or JavaScript check out my jQuery Fundamentals, Building ASP.NET MVC Apps with EF Code First, HTML5, and jQuery, or Structuring JavaScript Code courses from Pluralsight. We also offer onsite/online training options for companies as well at http://www.thewahlingroup.com.



 

Conclusion

The custom :hiddenPanel selector is now available to use anytime you're working with selectors. By creating a custom selector it's straightforward to look for hidden panels, get a set of nodes that match the conditions defined in the selector, and then modify the nodes. Although this simple custom selector example may not necessarily apply to your own application, knowing how custom selectors can be created and used is useful in a variety of scenarios.


image

comments powered by Disqus

4 Comments

Comments have been disabled for this content.