From 505d770a1174bcea6fffeae31b9d8605fc0edcd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 13 Jan 2017 20:04:53 +0100 Subject: [PATCH] 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 --- src/model.js | 33 +++++---------------------------- src/view/form.js | 25 ++++++++++++++++--------- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/src/model.js b/src/model.js index b4c0287c16..c6c3baa329 100644 --- a/src/model.js +++ b/src/model.js @@ -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) { diff --git a/src/view/form.js b/src/view/form.js index 614632d014..64eb5968b7 100644 --- a/src/view/form.js +++ b/src/view/form.js @@ -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('').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('