[IMP] web: use moment object instead of string for date
Before this commit, the odoo web client used strings to represent dates. Now, the date is parsed into a moment object when the value is read from the server side. The widget formats the object to display the value. When the widget value changes, the value is parsed to a moment object. The value is automatically formatted to server value in ajax calls (toJSON method).
This commit is contained in:
committed by
Aaron Bohy
parent
cce579434b
commit
3c0190d0a6
@@ -133,9 +133,8 @@ var FieldDate = InputField.extend({
|
||||
if (this.mode === 'edit') {
|
||||
this.datewidget = this._makeDatePicker();
|
||||
this.datewidget.on('datetime_changed', this, function () {
|
||||
var value = this._parseValue(this.datewidget.get_value());
|
||||
if (value !== this._parseValue(this.value)) {
|
||||
this._setValue(value);
|
||||
if (!this.datewidget.get_value().isSame(this.value)) {
|
||||
this._setValue(this.datewidget.get_value());
|
||||
}
|
||||
});
|
||||
def = this.datewidget.appendTo('<div>').done(function () {
|
||||
|
||||
@@ -35,18 +35,26 @@ function format_char(value) {
|
||||
return typeof value === 'string' ? value : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @params {Moment}
|
||||
* @returns {string}
|
||||
*/
|
||||
function format_date(value) {
|
||||
var l10n = core._t.database.parameters;
|
||||
var date_format = time.strftime_to_moment_format(l10n.date_format);
|
||||
return value && moment(time.str_to_date(value), moment.ISO_8601).format(date_format);
|
||||
return value.format(date_format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @params {Moment}
|
||||
* @returns {string}
|
||||
*/
|
||||
function format_datetime(value) {
|
||||
var l10n = core._t.database.parameters;
|
||||
var date_format = time.strftime_to_moment_format(l10n.date_format);
|
||||
var time_format = time.strftime_to_moment_format(l10n.time_format);
|
||||
var datetime_format = date_format + ' ' + time_format;
|
||||
return value && moment(time.str_to_datetime(value), moment.ISO_8601).format(datetime_format);
|
||||
return value.format(datetime_format);
|
||||
}
|
||||
|
||||
// Format a float, according to the local settings
|
||||
@@ -147,12 +155,20 @@ function format_selection(value, field) {
|
||||
// Parse
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* create an Date object
|
||||
* The method toJSON return the formated value to send value server side
|
||||
*
|
||||
* @params {string}
|
||||
* @returns {Moment} Moment date object
|
||||
*/
|
||||
function parse_date(value) {
|
||||
var date_pattern = time.strftime_to_moment_format(core._t.database.parameters.date_format);
|
||||
var date_pattern_wo_zero = date_pattern.replace('MM','M').replace('DD','D');
|
||||
var date = moment(value, [date_pattern, date_pattern_wo_zero, moment.ISO_8601], true);
|
||||
if (date.isValid() && date.year() >= 1900) {
|
||||
return time.date_to_str(date.toDate());
|
||||
date.toJSON = time.date_to_str.bind(time, date.toDate());
|
||||
return date;
|
||||
}
|
||||
date = moment(value, [date_pattern, date_pattern_wo_zero, moment.ISO_8601]);
|
||||
if (date.isValid()) {
|
||||
@@ -160,12 +176,20 @@ function parse_date(value) {
|
||||
date.year(moment.utc().year());
|
||||
}
|
||||
if (date.year() >= 1900) {
|
||||
return time.date_to_str(date.toDate());
|
||||
date.toJSON = time.date_to_str.bind(time, date.toDate());
|
||||
return date;
|
||||
}
|
||||
}
|
||||
throw new Error(_.str.sprintf(core._t("'%s' is not a correct date"), value));
|
||||
}
|
||||
|
||||
/**
|
||||
* create an Date object
|
||||
* The method toJSON return the formated value to send value server side
|
||||
*
|
||||
* @params {string}
|
||||
* @returns {Moment} Moment date object
|
||||
*/
|
||||
function parse_datetime(value) {
|
||||
var date_pattern = time.strftime_to_moment_format(core._t.database.parameters.date_format),
|
||||
time_pattern = time.strftime_to_moment_format(core._t.database.parameters.time_format);
|
||||
@@ -175,7 +199,8 @@ function parse_datetime(value) {
|
||||
var pattern2 = date_pattern_wo_zero + ' ' + time_pattern_wo_zero;
|
||||
var datetime = moment(value, [pattern1, pattern2, moment.ISO_8601], true);
|
||||
if (datetime.isValid() && datetime.year() >= 1900) {
|
||||
return time.datetime_to_str(datetime.toDate());
|
||||
datetime.toJSON = time.datetime_to_str.bind(time, datetime.toDate());
|
||||
return datetime;
|
||||
}
|
||||
datetime = moment(value, [pattern1, pattern2, moment.ISO_8601]);
|
||||
if (datetime.isValid()) {
|
||||
@@ -183,7 +208,8 @@ function parse_datetime(value) {
|
||||
datetime.year(moment.utc().year());
|
||||
}
|
||||
if (datetime.year() >= 1900) {
|
||||
return time.datetime_to_str(datetime.toDate());
|
||||
datetime.toJSON = time.datetime_to_str.bind(time, datetime.toDate());
|
||||
return datetime;
|
||||
}
|
||||
}
|
||||
throw new Error(_.str.sprintf(core._t("'%s' is not a correct datetime"), value));
|
||||
|
||||
@@ -83,6 +83,7 @@ var Context = require('web.Context');
|
||||
var data = require('web.data'); // TODO: remove dependency to data.js
|
||||
var pyeval = require('web.pyeval');
|
||||
var session = require('web.session');
|
||||
var field_utils = require('web.field_utils');
|
||||
|
||||
var x2ManyCommands = {
|
||||
// (0, _, {values})
|
||||
@@ -536,6 +537,12 @@ var Model = AbstractModel.extend({
|
||||
_.each(_.keys(many2ones), function (name) {
|
||||
defs.push(self._fetchNameGets(x2manyList, name));
|
||||
});
|
||||
} else if (field.type === 'date') {
|
||||
// process date: convert into Date object
|
||||
record._changes[name] = field_utils.parse_date(result[name]);
|
||||
} else if (field.type === 'datetime') {
|
||||
// process datetime: convert into Date object
|
||||
record._changes[name] = field_utils.parse_datetime(result[name]);
|
||||
} else {
|
||||
record._changes[name] = result[name];
|
||||
}
|
||||
@@ -1252,11 +1259,11 @@ var Model = AbstractModel.extend({
|
||||
record.data = _.extend({}, record.data, result);
|
||||
return self._postprocess(record);
|
||||
}).then(function (record) {
|
||||
// process many2one: split [id, nameget] and create corresponding record
|
||||
_.each(fieldNames, function (name) {
|
||||
var field = record.fields[name];
|
||||
var val = record.data[name];
|
||||
if (field.type === 'many2one') {
|
||||
// process many2one: split [id, nameget] and create corresponding record
|
||||
if (val !== false) {
|
||||
// the many2one value is of the form [id, display_name]
|
||||
var r = self._makeDataPoint({
|
||||
@@ -1271,6 +1278,12 @@ var Model = AbstractModel.extend({
|
||||
// no value for the many2one
|
||||
record.data[name] = false;
|
||||
}
|
||||
} else if (field.type === 'date') {
|
||||
// process data: convert into Date object
|
||||
record.data[name] = field_utils.parse_date(val);
|
||||
} else if (field.type === 'datetime') {
|
||||
// process datetime: convert into Date object
|
||||
record.data[name] = field_utils.parse_datetime(val);
|
||||
}
|
||||
});
|
||||
}).then(function () {
|
||||
|
||||
@@ -519,7 +519,7 @@ QUnit.module('basic_fields', {
|
||||
});
|
||||
|
||||
QUnit.test('field date in editable list view', function (assert) {
|
||||
assert.expect(1);
|
||||
assert.expect(2);
|
||||
|
||||
this.data.partner.fields.date.default = "2017-02-10";
|
||||
this.data.partner.records = [];
|
||||
@@ -535,7 +535,10 @@ QUnit.module('basic_fields', {
|
||||
|
||||
list.$buttons.find('.o_list_button_add').click();
|
||||
|
||||
assert.ok(list.$('input').is(':focus'),
|
||||
assert.strictEqual(list.$('input.o_datepicker_input').length, 1,
|
||||
"the view should have a date input for editable mode");
|
||||
|
||||
assert.ok(list.$('input.o_datepicker_input').is(':focus'),
|
||||
"date input should have the focus (make sure the test window had the focus)");
|
||||
});
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@ QUnit.test("format_datetime", function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var date_string = "2009-05-04 12:34:23";
|
||||
var date = time.str_to_datetime(date_string);
|
||||
var str = fieldUtils.format_datetime(date_string);
|
||||
var date = fieldUtils.parse_datetime(date_string);
|
||||
var str = fieldUtils.format_datetime(date);
|
||||
assert.strictEqual(str, moment(date).format("MM/DD/YYYY HH:mm:ss"));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user