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: '{{title}}',
+ category: '{{category}}' //TODO add support for categories
}
};