]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/widget/AutoSuggest.js
LP2045292 Color contrast for AngularJS patron bills
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / widget / AutoSuggest.js
1 if (!dojo._hasResource["openils.widget.AutoSuggest"]) {
2     dojo.provide("openils.widget.AutoSuggest");
3     dojo._hasResource["openils.widget.AutoSuggest"] = true;
4
5     dojo.require("dijit.form.ComboBox");
6     dojo.require("openils.AutoSuggestStore");
7
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. */
11
12     (function() {
13         var victim = dijit.form._ComboBoxMenu;
14
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);
22         };
23
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
32              * same page. */
33             if (this.parent_widget && key == " ") {
34                 this.just_had_space = true;
35             } else {
36                 this.just_had_space = false;
37                 return dojo.hitch(this, _orig_handleKey)(key);
38             }
39         }
40
41         var _orig_getHighlightedOption = victim.prototype.getHighlightedOption;
42         victim.prototype.getHighlightedOption = function() {
43             if (this.just_had_space) {
44                 this.just_had_space = false;
45                 return null;
46             } else {
47                 return dojo.hitch(this, _orig_getHighlightedOption)();
48             }
49         }
50     })();
51
52     dojo.declare(
53         "openils.widget.AutoSuggest", [dijit.form.ComboBox], {
54
55             "scrollOnFocus": false,
56             "labelAttr": "match",
57             "labelType": "html",
58             "searchAttr": "term",
59             "hasDownArrow": false,
60             "autoComplete": false,
61             "searchDelay": 200,
62
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 */
66
67             "store_args": {},
68
69             "mouse_used_most_recently": false,
70
71             "_update_search_type_selector": function(id) {  /* cmf id */
72                 if (!this.store.cm_cache.is_done) {
73                     console.warn(
74                         "can't update search type selector; " +
75                         "store doesn't have config.metabib_* caches available"
76                     );
77                     return;
78                 }
79
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; }),
85                     search_class
86                 );
87
88                 if (exact > 0) {
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] ==
93                                 f.field_class) {
94                             selector.selectedIndex = i;
95                             break;
96                         }
97                     }
98                 }
99             },
100
101             "_startSearch": function() {
102                 this.inherited(arguments);
103                 this._popupWidget.parent_widget = this;
104             },
105
106             "_setCaretPos": function(element, loc) {
107                 /* selects nothing, puts cursor at the end of the string */
108                 dijit.selectInputText(element, element.value.length);
109             },
110
111             "_autoCompleteText": function() {
112                 var orig = dijit.selectInputText;
113                 dijit.selectInputText = function() { };
114
115                 this.inherited(arguments);
116
117                 dijit.selectInputText = orig;
118             },
119
120             "onChange": function(value) {
121                 if (typeof value.field == "number") {
122                     this._update_search_type_selector(value.field);
123
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)
130                         this.submitter();
131                 }
132             },
133
134             "postMixInProperties": function() {
135                 this.inherited(arguments);
136
137                 if (typeof this.submitter == "string")
138                     this.submitter = dojo.hitch(this, this.submitter);
139
140                 if (typeof this.type_selector == "string")
141                     this.type_selector = dojo.byId(this.type_selector);
142
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;
147
148                 this.store = new openils.AutoSuggestStore(this.store_args);
149             },
150
151             "postCreate": function() {
152                 this.inherited(arguments);
153
154                 dojo.connect(
155                     this, "onKeyPress", this, function(evt) {
156                         this.mouse_used_most_recently = false;
157                         if (evt.keyCode == dojo.keys.ENTER)
158                             this.submitter();
159                     }
160                 );
161             }
162         }
163     );
164 }