From c04b840a45edd222c50e74d18e2d02a3dd3175cd Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Fri, 5 May 2017 15:21:36 +0200 Subject: [FIX] web: FieldMonetary: don't loose focus after edition ... in x2many editable list views. Field widgets can detect that they are at the origin of a field_changed event, so that they don't re-render themselves when they are being edited. This didn't work for fields inside x2many list views. This wasn't a big problem for most of the fields, because the cursor position was automatically reset after a re-rendering, but it wasn't working for monetary fields that empty their $el before each re-rendering. This rev. fixes the issue by making the field widgets inside x2many list able to detect that they are the origin of a change, and thus removes the now useless code that restore the cursor position. --- addons/web/static/src/js/fields/basic_fields.js | 5 ----- 1 file changed, 5 deletions(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index b3defa97911..fc4af105865 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -229,12 +229,7 @@ var InputField = DebouncedField.extend({ type: 'text', placeholder: this.attrs.placeholder || "", }); - // Save cursor position to restore it after updating value - var selectionStart = this.$input[0].selectionStart; - var selectionEnd = this.$input[0].selectionEnd; this.$input.val(this._formatValue(this.value)); - this.$input[0].selectionStart = selectionStart; - this.$input[0].selectionEnd = selectionEnd; return this.$input; }, /** -- cgit v1.2.3 From c1377f597205026e76d86ca5240ec7f4b6e1fbf1 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Fri, 5 May 2017 13:50:46 +0200 Subject: [FIX] web: properly handle field navigation for all fields Before this commit, only fields which were specializations of the `InputField` were handling up/right/down/left navigation in editable list view. As m2o field is not an `InputField` (yet?), it was not possible to navigate from one of those for example. Now, navigation events are handled by the `AbstractField` class. If a given field has to handle navigation a different way, it is its responsability to stop the associated navigation event. For example, `InputField` instances are stopping the left/right event if the cursor is not at the start/end of the element. Also, before this commit, there were many events ("move_down", "move_left", "move_next", ...). Now there is only one event for navigation: "navigation_move". This event is given a "direction" data ("left", "next", ...). It also comes with a "target" data which is a reference to the last `AbstractField` instance the navigation event has crossed. --- addons/web/static/src/js/fields/basic_fields.js | 64 +++++++------------------ 1 file changed, 16 insertions(+), 48 deletions(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index fc4af105865..9df9a49fac2 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -277,40 +277,20 @@ var InputField = DebouncedField.extend({ this._doDebouncedAction(); }, /** - * Implement keyboard movements. Mostly useful for its environment, such - * as a list view. + * Stops the left/right navigation move event if the cursor is not at the + * start/end of the input element. * - * @override * @private - * @param {any} event + * @param {OdooEvent} ev */ - _onKeydown: function (event) { + _onNavigationMove: function (ev) { + this._super.apply(this, arguments); var input = this.$input[0]; - var is_not_selecting; - switch (event.which) { - case $.ui.keyCode.DOWN: - this.trigger_up('move_down'); - break; - case $.ui.keyCode.UP: - this.trigger_up('move_up'); - break; - case $.ui.keyCode.LEFT: - is_not_selecting = input.selectionEnd === input.selectionStart; - if (is_not_selecting && input.selectionStart === 0) { - this.trigger_up('move_left'); - } - break; - case $.ui.keyCode.RIGHT: - is_not_selecting = input.selectionEnd === input.selectionStart; - if (is_not_selecting && input.selectionEnd === input.value.length) { - this.trigger_up('move_right'); - } - break; - case $.ui.keyCode.ENTER: - this.trigger_up('move_next_line'); - break; + var selecting = (input.selectionEnd !== input.selectionStart); + if ((ev.data.direction === "left" && (selecting || input.selectionStart !== 0)) + || (ev.data.direction === "right" && (selecting || input.selectionStart !== input.value.length))) { + ev.stopPropagation(); } - this._super.apply(this, arguments); }, }); @@ -660,28 +640,16 @@ var FieldBoolean = AbstractField.extend({ * * @override * @private - * @param {KeyEvent} event + * @param {KeyEvent} ev */ - _onKeydown: function (event) { - this._super.apply(this, arguments); - switch (event.which) { - case $.ui.keyCode.DOWN: - this.trigger_up('move_down'); - break; - case $.ui.keyCode.UP: - this.trigger_up('move_up'); - break; - case $.ui.keyCode.LEFT: - this.trigger_up('move_left'); - break; - case $.ui.keyCode.RIGHT: - this.trigger_up('move_right'); - break; + _onKeydown: function (ev) { + switch (ev.which) { case $.ui.keyCode.ENTER: this.$input.prop('checked', !this.value); this._setValue(!this.value); - break; + return; } + this._super.apply(this, arguments); }, }); @@ -1904,10 +1872,10 @@ var FieldDomain = AbstractField.extend({ "click .o_domain_show_selection_button": "_onShowSelectionButtonClick", "click .o_field_domain_dialog_button": "_onDialogEditButtonClick", }), - custom_events: { + custom_events: _.extend({}, AbstractField.prototype.custom_events, { "domain_changed": "_onDomainSelectorValueChange", "domain_selected": "_onDomainSelectorDialogValueChange", - }, + }), /** * @constructor * @override init from AbstractField -- cgit v1.2.3 From c8d77f93e5a857acd22025f4a8d4d42d674479d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Mon, 8 May 2017 10:55:46 +0200 Subject: [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. --- addons/web/static/src/js/fields/basic_fields.js | 3 --- 1 file changed, 3 deletions(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 9df9a49fac2..3e9ea89be31 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -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) { -- cgit v1.2.3 From e1edd62320fef4991ba9554ee197021b45987a60 Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Fri, 5 May 2017 16:34:54 +0200 Subject: [FIX] web: toggle checkboxes when clicked in editable list view Previously, the checkbox was not checked when it was clicked in editable list view, it only opened the row but did not check the checkbox. --- addons/web/static/src/js/fields/basic_fields.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 3e9ea89be31..6fc1736870f 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -581,6 +581,23 @@ var FieldBoolean = AbstractField.extend({ // Public //-------------------------------------------------------------------------- + /** + * Toggle the checkbox if it is activated due to a click on itself. + * + * @override + */ + activate: function (options) { + var activated = this._super.apply(this, arguments); + // The formatValue of boolean fields renders HTML elements similar to + // the one rendered by the widget itself. Even though the event might + // have been fired on the non-widget version of this field, we can still + // test the presence of its o_checkbox class. + if (activated && options && options.event && $(options.event.target).parents('.o_checkbox').length) { + this._setValue(!this.value); // Toggle the checkbox + } + return activated; + }, + /** * @override * @returns {jQuery} the focusable checkbox input -- cgit v1.2.3 From 42d95cbfc3d85a8ab79e5ac6fceee5d8f7c6c550 Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Thu, 11 May 2017 13:29:52 +0200 Subject: [FIX] web: keep focus on checkboxes after rerendering Previously, when a checkbox was re-rendered, it was losing focus since it was removed and re-created. Now, if the checkbox itself is the origin point of the re-rendering, we give the focus to the newly re-rendered checkbox, resulting in a seamless experience just as if the checkbox was never removed and re-rendered. --- addons/web/static/src/js/fields/basic_fields.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 6fc1736870f..b1b51e69e36 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -613,6 +613,20 @@ var FieldBoolean = AbstractField.extend({ isSet: function () { return true; }, + /** + * When the checkbox is rerendered, we need to check if it was the actual + * origin of the reset. If it is, we need to activate it back so it looks + * like it was not rerendered but is still the same input. + * + * @override + */ + reset: function (record, event) { + var rendered = this._super.apply(this, arguments); + if (event && event.target.name === this.name) { + this.activate(); + } + return rendered; + }, //-------------------------------------------------------------------------- // Private -- cgit v1.2.3 From 1c5ea99b7b82c2b6f28ad1a3dbffc1300fda6466 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 4 May 2017 13:27:31 +0200 Subject: [FIX] web: display a translation alert when saving the form view In the form view, when the user saves a record (with a multilang instance), an alert is displayed to display all modified translatable fields. --- addons/web/static/src/js/fields/basic_fields.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index b1b51e69e36..17cac8e86e5 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -56,14 +56,7 @@ var TranslatableFieldMixin = { * @private */ _onTranslate: function () { - this._rpc({ - route: '/web/dataset/call_button', - params: { - model: 'ir.translation', - method: 'translate_fields', - args: [this.model, this.res_id, this.name, this.record.getContext()], - } - }).then(this.do_action.bind(this)); + this.trigger_up('translate', {fieldName: this.name, id: this.dataPointID}); }, }; -- cgit v1.2.3 From ef35702cbcc10caa203eccdfe6ea5166fdac15c4 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 11 May 2017 10:47:18 +0200 Subject: [FIX] web: remove some memory leak --- addons/web/static/src/js/fields/basic_fields.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 17cac8e86e5..921169e5ab6 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1758,7 +1758,8 @@ var JournalDashboardGraph = AbstractField.extend({ this.data = JSON.parse(this.value); }, start: function () { - nv.utils.windowResize(this._onResize.bind(this)); + this._onResize = this._onResize.bind(this); + nv.utils.windowResize(this._onResize); return this._super.apply(this, arguments); }, destroy: function () { -- cgit v1.2.3 From 5f13b7f019a0aa56dabd426bb33b3be93f2954b0 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 15 May 2017 16:18:28 +0200 Subject: [IMP] web: update datepicker syntax with the new guidelines --- addons/web/static/src/js/fields/basic_fields.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 921169e5ab6..cafa59bbd00 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -345,7 +345,7 @@ var FieldDate = InputField.extend({ * @private */ _doDebouncedAction: function () { - this.datewidget.change_datetime(); + this.datewidget.changeDatetime(); }, /** @@ -354,7 +354,7 @@ var FieldDate = InputField.extend({ * @private */ _getValue: function () { - return this.datewidget.get_value(); + return this.datewidget.getValue(); }, /** * @override @@ -383,7 +383,7 @@ var FieldDate = InputField.extend({ * @private */ _renderEdit: function () { - this.datewidget.set_value(this.value); + this.datewidget.setValue(this.value); this.$input = this.datewidget.$input; }, @@ -412,7 +412,7 @@ var FieldDateTime = FieldDate.extend({ * @private */ _getValue: function () { - var value = this.datewidget.get_value(); + var value = this.datewidget.getValue(); return value && value.add(-this.getSession().tzOffset, 'minutes'); }, @@ -435,7 +435,7 @@ var FieldDateTime = FieldDate.extend({ */ _renderEdit: function () { var value = this.value && this.value.clone().add(this.getSession().tzOffset, 'minutes'); - this.datewidget.set_value(value); + this.datewidget.setValue(value); this.$input = this.datewidget.$input; }, -- cgit v1.2.3