diff --git a/web_widget_one2many_product_picker/README.rst b/web_widget_one2many_product_picker/README.rst
index 7f7e54dfa..10fb845f2 100644
--- a/web_widget_one2many_product_picker/README.rst
+++ b/web_widget_one2many_product_picker/README.rst
@@ -47,7 +47,6 @@ You need to define the view fields. The view must be of ``form`` type.
Widget options:
~~~~~~~~~~~~~~~
-* product_per_page > Integer -> Used to control the load more behaviour (16 by default)
* groups > Array of dictionaries -> Declare the groups
* name -> The group name
@@ -58,6 +57,9 @@ Widget options:
* name -> The field name to order
* asc -> Flag to use 'asc' order
+ * records_per_page > Integer -> Used to control the load more behaviour (16 by default)
+ * active -> Boolean -> Select the default group to use ('false' by default = 'All' group)
+
* currency_field > Model field used to format monetary values ('currency_id' by default)
* field_map > Dictionary:
diff --git a/web_widget_one2many_product_picker/readme/CONFIGURE.rst b/web_widget_one2many_product_picker/readme/CONFIGURE.rst
index 984006746..9d6350245 100644
--- a/web_widget_one2many_product_picker/readme/CONFIGURE.rst
+++ b/web_widget_one2many_product_picker/readme/CONFIGURE.rst
@@ -5,7 +5,6 @@ You need to define the view fields. The view must be of ``form`` type.
Widget options:
~~~~~~~~~~~~~~~
-* product_per_page > Integer -> Used to control the load more behaviour (16 by default)
* groups > Array of dictionaries -> Declare the groups
* name -> The group name
@@ -16,6 +15,9 @@ Widget options:
* name -> The field name to order
* asc -> Flag to use 'asc' order
+ * records_per_page > Integer -> Used to control the load more behaviour (16 by default)
+ * active -> Boolean -> Select the default group to use ('false' by default = 'All' group)
+
* currency_field > Model field used to format monetary values ('currency_id' by default)
* field_map > Dictionary:
diff --git a/web_widget_one2many_product_picker/static/description/index.html b/web_widget_one2many_product_picker/static/description/index.html
index 84b25088e..823f5446b 100644
--- a/web_widget_one2many_product_picker/static/description/index.html
+++ b/web_widget_one2many_product_picker/static/description/index.html
@@ -406,8 +406,6 @@ You need to define the view fields. The view must be of
+
+active -> Boolean -> Select the default group to use (‘false’ by default = ‘All’ group)
+
diff --git a/web_widget_one2many_product_picker/static/src/js/tools.js b/web_widget_one2many_product_picker/static/src/js/tools.js
index 5181b1de4..a839b884d 100644
--- a/web_widget_one2many_product_picker/static/src/js/tools.js
+++ b/web_widget_one2many_product_picker/static/src/js/tools.js
@@ -34,8 +34,15 @@ odoo.define("web_widget_one2many_product_picker.tools", function(require) {
});
}
+ function float(value, field_info, digits) {
+ return field_utils.format.float(value, field_info, {
+ digits: digits,
+ });
+ }
+
return {
monetary: monetary,
+ float: float,
priceReduce: priceReduce,
};
});
diff --git a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js
index 652864ec7..170efe4ed 100644
--- a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js
+++ b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js
@@ -28,6 +28,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
},
_click_card_delayed_time: 250,
+ _onchange_delay: 250,
/**
* @override
@@ -48,6 +49,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
/**
* Generates a new virtual state and recreates the product card
*
+ * @param {Boolean} simple_mode
* @returns {Object}
*/
generateVirtualState: function(simple_mode) {
@@ -186,6 +188,19 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
);
},
+ /**
+ * Prints the given field value using the selected format
+ *
+ * @private
+ * @param {String} price_field
+ * @returns {String}
+ */
+ _getFloatFieldValue: function(field) {
+ const field_name = this.options.fieldMap[field];
+ const value = this.state.data[field_name];
+ return tools.float(value, this.state.fields[field_name]);
+ },
+
/**
* @private
* @param {String} d a stringified domain
@@ -241,6 +256,10 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
this._setMasterUomMap();
},
+ /**
+ * Used to know what is the "main" uom
+ * @private
+ */
_setMasterUomMap: function() {
this.master_uom_map = {
field_uom: "product_uom",
@@ -269,9 +288,13 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
field_map: this.options.fieldMap,
widget: this,
monetary: this._getMonetaryFieldValue.bind(this),
+ floatFixed: this._getFloatFieldValue.bind(this),
show_discount: this.options.showDiscount,
is_virtual: this.is_virtual,
- modified: record && record.context.product_picker_modified,
+ modified:
+ record &&
+ model.hasChanges(record.id) &&
+ !model.isPureVirtual(record.id),
active_model: "",
auto_save: this.options.autoSave,
is_saving: record && record.context.saving,
@@ -310,6 +333,15 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
return {};
},
+ /**
+ * This generates a virtual record with delayed call to "get_default" & "onchange"
+ * used in "instant search" mode
+ *
+ * @private
+ * @param {Object} context
+ * @param {Object} def_values
+ * @returns {Promise}
+ */
_generateVirtualStateSimple: function(context, def_values) {
const model = this.options.basicFieldParams.model;
return new Promise(resolve => {
@@ -349,7 +381,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
(current_batch_id, record_def) => {
this._timerOnChange = false;
if (
- current_batch_id !=
+ current_batch_id !==
this.options.basicFieldParams
.current_batch_id ||
record_def.record.context.aborted
@@ -376,7 +408,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
);
});
},
- 750,
+ this._onchange_delay,
this.options.basicFieldParams.current_batch_id,
record_def
);
@@ -387,6 +419,15 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
});
},
+ /**
+ * Generates a complete virtual record
+ *
+ * @private
+ * @param {Object} data
+ * @param {Object} context
+ * @param {Object} def_values
+ * @returns {Promise}
+ */
_generateVirtualStateFull: function(data, context, def_values) {
const model = this.options.basicFieldParams.model;
return new Promise(resolve => {
@@ -441,6 +482,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
* @private
* @param {Object} data
* @param {Object} context
+ * @param {Boolean} simple_mode
* @returns {Object}
*/
_generateVirtualState: function(data, context, simple_mode) {
@@ -468,6 +510,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
* @param {Integer/String} record_id
* @param {Object} changes
* @param {Object} options
+ * @returns {Promise}
*/
_applyChanges: function(record_id, changes, options) {
const model = this.options.basicFieldParams.model;
@@ -479,6 +522,9 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
});
},
+ /**
+ * @private
+ */
_detachAllWidgets: function() {
_.invoke(this.widgets.front, "on_detach_callback");
_.invoke(this.widgets.back, "on_detach_callback");
@@ -633,6 +679,9 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
});
},
+ /**
+ * @private
+ */
_updateLazyQty: function() {
var model = this.options.basicFieldParams.model;
var record = model.get(this.state.id);
@@ -664,12 +713,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
const state_data = record.data;
let to_find = [];
- if (!_.isEmpty(fields)) {
+ if (_.isEmpty(fields)) {
+ to_find = ["[data-field]"];
+ } else {
to_find = _.map(fields, field => {
return _.str.sprintf("[data-field=%s]", [field]);
});
- } else {
- to_find = ["[data-field]"];
}
this.$el.find(to_find.join()).each((key, value) => {
diff --git a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js
index 994cd5252..c50076b54 100644
--- a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js
+++ b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js
@@ -107,6 +107,14 @@ odoo.define(
});
},
+ /**
+ * Because this widget doesn't support comments/sections line types
+ * we need check if the line is valid to be shown.
+ *
+ * @private
+ * @param {Object} state
+ * @returns {Boolean}
+ */
_isValidLineState: function(state) {
return (
state.data[this.options.field_map.product] &&
@@ -114,6 +122,12 @@ odoo.define(
);
},
+ /**
+ * @private
+ * @param {Object} state_a
+ * @param {Object} state_b
+ * @returns {Boolean}
+ */
_isEqualState: function(state_a, state_b) {
if (state_a.id === state_b.id) {
return true;
@@ -133,6 +147,11 @@ odoo.define(
);
},
+ /**
+ * @private
+ * @param {Object} state
+ * @returns {Boolean}
+ */
_existsWidgetWithState: function(state) {
for (let eb = this.widgets.length - 1; eb >= 0; --eb) {
const widget = this.widgets[eb];
@@ -388,6 +407,7 @@ odoo.define(
},
/**
+ * @private
* @param {Array} datas
* @returns {Array}
*/
@@ -540,8 +560,7 @@ odoo.define(
*
* @private
* @param {Array} search_records
- * @param {Boolean} no_process_records
- * @param {Number} position
+ * @param {Object} options
*/
_appendSearchRecords: function(search_records, options) {
const processed_info = options.no_process_records
@@ -569,8 +588,8 @@ odoo.define(
}
// At this point the widget will use the existing state (line) or
- // the search data. Using search data instead of waiting for
- // simulated state gives a low FCP time.
+ // a simple state data. Using simple state data instead of waiting for
+ // complete state (default + onchange) gives a low FCP time.
const def = $.Deferred();
ProductPickerRecord.appendTo(this.$recordsContainer).then(
function(widget, widget_position) {
@@ -622,9 +641,7 @@ odoo.define(
* Append search records to the view
*
* @param {Array} search_records
- * @param {Boolean} no_attach_widgets
- * @param {Boolean} no_process_records
- * @param {Number} position
+ * @param {Object} options
* @returns {Array}
*/
appendSearchRecords: function(search_records, options = {}) {
@@ -690,6 +707,7 @@ odoo.define(
* Handle card flip.
* Used to create/update the record
*
+ * @private
* @param {CustomEvent} evt
*/
_onRecordFlip: function(evt) {
diff --git a/web_widget_one2many_product_picker/static/src/js/views/basic_controller.js b/web_widget_one2many_product_picker/static/src/js/views/basic_controller.js
index 68176cbff..7c13bede5 100644
--- a/web_widget_one2many_product_picker/static/src/js/views/basic_controller.js
+++ b/web_widget_one2many_product_picker/static/src/js/views/basic_controller.js
@@ -12,22 +12,19 @@ odoo.define("web_widget_one2many_product_picker.BasicController", function(requi
* @override
*/
_confirmChange: function(id, fields, e) {
+ id = id || this.handle;
return this._super.apply(this, arguments).then(() => {
- const product_picker_widgets = _.filter(
- this.renderer.allFieldWidgets[this.handle],
- item => item.attrs.widget === "one2many_product_picker"
- );
- for (const widget of product_picker_widgets) {
- const trigger_fields = widget.options.trigger_refresh_fields || [];
- if (
- _.difference(trigger_fields, fields).length !==
- trigger_fields.length
- ) {
- widget._reset(this.model.get(this.handle), e);
- // Force re-launch onchanges on 'pure virtual' records
- widget.renderer.clearRecords();
- widget._render();
- }
+ if (this.renderer && !_.isEmpty(this.renderer.allFieldWidgets)) {
+ const product_picker_widgets = _.filter(
+ this.renderer.allFieldWidgets[id],
+ item => item.attrs.widget === "one2many_product_picker"
+ );
+ _.invoke(
+ product_picker_widgets,
+ "onDocumentConfirmChanges",
+ fields,
+ e
+ );
}
});
},
diff --git a/web_widget_one2many_product_picker/static/src/js/views/basic_model.js b/web_widget_one2many_product_picker/static/src/js/views/basic_model.js
index c55d3849b..e027c3b70 100644
--- a/web_widget_one2many_product_picker/static/src/js/views/basic_model.js
+++ b/web_widget_one2many_product_picker/static/src/js/views/basic_model.js
@@ -74,6 +74,7 @@ odoo.define("web_widget_one2many_product_picker.BasicModel", function(require) {
* elements so can be removed safesly
*
* @param {String} id
+ * @returns {Boolean}
*/
removeVirtualRecord: function(id) {
if (!this.isPureVirtual(id)) {
@@ -91,6 +92,7 @@ odoo.define("web_widget_one2many_product_picker.BasicModel", function(require) {
this.removeLine(remove_id);
delete this.localData[remove_id];
}
+ return true;
},
/**
@@ -158,6 +160,10 @@ odoo.define("web_widget_one2many_product_picker.BasicModel", function(require) {
return Promise.reject();
}
var def = new Promise(function(resolve, reject) {
+ // Interrupt point (used in instant search)
+ if (!self.exists(record.id)) {
+ return Promise.reject();
+ }
var always = function() {
if (record._warning) {
if (params.allowWarning) {
@@ -329,28 +335,142 @@ odoo.define("web_widget_one2many_product_picker.BasicModel", function(require) {
},
/**
- * This happens when the user discard main document changes (isn't a rollback)
+ * Because records can be removed at any time we
+ * need check if the record still existing.
+ * Necessary for 'instant search' feature.
*
* @override
*/
- discardChanges: function(id, options) {
- this._super.apply(this, arguments);
- options = options || {};
- var isNew = this.isNew(id);
- var rollback = "rollback" in options ? options.rollback : isNew;
- if (rollback) {
- return;
+ _applyOnChange: function(values, record) {
+ if (!this.exists(record.id)) {
+ return Promise.reject();
}
- const element = this.localData[id];
- this._visitChildren(element, function(elem) {
- if (
- elem &&
- elem.context &&
- elem.context.product_picker_modified &&
- _.isEmpty(elem._changes)
- ) {
- elem.context.product_picker_modified = false;
+ return this._super.apply(this, arguments);
+ },
+
+ /**
+ * @param {String} recordID
+ * @returns {Boolean}
+ */
+ hasChanges: function(recordID) {
+ const record = this.localData[recordID];
+ return record && !_.isEmpty(record._changes);
+ },
+
+ /**
+ * @param {Object} model_fields
+ * @param {String} model
+ * @param {String} search_val
+ * @param {Array} domain
+ * @param {Array} fields
+ * @param {Object} orderby
+ * @param {String} operator
+ * @param {Number} limit
+ * @param {Number} offset
+ * @param {Object} context
+ * @returns {Promise}
+ */
+ fetchNameSearchFull: function(
+ model_fields,
+ model,
+ search_val,
+ domain,
+ fields,
+ orderby,
+ operator,
+ limit,
+ offset,
+ context
+ ) {
+ return this._rpc({
+ model: model,
+ method: "name_search",
+ kwargs: {
+ name: search_val,
+ args: domain || [],
+ operator: operator || "ilike",
+ limit: this.limit,
+ context: context || {},
+ },
+ }).then(results => {
+ const record_ids = results.map(item => item[0]);
+ return this.fetchGenericRecords(
+ model_fields,
+ model,
+ [["id", "in", record_ids]],
+ fields,
+ orderby,
+ limit,
+ offset,
+ context
+ );
+ });
+ },
+
+ /**
+ * @param {Object} model_fields
+ * @param {String} model
+ * @param {Array} domain
+ * @param {Array} fields
+ * @param {Array} orderby
+ * @param {Number} limit
+ * @param {Number} offset
+ * @param {Object} context
+ * @returns {Promise}
+ */
+ fetchGenericRecords: function(
+ model_fields,
+ model,
+ domain,
+ fields,
+ orderby,
+ limit,
+ offset,
+ context
+ ) {
+ return this._rpc({
+ model: model,
+ method: "search_read",
+ fields: fields,
+ domain: domain,
+ limit: limit,
+ offset: offset,
+ orderBy: orderby,
+ kwargs: {context: context},
+ }).then(result => {
+ for (const index in result) {
+ const record = result[index];
+ for (const fieldName in record) {
+ const field = model_fields[fieldName];
+ if (field.type !== "many2one") {
+ record[fieldName] = this._parseServerValue(
+ model_fields[fieldName],
+ record[fieldName]
+ );
+ }
+ }
}
+ return result;
+ });
+ },
+
+ fetchModelFieldsInfo: function(model) {
+ return this._rpc({
+ model: model,
+ method: "fields_get",
+ args: [
+ false,
+ [
+ "store",
+ "searchable",
+ "type",
+ "string",
+ "relation",
+ "selection",
+ "related",
+ ],
+ ],
+ context: this.getSession().user_context,
});
},
});
diff --git a/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js b/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js
index 085cdb68d..01613eeea 100644
--- a/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js
+++ b/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js
@@ -42,7 +42,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
}),
_auto_search_delay: 450,
- _input_instant_search_time: 150,
+ _input_instant_search_time: 100,
// Model product.product fields
search_read_fields: ["id", "display_name", "uom_id"],
@@ -88,14 +88,25 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
},
willStart: function() {
- return this._super.apply(this, arguments).then(() => {
- if (this.isReadonly) {
- // Show Lines
- this._updateSearchContext(-1);
- } else {
- this._updateSearchContext(0);
- }
- });
+ return this._super
+ .apply(this, arguments)
+ .then(() => {
+ const arch = this.view.arch;
+ const field_name = this.options.field_map.product;
+ const field_info = this.view.fieldsInfo[arch.tag][field_name];
+ const model = this.view.viewFields[field_info.name].relation;
+ this._modelName = model;
+ return this.parent_controller.model.fetchModelFieldsInfo(model);
+ })
+ .then(fields_info => {
+ this._fieldsInfo = fields_info;
+ if (this.isReadonly) {
+ // Show Lines
+ this._updateSearchContext(-1);
+ } else {
+ this._updateSearchContext(0);
+ }
+ });
},
/**
@@ -169,6 +180,26 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
};
},
+ /**
+ * Because the widget shows "pure virtual" information, we don't have any 'onchange' linked.
+ * This method forces 'refresh' the widget if the selected fields was changed.
+ *
+ * @param {Array} fields
+ * @param {Event} e
+ */
+ onDocumentConfirmChanges: function(fields, e) {
+ const trigger_fields = this.options.trigger_refresh_fields || [];
+ if (_.difference(trigger_fields, fields).length !== trigger_fields.length) {
+ this._reset(
+ this.parent_controller.model.get(this.parent_controller.handle),
+ e
+ );
+ // Force re-launch onchanges on 'pure virtual' records
+ this.renderer.clearRecords();
+ this._render();
+ }
+ },
+
/**
* @override
*/
@@ -191,6 +222,9 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
group_def.active = !hasUserActive;
hasUserActive = true;
}
+ if (!group_def.records_per_page) {
+ group_def.records_per_page = 16;
+ }
this.searchGroups.push(group_def);
}
@@ -200,6 +234,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
domain: this.options.all_domain,
order: false,
active: !hasUserActive,
+ records_per_page: 16,
});
this._activeSearchGroup = this.searchGroups[0];
},
@@ -305,6 +340,16 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
this.updateSubtotalPrice();
},
+ /**
+ * Replace placeholders for search
+ * - $number_search -> Is a number
+ * - $search -> Is a string
+ *
+ * @private
+ * @param {Number/String} value
+ * @param {String} format
+ * @returns {Number/String}
+ */
_getSearchValue: function(value, format) {
if (format === "$number_search") {
return Number(value);
@@ -320,15 +365,10 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
*
* @private
* @param {Dictionary} options
- * @param {Boolean} merge
* @returns {Deferred}
*/
_getSearchRecords: function(options) {
- const arch = this.view.arch;
const search_mode = this.options.search[this._searchMode];
- const field_name = this.options.field_map.product;
- const field_info = this.view.fieldsInfo[arch.tag][field_name];
- const model = this.view.viewFields[field_info.name].relation;
const orderby = this._searchContext.order;
const fields = this.search_read_fields;
@@ -344,7 +384,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
},
this.value.getContext()
);
- const limit = soptions.limit || this.options.records_per_page;
+ const limit = soptions.limit || this._activeSearchGroup.records_per_page;
const offset = soptions.offset || 0;
return new Promise(resolve => {
@@ -355,8 +395,9 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
search_mode.name_search_value
);
const operator = search_mode.operator;
- task = this._doSearchRecordsNameSearch(
- model,
+ task = this.parent_controller.model.fetchNameSearchFull(
+ this._fieldsInfo,
+ this._modelName,
search_val,
domain,
fields,
@@ -367,8 +408,9 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
context
);
} else {
- task = this._doSearchRecords(
- model,
+ task = this.parent_controller.model.fetchGenericRecords(
+ this._fieldsInfo,
+ this._modelName,
domain,
fields,
orderby,
@@ -386,76 +428,6 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
});
},
- _doSearchRecordsNameSearch: function(
- model,
- search_val,
- domain,
- fields,
- orderby,
- operator,
- limit,
- offset,
- context
- ) {
- return new Promise(resolve => {
- this._rpc({
- model: model,
- method: "name_search",
- kwargs: {
- name: search_val,
- args: domain || [],
- operator: operator || "ilike",
- limit: this.limit,
- context: context || {},
- },
- }).then(results => {
- const record_ids = results.map(item => item[0]);
- this._doSearchRecords(
- model,
- [["id", "in", record_ids]],
- fields,
- orderby,
- limit,
- offset,
- context
- ).then(records => {
- resolve(records);
- });
- });
- });
- },
-
- /**
- * @param {String} model
- * @param {Array} domain
- * @param {Array} fields
- * @param {Array} orderby
- * @param {Number} limit
- * @param {Number} offset
- * @param {Object} context
- * @returns {Promise}
- */
- _doSearchRecords: function(
- model,
- domain,
- fields,
- orderby,
- limit,
- offset,
- context
- ) {
- return this._rpc({
- model: model,
- method: "search_read",
- fields: fields,
- domain: domain,
- limit: limit,
- offset: offset,
- orderBy: orderby,
- kwargs: {context: context},
- });
- },
-
/**
* @private
* @param {MouseEvent} evt
@@ -514,7 +486,6 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
_getDefaultOptions: function() {
return {
currency_field: "currency_id",
- records_per_page: 16,
show_subtotal: true,
show_discount: false,
edit_discount: false,
@@ -540,7 +511,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
* This domain is used to get the records to display.
*
* @private
- * @param {Object} active_search
+ * @param {Object} search_mode
* @returns {Array}
*/
_getFullSearchDomain: function(search_mode) {
@@ -671,18 +642,24 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
return this._super.apply(this, arguments);
},
+ /**
+ * @private
+ * @param {SearchEvent} evt
+ */
_onSearch: function(evt) {
this._searchContext.text = evt.target.value;
this.doRenderSearchRecords();
},
+ /**
+ * @private
+ * @param {InputEvent} evt
+ */
_onInputSearch: function(evt) {
- if (!this.options.instant_search) {
- return;
+ if (this.options.instant_search) {
+ this._searchContext.text = evt.target.value;
+ this._lazyRenderSearchRecords();
}
- this._searchContext.text = evt.target.value;
- this._lazyRenderSearchRecords();
- // This.doRenderSearchRecords()
},
/**
@@ -751,10 +728,6 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
}
});
} else {
- // This is used to know when need use 'yellow' color
- this.parent_controller.model.updateRecordContext(evt.data.id, {
- product_picker_modified: true,
- });
// This will trigger an "state" update
this._setValue({operation: "ADD", id: evt.data.id}).then(() => {
if (evt.data.callback) {
@@ -764,6 +737,11 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
}
},
+ /**
+ * @param {Number} id
+ * @param {Object} data
+ * @param {Function} callback
+ */
_doUpdateQuickRecord: function(id, data, callback) {
if (this.options.auto_save) {
var self = this;
@@ -790,10 +768,6 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
}
});
} else {
- // This is used to know when need use 'yellow' color
- this.parent_controller.model.updateRecordContext(id, {
- product_picker_modified: true,
- });
// This will trigger an "state" update
this._setValue({operation: "UPDATE", id: id, data: data}).then(
function() {
diff --git a/web_widget_one2many_product_picker/static/src/xml/one2many_product_picker.xml b/web_widget_one2many_product_picker/static/src/xml/one2many_product_picker.xml
index c14b36ea0..dbe754cd5 100644
--- a/web_widget_one2many_product_picker/static/src/xml/one2many_product_picker.xml
+++ b/web_widget_one2many_product_picker/static/src/xml/one2many_product_picker.xml
@@ -98,7 +98,7 @@