Load autocomplete only on display of Char widget

Keeping the autocomplete always up to date is very expensive especially for
large list because the method is called once per field for each record.
Indeed autocomplete is only needed when the Char widget is displayed. So we
could just load it at display and keep it up to date when fields are changed.

issue6167
review31871002
This commit is contained in:
Cédric Krier committed 2017-01-13 20:04:53 +01:00
1 parent 667b387bdd
commit 505d770a11
2 files changed
+21 -37

No files matched your search

+5 -28
View File
@@ -727,7 +727,6 @@
var name, value;
var rec_named_fields = ['many2one', 'one2one', 'reference'];
var later = {};
var promises = [];
var fieldnames = [];
for (name in values) {
if (!values.hasOwnProperty(name)) {
@@ -769,17 +768,10 @@
this.model.fields[name].set(this, value);
this._loaded[name] = true;
}
for (var fname in this.model.fields) {
var field = this.model.fields[fname];
if (field.description.autocomplete &&
field.description.autocomplete.length > 0) {
promises.push(this.do_autocomplete(fname));
}
}
if (validate) {
promises.push(this.validate(fieldnames, true));
return this.validate(fieldnames, true);
}
return jQuery.when.apply(jQuery, promises);
return jQuery.when();
},
get: function() {
var value = {};
@@ -825,16 +817,6 @@
this.model.fields[name].set_client(this, value, force_change);
},
default_get: function(rec_name) {
var dfd = jQuery.Deferred();
var promises = [];
// Ensure promisses is filled before default_get is resolved
for (var fname in this.model.fields) {
var field = this.model.fields[fname];
if (field.description.autocomplete &&
field.description.autocomplete.length > 0) {
promises.push(this.do_autocomplete(fname));
}
}
if (!jQuery.isEmptyObject(this.model.fields)) {
var context = this.get_context();
if (context.default_rec_name === undefined) {
@@ -842,7 +824,7 @@
}
var prm = this.model.execute('default_get',
[Object.keys(this.model.fields)], context);
prm.then(function(values) {
return prm.then(function(values) {
if (this.group.parent &&
this.group.parent_name in this.group.model.fields) {
var parent_field =
@@ -857,15 +839,10 @@
this.group.parent.id;
}
}
promises.push(this.set_default(values));
jQuery.when.apply(jQuery, promises).then(function() {
dfd.resolve(values);
});
return this.set_default(values);
}.bind(this));
} else {
dfd.resolve();
}
return dfd;
return jQuery.when();
},
set_default: function(values, validate) {
if (validate === undefined) {
+16 -9
View File
@@ -1194,7 +1194,7 @@ function eval_pyson(value){
'type': 'text',
'class': 'form-control input-sm'
}).appendTo(this.group);
if (attributes.autocomplete) {
if (!jQuery.isEmptyObject(attributes.autocomplete)) {
this.datalist = jQuery('<datalist/>').appendTo(this.el);
this.datalist.uniqueId();
this.input.attr('list', this.datalist.attr('id'));
@@ -1228,15 +1228,22 @@ function eval_pyson(value){
Sao.View.Form.Char._super.display.call(this, record, field);
if (this.datalist) {
this.datalist.children().remove();
var selection = [];
if (record) {
selection = record.autocompletion[this.field_name] || [];
var set_autocompletion = function() {
var selection = [];
if (record) {
selection = record.autocompletion[this.field_name] || [];
}
selection.forEach(function(e) {
jQuery('<option/>', {
'value': e
}).appendTo(this.datalist);
}.bind(this));
}.bind(this);
if (record && !(this.field_name in record.autocompletion)) {
record.do_autocomplete(this.field_name).done(set_autocompletion);
} else {
set_autocompletion();
}
selection.forEach(function(e) {
jQuery('<option/>', {
'value': e
}).appendTo(this.datalist);
}.bind(this));
}
// Set size