[FIX] search view: autocomplete: further improve support for rapid barcode scanning
This patch removes the asynchronous code that was still used to open the autocompletion drawer. Even with the setTimeout delay forced to 0, the asynchronous handling meant the final ENTER keyUp event could be processed before the opening of the autocompletion drawer related to the last key pressed. This would trigger the search with the search string of the previous autocompletion popup, missing the last few keys. Also handle ENTER at keyDown, because in some rare cases a barcode scanner may emit only the keyDown event for ENTER, without the corresponding keyUp, causing a merge of two successive scanned barcodes. Based on many tests conducted with different barcode scanners, the only thing that is guaranteed is the correct order of the keyPress events for all regular characters, and the fact that the ENTER keyDown and/or keyUp will always be sent after them. All other events can be mixed or simply missing if you make a rapid succession of scans, especially if done with a long series of barcodes. Scanners tested (with 1ms data transmission delay): - Honeywell Eclipse MS5145 - Dacomex Slim 50mm CCD scanner
This commit is contained in:
parent
db45099a27
commit
df4bd736f1
|
@ -490,7 +490,6 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
|
|||
this.autocomplete = new instance.web.search.AutoComplete(this, {
|
||||
source: this.proxy('complete_global_search'),
|
||||
select: this.proxy('select_completion'),
|
||||
delay: 0,
|
||||
get_search_string: function () {
|
||||
return self.$('div.oe_searchview_input').text();
|
||||
},
|
||||
|
@ -2337,8 +2336,6 @@ instance.web.search.AutoComplete = instance.web.Widget.extend({
|
|||
// options.source: function ({term:query}, callback). This function will be called to
|
||||
// obtain the search results corresponding to the query string. It is assumed that
|
||||
// options.source will call callback with the results.
|
||||
// options.delay: delay in millisecond before calling source. Useful if you don't want
|
||||
// to make too many rpc calls
|
||||
// options.select: function (ev, {item: {facet:facet}}). Autocomplete widget will call
|
||||
// that function when a selection is made by the user
|
||||
// options.get_search_string: function (). This function will be called by autocomplete
|
||||
|
@ -2347,15 +2344,14 @@ instance.web.search.AutoComplete = instance.web.Widget.extend({
|
|||
this._super(parent);
|
||||
this.$input = parent.$el;
|
||||
this.source = options.source;
|
||||
this.delay = options.delay;
|
||||
this.select = options.select,
|
||||
this.select = options.select;
|
||||
this.get_search_string = options.get_search_string;
|
||||
this.width = options.width || 400;
|
||||
|
||||
this.current_result = null;
|
||||
|
||||
this.searching = true;
|
||||
this.search_string = null;
|
||||
this.search_string = '';
|
||||
this.current_search = null;
|
||||
},
|
||||
start: function () {
|
||||
|
@ -2367,10 +2363,8 @@ instance.web.search.AutoComplete = instance.web.Widget.extend({
|
|||
ev.preventDefault();
|
||||
return;
|
||||
}
|
||||
// ENTER is caugth at KeyUp rather than KeyDown to avoid firing
|
||||
// before all regular keystrokes have been processed
|
||||
if (ev.which === $.ui.keyCode.ENTER) {
|
||||
if (self.current_result && self.get_search_string().length) {
|
||||
if (self.search_string.length) {
|
||||
self.select_item(ev);
|
||||
}
|
||||
return;
|
||||
|
@ -2379,29 +2373,31 @@ instance.web.search.AutoComplete = instance.web.Widget.extend({
|
|||
if (self.search_string !== search_string) {
|
||||
if (search_string.length) {
|
||||
self.search_string = search_string;
|
||||
setTimeout(function () { self.initiate_search(search_string);}, self.delay);
|
||||
self.initiate_search(search_string);
|
||||
} else {
|
||||
self.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.$input.on('keypress', function (ev) {
|
||||
self.search_string = self.get_search_string() + String.fromCharCode(ev.which);
|
||||
self.search_string = self.search_string + String.fromCharCode(ev.which);
|
||||
if (self.search_string.length) {
|
||||
self.searching = true;
|
||||
var search_string = self.search_string;
|
||||
setTimeout(function () { self.initiate_search(search_string);}, self.delay);
|
||||
self.initiate_search(search_string);
|
||||
} else {
|
||||
self.close();
|
||||
}
|
||||
});
|
||||
this.$input.on('keydown', function (ev) {
|
||||
switch (ev.which) {
|
||||
case $.ui.keyCode.ENTER:
|
||||
|
||||
// TAB and direction keys are handled at KeyDown because KeyUp
|
||||
// is not guaranteed to fire.
|
||||
// See e.g. https://github.com/aef-/jquery.masterblaster/issues/13
|
||||
case $.ui.keyCode.TAB:
|
||||
if (self.current_result && self.get_search_string().length) {
|
||||
if (self.search_string.length) {
|
||||
self.select_item(ev);
|
||||
}
|
||||
break;
|
||||
|
@ -2532,7 +2528,7 @@ instance.web.search.AutoComplete = instance.web.Widget.extend({
|
|||
},
|
||||
close: function () {
|
||||
this.current_search = null;
|
||||
this.search_string = null;
|
||||
this.search_string = '';
|
||||
this.searching = true;
|
||||
this.$el.hide();
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue