While working on some code today, I faced a problem I've run into a few times in the past where I needed to find the first usable input element within a specific context. What I mean by "usable" is an element which is visible to the user and not disabled.
Finding the first usable input element can be handy when you're using tabbed form, as when the user changes tabs, you can place the focus in the first visible input element. In my use case, I was implement a "reset" on a form where the fields being displayed could vary. I wanted to automatically place the focus in the first visible field after the user triggered a "reset" of the form.
If you're using jQuery v1.3 (or higher) this custom selector is very simple, just add the following to your page:
// finds elements that are usable (i.e. visible on the screen and are not disabled) $.expr[":"].usable = function (node, index, prop, nodes){ var $n = $(node); // return if the element is viewable or not return ($n.attr("disabled") !== true) && $n.is(":visible"); };
If you're using jQuery v1.2 (or lower) the code is slightly more complex because the ":visible" selector doesn't check with the parent elements to make sure they are all visible. So, in order to make our code work with jQuery v1.2 we'll need to first create a custom selector for which will find elements that are truly visible:
// finds elements that are viewable $.expr[":"].viewable = function (node, index, prop, nodes){ var r = false; function viewable(n){ var $n = $(n); return (($n.css("display") !== "none") && ($n.css("visibility") !== "hidden")); } // if not usable, stop processing if( !viewable(node) ) return false; $(node).parents().each(function (){ r = viewable(this); // if not viewable, stop processing chain return r; }); // return if the element is usable or not return r; };
The new ":viewable" selector should pretty much behave the same way that the ":visible" selector does in jQuery v1.3.
The only difference in this version of the ":usable" selector is that we're going to use our custom ":viewable" selector instead of the ":visible" selector:
// finds elements that are usable (i.e. visible on the screen and are not disabled) $.expr[":"].usable = function (node, index, prop, nodes){ var $n = $(node); // return if the element is viewable or not return ($n.attr("disabled") !== true) && $n.is(":viewable"); };
The ":usable" selector can be used in several ways:
// find all usable form elements $(":input:usable") // find the first usable form element $(":input:usable:first")
While the most common usage of the selector will probably be :input:usable:first, I can see where occasionally you might want to get all the input elements visible to the user.
Hope this helps someone!
2 Comments
Comments for this entry have been disabled.