A quick-and-dirty list filter. Praise God (jeresig? ;o) for jQuery!
Sure, there are a gazillion plugins for this, that usually do too much, but anyway, here’s what so few lines of jQuery code can do…
Script
<ol id="foo"> <li>…</li> … </ol> <script> window.onload = function(){ var $o = $("#foo"); var $i = $('<input type="text" placeholder="Filter by">'); $i.on("keyup", function(){ $o.children("li").each(function(){ var $t = $(this); $t.toggle(-1 != $t.text().search(new RegExp($i.val(), "gi"))); }); }); $o.find("li:first").before($i); }; </script>
Explained
window.onload
: can’t use jQuery’s ready() because I’m loading it at the end of body, but DOM’s load event would work… unless jQuery is loaded asynchronously (AMD).#foo
: should really have used a class instead of an ID, and generalized the code so it would work on any/all lists. Nu.$o=$("#foo")
: saving the reference to a jQuery object wrapping the DOM element to avoid using a selector to search for it again.- Prefixing the variable name with “$” to remind that it’s not just a DOM element, but a jQuery wrapper, thus can apply jQuery’s methods on it.
$("<input>")
: creating a detached DOM element.$i.on()
: could’ve chained this method call, or even avoid the variable altogether, but, legibility?$o .find(...) .before( $("<input>") .on(...) );
Or the other way around with insertBefore. jQuery’s chaining is beautiful, but it can be too much.
on("keyup")
: runs so fast (on a short list?) that it filters as I type. Otherwise, better UX would be to wait for me to stop/pause typing. Should be easy with setTimeout…- JavaScript’s built-in String.search uses regular expressions, so
search($i.val())
is case sensitive by default. Yuck. - The input is inserted inside the ol, before the first li. Ugly! But I’m toggling that ol, like a tabbed view, so this conveniently hides the input with it. Nu.
Improvements?
- Generalize.
- Slow down and speed up: don’t run on each keypress, but only once per second, or less; don’t filter entire list at once — might choke, freeze the UI, because no reflows while scripts run. But, overkill?
- Live demo! jsFiddle?