summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2017-06-15 12:37:42 +0200
committerAaron Bohy <aab@odoo.com>2017-06-16 11:14:16 +0200
commit8859d25bc5b719734b7d02bc26adfd38dca79e56 (patch)
tree6106160ae2da305999149bbc141950442d802e26 /addons/web/static/src
parent1fa67917ba648bc15f5a895f6bdcea173e2a7258 (diff)
[FIX] web: FieldWidgets: use correct format/parse functions
Field widgets must format and parse values according to the widget type, not to the field type. For example, if a monetary field is inserted in a form view with widget="float", the field's value must be formatted with the float formatter, not the montetary one. This wasn't the case before this rev.
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/fields/abstract_field.js26
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js85
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js1
3 files changed, 42 insertions, 70 deletions
diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js
index 0c05b0721c2..52e0aef77e4 100644
--- a/addons/web/static/src/js/fields/abstract_field.js
+++ b/addons/web/static/src/js/fields/abstract_field.js
@@ -142,6 +142,21 @@ var AbstractField = Widget.extend({
// this is the last value that was set by the user, unparsed. This is
// used to avoid setting the value twice in a row with the exact value.
this.lastSetValue = undefined;
+
+ // formatType is used to determine which format (and parse) functions
+ // to call to format the field's value to insert into the DOM (typically
+ // put into a span or an input), and to parse the value from the input
+ // to send it to the server. These functions are chosen according to
+ // the 'widget' attrs if is is given, and if it is a valid key, with a
+ // fallback on the field type, ensuring that the value is formatted and
+ // displayed according to the choosen widget, if any.
+ this.formatType = this.attrs.widget in field_utils.format ?
+ this.attrs.widget :
+ this.field.type;
+ // formatOptions (resp. parseOptions) is a dict of options passed to
+ // calls to the format (resp. parse) function.
+ this.formatOptions = {};
+ this.parseOptions = {};
},
/**
* When a field widget is appended to the DOM, its start method is called,
@@ -266,15 +281,15 @@ var AbstractField = Widget.extend({
//--------------------------------------------------------------------------
/**
- * convert the value from the field to a string representation
+ * Converts the value from the field to a string representation.
*
* @private
* @param {any} value (from the field type)
* @returns {string}
*/
_formatValue: function (value) {
- var options = _.extend({}, this.nodeOptions, { data: this.recordData });
- return field_utils.format[this.field.type](value, this.field, options);
+ var options = _.extend({}, this.nodeOptions, { data: this.recordData }, this.formatOptions);
+ return field_utils.format[this.formatType](value, this.field, options);
},
/**
* This method check if a value is the same as the current value of the
@@ -291,15 +306,14 @@ var AbstractField = Widget.extend({
return this.value === value;
},
/**
- * convert a string representation to a valid value, depending on the field
- * type.
+ * Converts a string representation to a valid value.
*
* @private
* @param {string} value
* @returns {any}
*/
_parseValue: function (value) {
- return field_utils.parse[this.field.type](value, this.field);
+ return field_utils.parse[this.formatType](value, this.field, this.parseOptions);
},
/**
* main rendering function. Override this if your widget has the same render
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index ffe7d7c0f99..ef1832e00d6 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -322,6 +322,14 @@ var FieldDate = InputField.extend({
supportedFieldTypes: ['date'],
/**
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ // use the session timezone when formatting dates
+ this.formatOptions.timezone = true;
+ },
+ /**
* In edit mode, instantiates a DateWidget datepicker and listen to changes.
*
* @override
@@ -396,17 +404,6 @@ var FieldDate = InputField.extend({
this.datewidget.setValue(this.value);
this.$input = this.datewidget.$input;
},
-
- /**
- * FieldDateTime overrides _formatValue to use the session timezone
- *
- * @override
- * @private
- * @param {Moment} value
- */
- _formatValue: function (value) {
- return field_utils.format.date(value, {timezone: true});
- },
});
var FieldDateTime = FieldDate.extend({
@@ -448,17 +445,6 @@ var FieldDateTime = FieldDate.extend({
this.datewidget.setValue(value);
this.$input = this.datewidget.$input;
},
-
- /**
- * FieldDateTime overrides _formatValue to use the session timezone
- *
- * @override
- * @private
- * @param {Moment} value
- */
- _formatValue: function (value) {
- return field_utils.format.datetime(value, {timezone: true});
- },
});
var FieldMonetary = InputField.extend({
@@ -490,6 +476,13 @@ var FieldMonetary = InputField.extend({
this.tagName = 'div';
this.className += ' o_input';
}
+
+ // use the formatFloat function in edit
+ if (this.mode === 'edit') {
+ this.formatType = 'float';
+ }
+ this.formatOptions.currency = this.currency;
+ this.formatOptions.digits = [16, 2];
},
//--------------------------------------------------------------------------
@@ -562,22 +555,6 @@ var FieldMonetary = InputField.extend({
var currencyID = this.record.data[currencyField] && this.record.data[currencyField].res_id;
this.currency = session.get_currency(currencyID);
},
- /**
- * FieldMonetary overrides _formatValue to use the format monetary method
- * in readonly.
- *
- * @override
- * @private
- * @param {float} value
- * @returns {string}
- */
- _formatValue: function (value) {
- var format = field_utils.format[this.mode === 'edit' ? "float" : "monetary"];
- return format(value, this.field, {
- digits: [16, 2],
- currency: this.currency,
- });
- },
});
var FieldBoolean = AbstractField.extend({
@@ -739,7 +716,7 @@ var FieldInteger = InputField.extend({
}
return value;
}
- return field_utils.format.integer(value, this.field);
+ return this._super.apply(this, arguments);
},
});
@@ -776,31 +753,11 @@ var FieldFloat = InputField.extend({
});
var FieldFloatTime = FieldFloat.extend({
- supportedFieldTypes: ['float'],
-
- //--------------------------------------------------------------------------
- // Private
- //--------------------------------------------------------------------------
-
- /**
- * Format the float time value into a human-readable time format.
- *
- * @override
- * @private
- */
- _formatValue: function (value) {
- return field_utils.format.float_time(value);
- },
-
- /**
- * Parse the human-readable formatted time value into a float.
- *
- * @override
- * @private
- */
- _parseValue: function (value) {
- return field_utils.parse.float_time(value);
- },
+ // this is not strictly necessary, as for this widget to be used, the 'widget'
+ // attrs must be set to 'float_time', so the formatType is automatically
+ // 'float_time', but for the sake of clarity, we explicitely define a
+ // FieldFloatTime widget with formatType = 'float_time'.
+ formatType: 'float_time',
});
var FieldText = InputField.extend(TranslatableFieldMixin, {
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index 3b47b8c64b0..95bef29f88e 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -1763,6 +1763,7 @@ var FieldSelection = AbstractField.extend({
this._super.apply(this, arguments);
if (this.field.type === 'many2one') {
this.values = this.record.specialData[this.name];
+ this.formatType = 'many2one';
} else {
this.values = _.reject(this.field.selection, function (v) {
return v[0] === false && v[1] === '';