From 66e3bb87e75e70b7186e8f10727da7ecd121a855 Mon Sep 17 00:00:00 2001 From: John Nunemaker Date: Tue, 8 Jul 2008 16:14:06 -0400 Subject: [PATCH] added my live search examples for perusing, not worth a lot on there own for anything but that --- jquery.livesearch.js | 59 +++++++++++++++++++++++++++++++ livesearch.js | 84 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 jquery.livesearch.js create mode 100644 livesearch.js diff --git a/jquery.livesearch.js b/jquery.livesearch.js new file mode 100644 index 0000000..e87ec22 --- /dev/null +++ b/jquery.livesearch.js @@ -0,0 +1,59 @@ +/* just here to make it quicker to find in reference for myself */ +(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); \ No newline at end of file diff --git a/livesearch.js b/livesearch.js new file mode 100644 index 0000000..1803ea4 --- /dev/null +++ b/livesearch.js @@ -0,0 +1,84 @@ +/* just here to make it quicker to find in reference for myself */ +var QuicksilverLiveSearch = Class.create({ + /** + * Sets up the caches and adds observers + */ + initialize: function(field, list) { + this.field = $(field); + this.list = $(list); + + if (this.field && this.list) { + this.rows = $A([]); + this.cache = $A([]); + this.setupCache(); + + // kill normal submit of form since it's live + this.form = this.field.up('form'); + this.form.observe('submit', function(e) { e.stop(); }); + + // setup observer on the search field to run the filter when typing + this.field.observe('keyup', this.filter.bindAsEventListener(this)); + + // run the filter initially for any text that may be in it + this.filter(); + } + }, + + /** + * Caches inner html of children in array for later manipulation. + */ + setupCache: function() { + // loop through immediate descendents (in this case li's) and push + // their lowercase text to the cache and the li to the rows + this.list.immediateDescendants().each(function(child) { + this.cache.push(child.innerHTML.toLowerCase()); + this.rows.push(child); + }.bind(this)); + this.cache_length = this.cache.length; + }, + + /** + * Runs the filter that only shows the rows + * that have a score based on the search term. + */ + filter: function() { + // if nothing is in the field show all the rows + if (!this.field.present()) { this.rows.invoke('show'); return; } + + // get the scores and hide the low scoring items + this.displayResults(this.getScores($F(this.field).toLowerCase())); + }, + + /** + * Hides all the rows and shows on the ones with a score over 0 + */ + displayResults: function(scores) { + // hide all rows default + this.rows.invoke('hide'); + + // show each row that had a score + scores.each(function(score) { this.rows[score[1]].show(); }.bind(this)) + }, + + /** + * Get the score of each row in the cache and return sorted + * result set of [score, index of row in this.rows] + */ + getScores: function(term) { + var scores = $A([]); + + // loop through the cache and get the score for each item + // appending them to the return set if they have a score + // greater than 0; basically building an array like this: + // [[0.69, 2], [0.33, 34], ...] where the first element is + // the string score and the second is the index of the item + // that scored that + for (var i=0; i < this.cache_length; i++) { + var score = this.cache[i].score(term); + if (score > 0) { scores.push([score, i]); } + } + + // sort the scores descending by the algorithm score (the first element in the array) + return scores.sort(function(a, b) { return b[0] - a[0]; }); + } +}); \ No newline at end of file