1 if (!dojo._hasResource["openils.widget.AutoSuggest"]) {
2 dojo.provide("openils.widget.AutoSuggest");
3 dojo._hasResource["openils.widget.AutoSuggest"] = true;
5 dojo.require("dijit.form.ComboBox");
6 dojo.require("openils.AutoSuggestStore");
8 /* Do some monkey-patching on dijit.form._ComboBoxMenu to make AutoSuggest
9 * widget behavior more Google-like, and do it within a function to prevent
10 * namespace pollution. */
13 var victim = dijit.form._ComboBoxMenu;
15 /* Assist in making clicking on a suggestion lead directly to search.
16 * Relies on overridden _startSearch() in the widget below. */
17 var _orig_onMouseUp = victim.prototype._onMouseUp;
18 victim.prototype._onMouseUp = function(evt) {
19 if (this.parent_widget)
20 this.parent_widget.mouse_used_most_recently = true;
21 dojo.hitch(this, _orig_onMouseUp)(evt);
24 /* These next two, taken together, prevent the user from having to
25 * type space twice after selecting (with arrow keys) an item from
26 * the autosuggestions. */
27 var _orig_handleKey = victim.prototype.handleKey;
28 victim.prototype.handleKey = function(key) {
29 /* Testing for this.parent_widget's existence allows our patch
30 * not to be intrusive if /other/ widgets (besides
31 * openils.widget.AutoSuggest) are using d.f._ComboBoxMenu on the
33 if (this.parent_widget && key == " ") {
34 this.just_had_space = true;
36 this.just_had_space = false;
37 return dojo.hitch(this, _orig_handleKey)(key);
41 var _orig_getHighlightedOption = victim.prototype.getHighlightedOption;
42 victim.prototype.getHighlightedOption = function() {
43 if (this.just_had_space) {
44 this.just_had_space = false;
47 return dojo.hitch(this, _orig_getHighlightedOption)();
53 "openils.widget.AutoSuggest", [dijit.form.ComboBox], {
55 "scrollOnFocus": false,
59 "hasDownArrow": false,
60 "autoComplete": false,
63 /* Don't forget to these two parameters when instantiating. */
64 "submitter": function() { console.log("No submitter connected"); },
65 "type_selector": null, /* see openils.AutoSuggestStore for docs */
69 "mouse_used_most_recently": false,
71 "_update_search_type_selector": function(id) { /* cmf id */
72 if (!this.store.cm_cache.is_done) {
74 "can't update search type selector; " +
75 "store doesn't have config.metabib_* caches available"
80 var f = this.store.cm_cache.cmf[id];
81 var selector = this.type_selector;
82 var search_class = f.field_class + "|" + f.name;
83 var exact = dojo.indexOf(
84 dojo.map(selector.options, function(o) { return o.value; }),
89 selector.selectedIndex = exact;
90 } else { /* settle for class match if we can get it */
91 for (var i = 0; i < selector.options.length; i++) {
92 if (selector.options[i].value.split("|")[0] ==
94 selector.selectedIndex = i;
101 "_startSearch": function() {
102 this.inherited(arguments);
103 this._popupWidget.parent_widget = this;
106 "_setCaretPos": function(element, loc) {
107 /* selects nothing, puts cursor at the end of the string */
108 dijit.selectInputText(element, element.value.length);
111 "_autoCompleteText": function() {
112 var orig = dijit.selectInputText;
113 dijit.selectInputText = function() { };
115 this.inherited(arguments);
117 dijit.selectInputText = orig;
120 "onChange": function(value) {
121 if (typeof value.field == "number") {
122 this._update_search_type_selector(value.field);
124 /* If onChange fires and the following condition is true,
125 * it must mean that the user clicked on an actual
126 * suggestion with the mouse. We also perform our search
127 * when the user presses enter (handled elsewhere), but not
128 * when the user selects something and keeps typing. */
129 if (this.mouse_used_most_recently)
134 "postMixInProperties": function() {
135 this.inherited(arguments);
137 if (typeof this.submitter == "string")
138 this.submitter = dojo.hitch(this, this.submitter);
140 if (typeof this.type_selector == "string")
141 this.type_selector = dojo.byId(this.type_selector);
143 /* Save the instantiator from needing to specify same thing
144 * twice, even though we need it and the store needs it too. */
145 if (this.type_selector && !this.store_args.type_selector)
146 this.store_args.type_selector = this.type_selector;
148 this.store = new openils.AutoSuggestStore(this.store_args);
151 "postCreate": function() {
152 this.inherited(arguments);
155 this, "onKeyPress", this, function(evt) {
156 this.mouse_used_most_recently = false;
157 if (evt.keyCode == dojo.keys.ENTER)