r3388 committed - autocomplete: implemented focus behaviour (update input when moving th...
Revision: 3388
Author: joern.zaefferer
Date: Fri Oct 23 09:20:42 2009
Log: autocomplete: implemented focus behaviour (update input when moving
the menu focus, put back the entered value when moving "back")
http://code.google.com/p/jquery-ui/source/detail?r=3388
Modified:
/branches/dev/ui/jquery.ui.autocomplete.js
/branches/dev/ui/jquery.ui.menu.js
=======================================
--- /branches/dev/ui/jquery.ui.autocomplete.js Fri Oct 23 08:18:50 2009
+++ /branches/dev/ui/jquery.ui.autocomplete.js Fri Oct 23 09:20:42 2009
@@ -28,9 +28,11 @@
break;
case $.ui.keyCode.UP:
self.move("previous");
+ event.preventDefault();
break;
case $.ui.keyCode.DOWN:
self.move("next");
+ event.preventDefault();
break;
case $.ui.keyCode.ENTER:
self.select();
@@ -68,8 +70,8 @@
if ($.isArray(this.options.source)) {
var array = this.options.source;
this.source = function(request, response) {
- // TODO escape regex characters
- var matcher = new RegExp(request.term, "i");
+ // escape regex characters
+ var matcher = new
RegExp(request.term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|
\\])/gi, "\\$1"), "i");
return $.grep(array, function(value) {
return matcher.test(value)
});
@@ -92,6 +94,7 @@
if (this._trigger("search") === false)
return;
self.element.addClass("ui-autocomplete-loading");
+ self.term = value;
function response(content) {
if (content.length) {
self._trigger("open");
@@ -115,7 +118,7 @@
clearTimeout(this.closing);
if (this.menu) {
this._trigger("close");
- this.menu.remove();
+ this.menu.element.remove();
this.menu = null;
}
if (this.previous != this.element.val()) {
@@ -141,9 +144,9 @@
suggest: function(items) {
items = this.normalize(items);
- this.menu && this.menu.remove();
+ this.menu && this.menu.element.remove();
var self = this;
- var ul = this.menu = $("<ul/>");
+ var ul = $("<ul/>");
$.each(items, function(index, item) {
$("<li/>").data("item.autocomplete", item).append("<a>" + item.label
+ "</a>").appendTo(ul);
});
@@ -152,7 +155,8 @@
}).appendTo(document.body).menu({
focus: function(event, ui) {
self._trigger("focus", null, { item: ui.item.data("item.autocomplete")
});
- // TODO update input value and revert back to the input when
focus "moves back" to the input
+ // use label or result?
+ self.element.val(ui.item.data("item.autocomplete").result);
},
selected: function(event, ui) {
var data = ui.item.data("item.autocomplete");
@@ -168,6 +172,7 @@
at: "left bottom",
of: this.element
});
+ this.menu = ul.data("menu");
if (ul.width() <= this.element.width()) {
ul.width(this.element.width());
}
@@ -178,18 +183,23 @@
this.search();
return;
}
- this.menu.menu(direction);
+ if (this.menu.first() && direction == "previous" || this.menu.last() &&
direction == "next") {
+ this.element.val(this.term);
+ this.menu.deactivate();
+ return;
+ }
+ this.menu[direction]();
},
select: function() {
if (!this.menu)
return;
- this.menu.menu("select");
+ this.menu.select();
},
widget: function() {
// return empty jQuery object when menu isn't initialized yet
- return this.menu || $([]);
+ return this.menu && this.menu.element || $([]);
}
});
=======================================
--- /branches/dev/ui/jquery.ui.menu.js Sat Oct 17 05:04:47 2009
+++ /branches/dev/ui/jquery.ui.menu.js Fri Oct 23 09:20:42 2009
@@ -38,6 +38,11 @@
},
deactivate: function(item) {
+ if (!item && this.activeitem) {
+ this.deactivate(this.activeitem);
+ this.activeitem = null;
+ return;
+ }
item.removeClass("ui-state-hover").removeAttr("id", "ui-active-menuitem");
},
@@ -49,6 +54,14 @@
this.move("prev", "li:last");
},
+ first: function() {
+ return this.activeitem && !this.activeitem.parent().prev().length;
+ },
+
+ last: function() {
+ return this.activeitem && !this.activeitem.parent().next().length;
+ },
+
move: function(direction, edge) {
if (!this.activeitem) {
this.activate(this.element.children(edge).children("a"));