Live Search with QuickSilver Style (for jQuery)

I’ve been palling around with jQuery quite a bit lately. The other day I whipped together my first jQuery plugin and things finally clicked. In the comments of the original post, I mentioned doing a jQuery port.

Lucky for you, I ran into some free time this weekend. Without any further ado, I will now link you to a demo and give you some code to peruse.

(function($) {  
	var self = null;
 	
	$.fn.liveUpdate = function(list) {	
		return this.each(function() {
			new $.liveUpdate(this, list);
		});
	};
	
	$.liveUpdate = function (e, list) {
		this.field = $(e);
		this.list  = $('#' + list);
		if (this.list.length > 0) {
			this.init();
		}
	};
	
	$.liveUpdate.prototype = {
		init: function() {
			var self = this;
			this.setupCache();
			this.field.parents('form').submit(function() { return false; });
			this.field.keyup(function() { self.filter(); });
			self.filter();
		},
		
		filter: function() {
			if ($.trim(this.field.val()) == '') { this.list.children('li').show(); return; }
			this.displayResults(this.getScores(this.field.val().toLowerCase()));
		},
		
		setupCache: function() {
			var self = this;
			this.cache = [];
			this.rows = [];
			this.list.children('li').each(function() {
				self.cache.push(this.innerHTML.toLowerCase());
				self.rows.push($(this));
			});
			this.cache_length = this.cache.length;
		},
		
		displayResults: function(scores) {
			var self = this;
			this.list.children('li').hide();
			$.each(scores, function(i, score) { self.rows[score[1]].show(); });
		},
		
		getScores: function(term) {
			var scores = [];
			for (var i=0; i < this.cache_length; i++) {
				var score = this.cache[i].score(term);
				if (score > 0) { scores.push([score, i]); }
			}
			return scores.sort(function(a, b) { return b[0] - a[0]; });
		}
	}
})(jQuery);

The cool thing about writing the same functionality with two different libraries is now you can compare a bit to see which implementation you like better. :)

If you want to learn more about why I did this, read the original post.

Update: The man himself, John Resig, has made the code a bit more efficient and jQuery-ish.

33 Comments

  • Jan

    Awesome, excellent work!

    The first technique using prototype was really nice, but using jQuery for the Quicksilver Search makes it even more attractive.

  • Adrian

    You need many beers bought for you for creating this code.

    You rule.

    Thanks. :o)

  • Matt Wilcox

    Thanks very much, this is another thing to add to my list of ‘cool things to use in my new site design’.

  • Arthus Erea

    You know what would be an even cooler feature? Add highlighting (like QuickSilver).

    That is, highlight the matched characters in the string… that’d truly make it awesome.

  • Fabrice

    May I suggest to edit your code a bit [line 28] to allow the use of both plugins together :
    if ($.trim(this.field.val()) == ‘’ || this.field.hasClass(“blank”)) { this.list.children(’li’).show(); return; }

  • Fabrice

    My suggestion doesn’t work completly, livesearch seams to focus on the field ruining the labelize work.

  • Wayde Christie

    Great work John – thanks for sharing.

    I’ll be stealing this for our new blog this week, so I’ll drop you a link when it’s ready for prime time. If I come across any potential optimisations or ideas I’ll return the favour :)

    Thanks again!

  • Brendan Falkowski

    Sweet, saving this for a del.icio.us weekend.

  • Muhammad Haris

    Absolutely love it, John. Thanks for writing it. Bookmarked!

  • Marek Nowak

    Really, really nice code. Thanks.

  • John Nunemaker

    @Adrian – I agree. When can we make that happen? :)

    @Arthus – Highlighting and tab/up/down key events are things I’d like to put in.

    @Everyone Else – Thanks! Glad you are finding it helpful.

  • Daniel

    Nice John, looks exactly like the search on dbelement.com in their Stripr and Reader apps.
    Thanks for this!

  • Benjamin Hunsaker

    Great job!

  • Ilnur

    Good Work! Thanks John ;)

  • Fikosa

    Thanks for sharing this code, it is really helpfull

  • Marry Mellow

    Great work – thanks for sharing this part of code.

  • Molly Gert

    Excellent work! Thanks John.

  • Rick

    Hi John! I love your code! I took a look at your demo and the code for it. But how should one go about to hide the list instead of showing it from the beginning? Also, can you style the search with css?

  • Wayde Christie

    Point me to a “Donate” link!

  • trif3cta

    Perfect timing, I can’t wait to use this. Many thanks!

  • Jerry Freeline

    Thats really smart, it has a real “air of speed” about it… I know theres not much processing to be done, but it just feels so fast seeing the search updating on the screen like that. I will definitely be using this in the future… so many uses you could put this to, thanks!

  • rouss

    point me to the donate link, John!

  • rouss

    John, what if i need to search within several lists? Is it possible?

  • John Nunemaker

    @rouss – Yes it is possible.

  • Sean O

    There’s also a more traditional livesearch, with a few more options: Rik Lomas’ QuickSearch:
    http://rikrikrik.com/jquery/quicksearch/
    I’d have to stay with QuickSearch in my corporate web app for now though, as most of my users would be confused by the results of some common searches (e.g. searching for “good” yields many unrelated hits)

    That being said, this seems to work well, is fast, and the code is compact and clean. Nice work.

  • Mark

    Where is the donate link? I cant see it… :(

  • Eric

    @John Nunemaker – can you give example?

  • Olly

    This is excellent. One enhancement I’d love to make (but can’t figure out how) is to filter only after a pause of, say, 500ms, as opposed to on every key up. A key down would reset the timer and this would make it more reponsive for large volumes of data (I do have a use for this).

    Is there a way to integrate setTimeout into this?

  • Jeff Myers

    I have absolutely no idea what you’re talking about, but you sure are cute!

  • Michael Web

    Great work – thanks for sharing this part of code.

  • hungertobel

    This is a great tutorial… I actually just found kinda the same just using prototype on a german blog… if you wanna check it out here’s the link: http://91media.de/91media/blog/article/23/Live_Suche_mit_Prototypejs

  • SC

    Would it be possible to have the user click on keywords / buttons to filter instead of having the user type / enter in text?

  • SC

    Would it be possible to have the user click on keywords / buttons to filter instead of having the user type / enter in text?