Poor Man’s List Filter — Dissected

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

  1. 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).
  2. #foo: should really have used a class instead of an ID, and generalized the code so it would work on any/all lists. Nu.
  3. $o=$("#foo"): saving the reference to a jQuery object wrapping the DOM element to avoid using a selector to search for it again.
  4. 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.
  5. $("<input>"): creating a detached DOM element.
  6. $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.

  7. 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…
  8. JavaScript’s built-in String.search uses regular expressions, so search($i.val()) is case sensitive by default. Yuck.
  9. 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?

  1. Generalize.
  2. 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?
  3. Live demo! jsFiddle?


Comments are closed.