summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/fields
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2017-03-30 13:06:38 +0200
committerAaron Bohy <aab@odoo.com>2017-04-11 19:44:38 +0200
commit2169a585dde01761567ef3baff685b12a09b03e9 (patch)
treef8b697783ff45751796ceb53fcfde1e98a00eb3a /addons/web/static/src/js/fields
parent4a9ca16369933fa92b211932a26892cf766aefae (diff)
[FIX] web: debounce field changes for FieldText
like done previously for input fields.
Diffstat (limited to 'addons/web/static/src/js/fields')
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js112
1 files changed, 73 insertions, 39 deletions
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index 3ec0c027c77..91aa9d4e1ce 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -26,14 +26,70 @@ var view_dialogs = require('web.view_dialogs');
var qweb = core.qweb;
var _t = core._t;
-
-var InputField = AbstractField.extend({
+var DebouncedField = AbstractField.extend({
events: _.extend({}, AbstractField.prototype.events, {
'input': '_onInput',
'change': '_onChange',
}),
/**
+ * Override init to debounce the input changes to make sure they are not
+ * done too quickly. Note that this is done here and not on the prototype,
+ * so each inputfield has its own debounced function to work with.
+ * Also, if the debounce value is set to 0, no debouncing is done, which is
+ * really useful for the unit tests.
+ *
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+
+ if (this.DEBOUNCE && this.mode === 'edit') {
+ this._onInput = _.debounce(this._onInput.bind(this), this.DEBOUNCE);
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Should return the current value of the field, in the DOM (for example,
+ * the content of the input)
+ *
+ * @abstract
+ * @private
+ * @returns {*}
+ */
+ _getValue: function () {
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * We immediately notify the outside world when this field confirms its
+ * changes
+ *
+ * @private
+ */
+ _onChange: function () {
+ this._setValue(this._getValue());
+ },
+ /**
+ * We notify the outside world for each change in this field. It does not
+ * necessarily mean that onchanges will be triggered instantly.
+ *
+ * @private
+ */
+ _onInput: function () {
+ this._setValue(this._getValue());
+ },
+});
+
+var InputField = DebouncedField.extend({
+ /**
* The very purpose of this field is to be an input tag in edit mode.
*
* @override
@@ -42,15 +98,6 @@ var InputField = AbstractField.extend({
this._super.apply(this, arguments);
if (this.mode === 'edit') {
this.tagName = 'input';
-
- // we debounce the input changes to make sure they are not done too
- // quickly. Note that this is done here and not on the prototype,
- // so each inputfield has its own debounced function to work with.
- // Also, if the debounce value is set to 0, no debouncing is done,
- // which is really useful for the unit tests.
- if (this.DEBOUNCE) {
- this._onInput = _.debounce(this._onInput.bind(this), this.DEBOUNCE);
- }
}
},
@@ -67,7 +114,6 @@ var InputField = AbstractField.extend({
this.$input.focus();
setTimeout(this.$input.select.bind(this.$input), 0);
},
-
/**
* Do not re-render this field if it was the origin of the onchange call.
* FIXME: make the onchange work on itself without disturbing the user typing
@@ -88,6 +134,13 @@ var InputField = AbstractField.extend({
//--------------------------------------------------------------------------
/**
+ * @override
+ * @returns {string} the content of the input
+ */
+ _getValue: function () {
+ return this.$input.val();
+ },
+ /**
* Formats an input element for edit mode. This is in a separate function so
* extending widgets can use it on their input without having input as tagName.
*
@@ -108,7 +161,6 @@ var InputField = AbstractField.extend({
this.$input[0].selectionStart = selectionStart;
this.$input[0].selectionEnd = selectionEnd;
},
-
/**
* Formats the HTML input tag for edit mode and stores selection status.
*
@@ -121,7 +173,6 @@ var InputField = AbstractField.extend({
this.$input = this.$el;
this._prepareInput(this.$input);
},
-
/**
* Resets the content to the formated value in readonly mode.
*
@@ -137,15 +188,6 @@ var InputField = AbstractField.extend({
//--------------------------------------------------------------------------
/**
- * We immediately notify the outside world when this input confirms its
- * changes.
- *
- * @private
- */
- _onChange: function () {
- this._setValue(this.$input.val());
- },
- /**
* Implement keyboard movements. Mostly useful for its environment, such
* as a list view.
*
@@ -181,16 +223,6 @@ var InputField = AbstractField.extend({
}
this._super.apply(this, arguments);
},
-
- /**
- * We notify the outside world for each change in this input value. It does
- * not necessarily mean that onchanges will be triggered instantly.
- *
- * @private
- */
- _onInput: function () {
- this._setValue(this.$input.val());
- },
});
var FieldChar = InputField.extend({
@@ -569,12 +601,7 @@ var FieldFloatTime = FieldFloat.extend({
},
});
-var FieldText = AbstractField.extend({
- events: _.extend({}, AbstractField.prototype.events, {
- 'input': function () {
- this._setValue(this.$textarea.val());
- },
- }),
+var FieldText = DebouncedField.extend({
supportedFieldTypes: ['text'],
/**
@@ -620,6 +647,13 @@ var FieldText = AbstractField.extend({
//--------------------------------------------------------------------------
/**
+ * @override
+ * @returns {string} the content of the textarea
+ */
+ _getValue: function () {
+ return this.$textarea.val();
+ },
+ /**
* Format the value and put it in the textarea.
*
* @override