From f27c7c3f57223ad1d217ce93d110e34401fcb14a Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Wed, 10 Mar 2010 00:57:58 +0200 Subject: [PATCH] things are closer to done --- demo/demo.css | 14 ++ demo/demo.html | 60 +++++++ demo/demo.json | 11 ++ example.json | 6 - examples.html | 53 ------ suggest_results/jquery.suggest_results.css | 30 +++- suggest_results/jquery.suggest_results.js | 191 ++++++++++++++++----- 7 files changed, 262 insertions(+), 103 deletions(-) create mode 100644 demo/demo.css create mode 100644 demo/demo.html create mode 100644 demo/demo.json delete mode 100644 example.json delete mode 100644 examples.html diff --git a/demo/demo.css b/demo/demo.css new file mode 100644 index 0000000..03c0cd6 --- /dev/null +++ b/demo/demo.css @@ -0,0 +1,14 @@ +/* @group Reset */ + +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}.clear {clear: both;display: block;overflow: hidden;visibility: hidden;width: 0;height: 0;}.clearfix:after {clear: both;content: ' ';display: block;font-size: 0;line-height: 0;visibility: hidden;width: 0;height: 0;}* html .clearfix {height: 1%;} + +/* @end */ + +input { + border: 1px solid #999; +} + +#container { + width: 960px; + margin: 0px auto; +} \ No newline at end of file diff --git a/demo/demo.html b/demo/demo.html new file mode 100644 index 0000000..f79bbc8 --- /dev/null +++ b/demo/demo.html @@ -0,0 +1,60 @@ + + + + + + + examples + + + + + + + + + + + + + + +
+ +
+
+ + +
+
+ + +
+
+ + +
+ + + diff --git a/demo/demo.json b/demo/demo.json new file mode 100644 index 0000000..44576b5 --- /dev/null +++ b/demo/demo.json @@ -0,0 +1,11 @@ +[ + {title: "head", href: "/head", match: "head zzz"}, + {title: "headache", href: "/headache", match: "headache zzz"}, + {title: "health", href: "/health", match: "health zzz"}, + {title: "healthcare", href: "/healthcare", match: "healthcare zzz"}, + {title: "healthier", href: "/healthier", match: "healthier zzz"}, + {title: "heck", href: "/heck", match: "heck zzz"}, + {title: "hectic", href: "/hectic", match: "hectic zzz"}, + {title: "held", href: "/held", match: "held zzz"}, + {title: "hell", href: "/hell", match: "hell zzz"}, +]; \ No newline at end of file diff --git a/example.json b/example.json deleted file mode 100644 index f1fb94f..0000000 --- a/example.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - {title: "hello", url: "/hello", match: "hello dude"}, - {title: "world", url: "/world", match: "world dude"}, - {title: "foo", url: "/foo", match: "foo dude"}, - {title: "bar", url: "/bar", match: "bar dude"} -]; \ No newline at end of file diff --git a/examples.html b/examples.html deleted file mode 100644 index 2e431fa..0000000 --- a/examples.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - examples - - - - - - - - - - - - -
-
- - -
-
- - - -
-
- - - - - diff --git a/suggest_results/jquery.suggest_results.css b/suggest_results/jquery.suggest_results.css index fdf75e7..b775922 100644 --- a/suggest_results/jquery.suggest_results.css +++ b/suggest_results/jquery.suggest_results.css @@ -1,7 +1,33 @@ #suggest_results { - background: #eee; + background: #fbfbfb; + border: 1px solid #ccc; + border-top: none; display: none; position: absolute; z-index: 1000; -} \ No newline at end of file + margin: 0px; + padding: 0px; +} + #suggest_results li { + margin: 0px; + border-bottom: 1px solid #ddd; + } + #suggest_results li.first { + + } + #suggest_results li.last { + border-bottom: none; + } + #suggest_results li.result { + display: block; + } + #suggest_results li.result a { + display: block; + padding: 3px 5px; + } + #suggest_results li.result a:hover, + #suggest_results li.result.selected a { + background: #3464C9; + color: #fff; + } \ No newline at end of file diff --git a/suggest_results/jquery.suggest_results.js b/suggest_results/jquery.suggest_results.js index e67ddcc..f17a7ca 100644 --- a/suggest_results/jquery.suggest_results.js +++ b/suggest_results/jquery.suggest_results.js @@ -5,25 +5,31 @@ self.init($options); - var TAB = 9; - var RETURN = 13; - var ESC = 27; - var ARRUP = 38; - var ARRDN = 40; - return this.each(function(){ var $e = $(this); $e.focus(function(){ - self.attach($e); + self.attach($e, options); + if ($e.val().length > 0) { + self.search_timeout = self.setTimeout(function(){ + self.search($e, $options); + }, $options.delay); + }; }).blur(function(){ self.hide(); }).keyup(function(e){ + var TAB = 9; + var RETURN = 13; + var ESC = 27; + var ARRUP = 38; + var ARRDN = 40; switch(e.keyCode) { - case ARRUP: - case ARRDN: - case ESC: self.clear($e, $options); - case RETURN: - default: self.search($e, $options); + case ARRUP: self.select_prev($options); return false; + case ARRDN: self.select_next($options); return false; + case ESC: self.clear($e, $options); break; + case RETURN: self.activate_selected($options); return false; + default: + self.clearTimeout(); + self.search($e, $options); } }); }); @@ -32,7 +38,8 @@ $.fn.suggest_results.box = null; $.fn.suggest_results.attached_to = null; $.fn.suggest_results.current_results = []; - $.fn.suggest_results.selected_result = []; + $.fn.suggest_results.selected_result = null; + $.fn.suggest_results.timeout = null; $.fn.suggest_results.init = function(options){ var self = $.fn.suggest_results; @@ -45,14 +52,21 @@ $.fn.suggest_results.search = function(elm, options){ var self = $.fn.suggest_results; - var terms = (options.exact_match) ? elm.val() : elm.val().split(/\s/); + var terms = (options.exact_match) ? $.trim(elm.val()) : elm.val().split(/\s/); if (typeof(options.url) === "string" && options.url !== "") { //TODO support fetching results from server-side } else { - var results = self.filter_data(terms, options.data); + console.log(options.data); + var results = self.filter_data(terms, options.data, options); + console.log(results); + }; + self.current_results = results; + if (results.length > 0) { + self.render(results, options); + self.show(); + } else { + self.hide(); }; - self.render(results, options); - self.show(); }; $.fn.suggest_results.clear = function(elm, options){ @@ -66,11 +80,16 @@ var results_length = results.length; var html = ""; for (var i=0; i < results_length; i++) { - html += self.mustache(options.template.result, $.extend({}, {id: "suggest_result_" + i}, results[i])); + var meta = {id: "suggested_result_" + i, "class": ""}; + if (i == 0) { $.extend(meta, {"class": "first"}); }; + if (i == results_length - 1) { $.extend(meta, {"class": "last"}); }; + html += self.mustache(options.template.result, $.extend({}, meta, results[i])); }; self.box.html(""); self.box.append(html); - + $(".result", self.box).click(function(){ + self.redirect_to($("a", $(this)).attr("href")); + }); }; $.fn.suggest_results.attach = function(elm, options){ @@ -78,18 +97,25 @@ var elm_uid = self.elm_uid(elm); if (elm_uid !== self.attached_to) { var offset = elm.offset(); - - var width = elm.innerWidth(); - width += parseInt(elm.css("border-left-width"), 10) + parseInt(elm.css("border-right-width"), 10); - self.box.css("width", width + "px"); - + + // left offset self.box.css("left", offset.left + "px"); - + + // top offset var top = offset.top + elm.innerHeight(); - top += parseInt(elm.css("margin-top"), 10); top += parseInt(elm.css("border-top-width"), 10) + parseInt(elm.css("border-bottom-width"), 10); self.box.css("top", top + "px"); + // width + if (typeof(options.width) === "number" || (typeof(options.width) === "string" && options.width != "")) { + self.box.css("width", options.width); + } else { + var width = elm.innerWidth(); + width += parseInt(elm.css("border-left-width"), 10) + parseInt(elm.css("border-right-width"), 10); + width -= parseInt(self.box.css("border-left-width"), 10) + parseInt(self.box.css("border-right-width"), 10); + self.box.css("width", width + "px"); + }; + self.attached_to = elm_uid; }; }; @@ -99,32 +125,79 @@ }; $.fn.suggest_results.hide = function(){ - $.fn.suggest_results.box.hide(); + var self = $.fn.suggest_results; + self.setTimeout(function(){ + self.selected_result = null; + self.box.hide(); + }, 500); }; - $.fn.suggest_results.filter_data = function(terms, data){ - if (typeof(terms) === "string") { - terms = [terms]; + $.fn.suggest_results.select_next = function(options){ + var self = $.fn.suggest_results; + var limit = self.current_results.length; + console.log(limit); + if (limit > 0) { + if (self.selected_result === null) { + self.selected_result = 0; + $("#suggested_result_" + self.selected_result, self.box).addClass("selected"); + } else if (self.selected_result + 1 < limit) { + $(".selected", self.box).removeClass("selected"); + self.selected_result++; + $("#suggested_result_" + self.selected_result, self.box).addClass("selected"); + }; }; + return false; + }; + + $.fn.suggest_results.select_prev = function(options){ + var self = $.fn.suggest_results; + var limit = self.current_results.length; + console.log(limit); + if (limit > 0) { + if (self.selected_result === null) { + self.selected_result = limit - 1; + $("#suggested_result_" + self.selected_result, self.box).addClass("selected"); + } else if (self.selected_result > 0) { + $(".selected", self.box).removeClass("selected"); + self.selected_result--; + $("#suggested_result_" + self.selected_result, self.box).addClass("selected"); + }; + }; + return false; + }; + + $.fn.suggest_results.activate_selected = function(options){ + var self = $.fn.suggest_results; + if (self.selected_result !== null) { + self.redirect_to(self.current_results[self.selected_result].href); + }; + }; + + $.fn.suggest_results.filter_data = function(terms, data, options){ + if (typeof(terms) === "string") { terms = [terms]; }; var matched = ""; - var result = []; + var results = []; for (var i = terms.length - 1; i >= 0; i--){ var term = terms[i]; term = term.toLowerCase(); if (data !== null && typeof(term) !== "undefined" && term !== "") { - for (var i = data.length - 1; i >= 0; i--){ - var title = data[i].title.toLowerCase(); - var match = (typeof(data[i].match) !== "undefined") ? data[i].match.toLowerCase() : "" ; + var data_length = data.length; + for (var n=0; n < data_length; n++) { + var title = data[n].title.toLowerCase(); + var match = (typeof(data[n].match) !== "undefined") ? data[n].match.toLowerCase() : "" ; if (title.indexOf(term) !== -1 || match.indexOf(term) !== -1) { - if (matched.indexOf(":" + i + ":") == -1) { - result.push(data[i]); - matched += ":" + i + ":"; + if (matched.indexOf(":" + n + ":") == -1) { + results.push(data[n]); + matched += ":" + n + ":"; + if (results.length >= options.limit) { + return results; + }; }; }; }; }; }; - return result; + return results; }; $.fn.suggest_results.elm_uid = function(elm){ @@ -144,14 +217,48 @@ return string; }; + $.fn.suggest_results.redirect_to = function(url, location){ + if (typeof(location) == "undefined") { + location = window.location; + }; + var redirect_to = ""; + if (url.match(/.+\:\/\/.+/) === null) { + redirect_to += location.protocol + "//"; + redirect_to += location.hostname; + if (location.port != "") { redirect_to += ":" + location.port; }; + if (url.charAt(0) !== "/") { + redirect_to += location.pathname.substr(0, location.pathname.lastIndexOf("/")+1); + }; + window.location.href = redirect_to + url; + } else { + window.location.href = url; + }; + }; + + $.fn.suggest_results.setTimeout = function(callback, delay){ + var self = $.fn.suggest_results; + self.clearTimeout(); + self.timeout = setTimeout(callback, delay); + }; + + $.fn.suggest_results.clearTimeout = function(){ + var self = $.fn.suggest_results; + if (self.timeout !== null) { + clearTimeout(self.timeout); + self.timeout = null; + }; + }; + $.fn.suggest_results.defaults = { + delay: 150, + limit: 6, data: null, - exact_match: false, + exact_match: true, template: { container_id: "suggest_results", - container: '
', - result: '{{title}}', - category: '{{category}}' //TODO add support for categories + container: '
    ', + result: '
  1. {{title}}
  2. ', + category: '{{category}}' //TODO add support for categories } };