AutoSuggest: more UI tweaks regarding typing after selecting
authorLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 13 Feb 2012 19:37:18 +0000 (14:37 -0500)
committerMike Rylander <mrylander@gmail.com>
Mon, 20 Feb 2012 19:22:22 +0000 (14:22 -0500)
Avoid highlighting text in the textbox part of the autosuggest widget,
so that if the user wants to type more after selecting a suggestion with the
arrow keys, s/he doesn't clobber the existing part.

Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Signed-off-by: Mike Rylander <mrylander@gmail.com>

Open-ILS/web/js/dojo/openils/widget/AutoSuggest.js

index f7e6283..e145c2d 100644 (file)
@@ -5,15 +5,49 @@ if (!dojo._hasResource["openils.widget.AutoSuggest"]) {
     dojo.require("dijit.form.ComboBox");
     dojo.require("openils.AutoSuggestStore");
 
-    /* Here's a monkey patch to assist in making clicking on a suggestion lead
-     * directly to search. Relies on overridden _startSearch() in the widget
-     * below. */
-    var _orig_onMouseUp = dijit.form._ComboBoxMenu.prototype._onMouseUp;
-    dijit.form._ComboBoxMenu.prototype._onMouseUp = function(evt) {
-        if (this.parent_widget)
-            this.parent_widget.mouse_used_most_recently = true;
-        dojo.hitch(this, _orig_onMouseUp)(evt);
-    };
+    /* Do some monkey-patching on dijit.form._ComboBoxMenu to make AutoSuggest
+     * widget behavior more Google-like, and do it within a function to prevent
+     * namespace pollution. */
+
+    (function() {
+        var victim = dijit.form._ComboBoxMenu;
+
+        /* Assist in making clicking on a suggestion lead directly to search.
+         * Relies on overridden _startSearch() in the widget below. */
+        var _orig_onMouseUp = victim.prototype._onMouseUp;
+        victim.prototype._onMouseUp = function(evt) {
+            if (this.parent_widget)
+                this.parent_widget.mouse_used_most_recently = true;
+            dojo.hitch(this, _orig_onMouseUp)(evt);
+        };
+
+        /* These next two, taken together, prevent the user from having to
+         * type space twice after selecting (with arrow keys) an item from
+         * the autosuggestions. */
+        var _orig_handleKey = victim.prototype.handleKey;
+        victim.prototype.handleKey = function(key) {
+            /* Testing for this.parent_widget's existence allows our patch
+             * not to be intrusive if /other/ widgets (besides
+             * openils.widget.AutoSuggest) are using d.f._ComboBoxMenu on the
+             * same page. */
+            if (this.parent_widget && key == " ") {
+                this.just_had_space = true;
+            } else {
+                this.just_had_space = false;
+                return dojo.hitch(this, _orig_handleKey)(key);
+            }
+        }
+
+        var _orig_getHighlightedOption = victim.prototype.getHighlightedOption;
+        victim.prototype.getHighlightedOption = function() {
+            if (this.just_had_space) {
+                this.just_had_space = false;
+                return null;
+            } else {
+                return dojo.hitch(this, _orig_getHighlightedOption)();
+            }
+        }
+    })();
 
     dojo.declare(
         "openils.widget.AutoSuggest", [dijit.form.ComboBox], {
@@ -68,18 +102,29 @@ if (!dojo._hasResource["openils.widget.AutoSuggest"]) {
                 this._popupWidget.parent_widget = this;
             },
 
+            "_setCaretPos": function(element, loc) {
+                /* selects nothing, puts cursor at the end of the string */
+                dijit.selectInputText(element, element.value.length);
+            },
+
+            "_autoCompleteText": function() {
+                var orig = dijit.selectInputText;
+                dijit.selectInputText = function() { };
+
+                this.inherited(arguments);
+
+                dijit.selectInputText = orig;
+            },
+
             "onChange": function(value) {
                 if (typeof value.field == "number") {
                     this._update_search_type_selector(value.field);
 
                     /* If onChange fires and the following condition is true,
                      * it must mean that the user clicked on an actual
-                     * suggestion with the mouse.  To match the behavior
-                     * of well known autosuggesting things out there (like
-                     * with Google search), we should actually perform our
-                     * search now.  We also perform our search when the user
-                     * presses enter (handled elsewhere), but not when the user
-                     * selects something and tabs out.  */
+                     * suggestion with the mouse.  We also perform our search
+                     * when the user presses enter (handled elsewhere), but not
+                     * when the user selects something and keeps typing. */
                     if (this.mouse_used_most_recently)
                         this.submitter();
                 }
@@ -95,8 +140,7 @@ if (!dojo._hasResource["openils.widget.AutoSuggest"]) {
                     this.type_selector = dojo.byId(this.type_selector);
 
                 /* Save the instantiator from needing to specify same thing
-                 * twice, even though we need it and the store needs it too.
-                 */
+                 * twice, even though we need it and the store needs it too. */
                 if (this.type_selector && !this.store_args.type_selector)
                     this.store_args.type_selector = this.type_selector;