summaryrefslogtreecommitdiff
path: root/javascript/live_search.js
diff options
context:
space:
mode:
Diffstat (limited to 'javascript/live_search.js')
-rwxr-xr-x[-rw-r--r--]javascript/live_search.js147
1 files changed, 77 insertions, 70 deletions
diff --git a/javascript/live_search.js b/javascript/live_search.js
index 42ebfbc..70dea50 100644..100755
--- a/javascript/live_search.js
+++ b/javascript/live_search.js
@@ -1,70 +1,77 @@
-/*
-Written by: Adam Crownoble (adam@bryan.edu)
-Date: April 3 2006
-License: LGPL (http://www.gnu.org/copyleft/lesser.html)
-*/
-
-var LiveSearch = Class.create();
-LiveSearch.prototype = {
- initialize: function(searchBox, results) {
- this.form = searchBox.form;
- this.searchBox = searchBox;
- this.results = results;
- this.url = this.form.action;
- this.method = this.form.method;
- this.stopSubmit = true;
- this.searchString = this.searchBox.value;
- this.starterText = this.searchString;
- this.searchingMessage = 'Searching...';
- this.minLength = 3;
- this.timeoutID = 0;
- this.delay = 500;
-
- Event.observe(this.form, 'submit', this.submit.bind(this));
- Event.observe(this.searchBox, 'keyup', this.update.bind(this));
- Event.observe(this.searchBox, 'focus', this.handleStarterText.bind(this));
- Event.observe(this.searchBox, 'blur', this.handleStarterText.bind(this));
-
- this.form.reset();
- },
-
- handleStarterText: function(event) {
- switch(event.type) {
- case 'focus':
- if(this.searchBox.value == this.starterText) {
- Field.clear(this.searchBox);
- }
- break;
-
- case 'blur':
- if(this.searchBox.value == '') {
- this.searchBox.value = this.starterText;
- }
- break;
- }
- },
-
- update: function() {
- if(this.searchString != this.searchBox.value && this.searchBox.value != this.starterText) {
-
- this.searchString = this.searchBox.value;
- clearTimeout(this.timeoutID);
-
- if(this.searchString.length >= this.minLength) {
- this.results.innerHTML = this.searchingMessage;
- this.timeoutID = setTimeout(this.search.bind(this), this.delay);
- } else {
- this.results.innerHTML = '';
- }
- }
- },
-
- search: function() {
- var parameters = Form.serialize(this.form);
- var ajax = new Ajax.Updater(this.results, this.url, { method: this.method, parameters: parameters });
- },
-
- submit: function(event) {
- if(this.stopSubmit) { Event.stop(event); }
- }
-};
+(function ($) {
+ 'use strict';
+
+ /**
+ * LiveSearch - debounced keyup search with JSON results rendered into a container.
+ *
+ * @param {string} inputSel - jQuery selector for the text input
+ * @param {string} resultsSel - jQuery selector for the results container div
+ * @param {string} url - endpoint that accepts ?highlight=<term> and returns
+ * JSON [{title, href, type}, ...]
+ */
+ function LiveSearch(inputSel, resultsSel, url) {
+ var $input = $(inputSel);
+ var $results = $(resultsSel);
+ var lastVal = '';
+ var minLen = 3;
+ var delay = 400;
+ var timer = 0;
+
+ if (!$input.length || !$results.length) { return; }
+
+ $input
+ .on('focus', function () {
+ if (this.value === this.defaultValue) { this.value = ''; }
+ })
+ .on('blur', function () {
+ if (this.value === '') { this.value = this.defaultValue; }
+ })
+ .on('keyup', function () {
+ var val = $.trim($input.val());
+ if (val === lastVal) { return; }
+ lastVal = val;
+ clearTimeout(timer);
+ if (val.length >= minLen) {
+ $results.text('Searching…');
+ timer = setTimeout(doSearch, delay);
+ } else {
+ $results.empty();
+ }
+ });
+
+ $input.closest('form').on('submit', function (e) {
+ e.preventDefault();
+ doSearch();
+ });
+
+ function esc(s) {
+ return $('<span>').text(s).html();
+ }
+
+ function doSearch() {
+ var val = $.trim($input.val());
+ if (!val || val === $input[0].defaultValue) { return; }
+ $.getJSON(url, { highlight: val })
+ .done(function (items) {
+ if (!items || !items.length) {
+ $results.html('<p>No results.</p>');
+ return;
+ }
+ var html = '<ul>';
+ $.each(items, function (i, r) {
+ html += '<li><a href="' + esc(r.href) + '">' + esc(r.title) + '</a>';
+ if (r.type) { html += ' <small>' + esc(r.type) + '</small>'; }
+ html += '</li>';
+ });
+ html += '</ul>';
+ $results.html(html);
+ })
+ .fail(function () {
+ $results.html('<p>Search unavailable.</p>');
+ });
+ }
+ }
+
+ window.LiveSearch = LiveSearch;
+
+}(jQuery));