[FIX] web: display empty input fields properly
Before this commit, it was not possible to see the difference between an unset float field (with a 'false' value) and a set field (for ex, with value 0) This was due to the fact that the formatFloat/formatMonetary functions format false values as the number 0, unlike many other formatting functions.
This commit is contained in:
@@ -93,9 +93,6 @@ var DebouncedField = AbstractField.extend({
|
||||
// _debouncedStarted is used to detect that the user interacted at least
|
||||
// once with the widget, so that we can prevent it from triggering a
|
||||
// field_changed in commitChanges if the user didn't change anything
|
||||
// (this is required as sometimes it is hard to detect that an unset
|
||||
// value is still unset, e.g. if a numerical field contains the value 0,
|
||||
// is it because it is still unset or because the user set it to 0?
|
||||
this._debouncedStarted = false;
|
||||
if (this.mode === 'edit') {
|
||||
if (this.DEBOUNCE) {
|
||||
|
||||
@@ -71,7 +71,7 @@ function formatChar(value) {
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatDate(value, field, options) {
|
||||
if (!value) {
|
||||
if (value === false) {
|
||||
return "";
|
||||
}
|
||||
if (!options || !('timezone' in options) || options.timezone) {
|
||||
@@ -96,7 +96,7 @@ function formatDate(value, field, options) {
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatDateTime(value, field, options) {
|
||||
if (!value) {
|
||||
if (value === false) {
|
||||
return "";
|
||||
}
|
||||
if (!options || !('timezone' in options) || options.timezone) {
|
||||
@@ -113,7 +113,7 @@ function formatDateTime(value, field, options) {
|
||||
* Returns a string representing a float. The result takes into account the
|
||||
* user settings (to display the correct decimal separator).
|
||||
*
|
||||
* @param {float} value the value that should be formatted
|
||||
* @param {float|false} value the value that should be formatted
|
||||
* @param {Object} [field] a description of the field (returned by fields_get
|
||||
* for example). It may contain a description of the number of digits that
|
||||
* should be used.
|
||||
@@ -124,6 +124,9 @@ function formatDateTime(value, field, options) {
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatFloat(value, field, options) {
|
||||
if (value === false) {
|
||||
return "";
|
||||
}
|
||||
var l10n = core._t.database.parameters;
|
||||
var precision;
|
||||
if (options && options.digits) {
|
||||
@@ -213,7 +216,7 @@ function formatX2Many(value) {
|
||||
* Returns a string representing a monetary value. The result takes into account
|
||||
* the user settings (to display the correct decimal separator, currency, ...).
|
||||
*
|
||||
* @param {float} value the value that should be formatted
|
||||
* @param {float|false} value the value that should be formatted
|
||||
* @param {Object} [field]
|
||||
* a description of the field (returned by fields_get for example). It
|
||||
* may contain a description of the number of digits that should be used.
|
||||
@@ -238,6 +241,9 @@ function formatX2Many(value) {
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatMonetary(value, field, options) {
|
||||
if (value === false) {
|
||||
return "";
|
||||
}
|
||||
options = options || {};
|
||||
|
||||
var currency = options.currency;
|
||||
|
||||
@@ -415,9 +415,9 @@ QUnit.module('basic_fields', {
|
||||
'</tree>',
|
||||
});
|
||||
|
||||
var zeroValues = list.$('td').filter(function () {return $(this).text() === '0.000';});
|
||||
assert.strictEqual(zeroValues.length, 2,
|
||||
'Unset float values should be rendered as zeros.');
|
||||
var zeroValues = list.$('td.o_data_cell').filter(function () {return $(this).text() === '';});
|
||||
assert.strictEqual(zeroValues.length, 1,
|
||||
'Unset float values should be rendered as empty strings.');
|
||||
|
||||
// switch to edit mode
|
||||
var $cell = list.$('tr.o_data_row td:not(.o_list_record_selector)').first();
|
||||
@@ -441,8 +441,8 @@ QUnit.module('basic_fields', {
|
||||
QUnit.test('do not trigger a field_changed if they have not changed', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
this.data.partner.records[1].qux = undefined;
|
||||
this.data.partner.records[1].int_field = undefined;
|
||||
this.data.partner.records[1].qux = false;
|
||||
this.data.partner.records[1].int_field = false;
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
@@ -1659,9 +1659,9 @@ QUnit.module('basic_fields', {
|
||||
assert.strictEqual(euroValues.length, 1,
|
||||
'One one line has euro as a currency.');
|
||||
|
||||
var zeroValues = list.$('td').filter(function () {return _.str.include($(this).text(), '0.00');});
|
||||
assert.strictEqual(zeroValues.length, 2,
|
||||
'Unset float values should be rendered as zeros.');
|
||||
var zeroValues = list.$('td.o_data_cell').filter(function () {return $(this).text() === '';});
|
||||
assert.strictEqual(zeroValues.length, 1,
|
||||
'Unset float values should be rendered as empty strings.');
|
||||
|
||||
// switch to edit mode
|
||||
var $cell = list.$('tr.o_data_row td:not(.o_list_record_selector):contains($)');
|
||||
|
||||
@@ -23,13 +23,13 @@ QUnit.test('format integer', function(assert) {
|
||||
assert.strictEqual(fieldUtils.format.integer(106500), '106,50,0');
|
||||
|
||||
assert.strictEqual(fieldUtils.format.integer(0), "0");
|
||||
assert.strictEqual(fieldUtils.format.integer(undefined), "");
|
||||
assert.strictEqual(fieldUtils.format.integer(false), "");
|
||||
|
||||
core._t.database.parameters.grouping = originalGrouping;
|
||||
});
|
||||
|
||||
QUnit.test('format float', function(assert) {
|
||||
assert.expect(4);
|
||||
assert.expect(5);
|
||||
|
||||
var originalParameters = $.extend(true, {}, core._t.database.parameters);
|
||||
|
||||
@@ -48,6 +48,7 @@ QUnit.test('format float', function(assert) {
|
||||
thousands_sep: '.'
|
||||
});
|
||||
assert.strictEqual(fieldUtils.format.float(6000), '6.000,00');
|
||||
assert.strictEqual(fieldUtils.format.float(false), '');
|
||||
|
||||
core._t.database.parameters = originalParameters;
|
||||
});
|
||||
@@ -70,6 +71,12 @@ QUnit.test("format_many2one", function (assert) {
|
||||
}));
|
||||
});
|
||||
|
||||
QUnit.test('format monetary', function(assert) {
|
||||
assert.expect(1);
|
||||
|
||||
assert.strictEqual(fieldUtils.format.monetary(false), '');
|
||||
});
|
||||
|
||||
QUnit.test('format char', function(assert) {
|
||||
assert.expect(1);
|
||||
|
||||
|
||||
@@ -696,6 +696,50 @@ QUnit.module('Views', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('required float fields works as expected', function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
this.data.partner.fields.qux.required = true;
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<group>' +
|
||||
'<field name="qux"/>' +
|
||||
'</group>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(args.method);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
assert.ok(form.$('input[name="qux"]').hasClass('o_required_modifier'),
|
||||
"qux input is flagged as required");
|
||||
assert.strictEqual(form.$('input[name="qux"]').val(), "",
|
||||
"qux input is empty");
|
||||
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
|
||||
assert.ok(form.$('input[name="qux"]').hasClass('o_field_invalid'),
|
||||
"qux input is displayed as invalid");
|
||||
|
||||
form.$('input[name="qux"]').val("0").trigger('input');
|
||||
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
|
||||
form.$buttons.find('.o_form_button_edit').click();
|
||||
|
||||
assert.strictEqual(form.$('input[name="qux"]').val(), "0.0",
|
||||
"qux input is properly formatted");
|
||||
|
||||
assert.verifySteps(['default_get', 'create', 'read']);
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('separators', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user