summaryrefslogtreecommitdiff
path: root/addons/web
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web')
-rw-r--r--addons/web/static/src/js/chrome/action_manager.js18
-rw-r--r--addons/web/static/src/js/chrome/view_manager.js13
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js12
-rw-r--r--addons/web/static/src/js/views/basic/basic_controller.js2
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js3
-rw-r--r--addons/web/static/tests/fields/relational_fields_tests.js80
6 files changed, 103 insertions, 25 deletions
diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js
index 280a90cec8d..5d4a44ba420 100644
--- a/addons/web/static/src/js/chrome/action_manager.js
+++ b/addons/web/static/src/js/chrome/action_manager.js
@@ -420,16 +420,20 @@ var ActionManager = Widget.extend({
return this.inner_widget;
},
history_back: function() {
- var nb_views = this.inner_action.get_nb_views();
- if (nb_views > 1) {
+ var nbViews = this.inner_action.get_nb_views();
+ if (nbViews > 1) {
// Stay on this action, but select the previous view
- return this.select_action(this.inner_action, nb_views - 2);
+ return this.select_action(this.inner_action, nbViews - 2);
}
- if (this.action_stack.length > 1) {
+ var nbActions = this.action_stack.length;
+ if (nbActions > 1) {
// Select the previous action
- var action = this.action_stack[this.action_stack.length - 2];
- nb_views = action.get_nb_views();
- return this.select_action(action, nb_views - 1);
+ var action = this.action_stack[nbActions - 2];
+ nbViews = action.get_nb_views();
+ return this.select_action(action, nbViews - 1);
+ }
+ else if (nbActions === 1 && nbViews === 1) {
+ return this.select_action(this.action_stack[0], 0);
}
return $.Deferred().reject();
},
diff --git a/addons/web/static/src/js/chrome/view_manager.js b/addons/web/static/src/js/chrome/view_manager.js
index 14ed4bdebc7..9b431d3e57a 100644
--- a/addons/web/static/src/js/chrome/view_manager.js
+++ b/addons/web/static/src/js/chrome/view_manager.js
@@ -561,7 +561,8 @@ var ViewManager = Widget.extend(ControlPanelMixin, {
var self = this;
var result_handler = on_closed || function () {};
var context = new Context(this.env.context, action_data.context || {});
- var record_id = res_ids && res_ids[0];
+ // OR NULL hereunder: pyeval waits specifically for a null value, different from undefined
+ var record_id = res_ids && res_ids[0] || null;
// response handler
var handler = function (action) {
@@ -651,18 +652,10 @@ var ViewManager = Widget.extend(ControlPanelMixin, {
* will call this very view manager to activate the previous view.
* @todo: directly switch to previous view
*
- * A special case is done in the case that there is no previous view. When
- * that happens, we simply rerender the current view.
- *
* @private
*/
_onSwitchToPreviousView: function () {
- if (this.view_stack.length === 1) {
- var currentView = this.view_stack[0].controller;
- currentView.update({}, {reload: false});
- } else {
- this.do_action('history_back');
- }
+ this.trigger_up('history_back');
}
});
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index 567c54abcb1..14512c02912 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -485,8 +485,16 @@ var FieldMany2One = AbstractField.extend({
},
/**
* @private
+ *
+ * @param {OdooEvent} ev
*/
- _onInputKeyup: function () {
+ _onInputKeyup: function (ev) {
+ if (ev.which === $.ui.keyCode.ENTER) {
+ // If we pressed enter, we want to prevent _onInputFocusout from
+ // executing since it would open a M2O dialog to request
+ // confirmation that the many2one is not properly set.
+ return;
+ }
if (this.$input.val() === "") {
this.reinitialize(false);
} else if (this._getDisplayName(this.m2o_value) !== this.$input.val()) {
@@ -1909,7 +1917,7 @@ var FieldRadio = FieldSelection.extend({
this._super.apply(this, arguments);
if (this.mode === 'edit') {
this.tagName = 'div';
- this.className += this.nodeOptions.horizontal ? 'o_horizontal' : 'o_vertical';
+ this.className += this.nodeOptions.horizontal ? ' o_horizontal' : ' o_vertical';
}
this.unique_id = _.uniqueId("radio");
this._setValues();
diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js
index 82dc6f90d26..cc72816a85d 100644
--- a/addons/web/static/src/js/views/basic/basic_controller.js
+++ b/addons/web/static/src/js/views/basic/basic_controller.js
@@ -250,7 +250,7 @@ var BasicController = AbstractController.extend(FieldManagerMixin, {
on_fail: function (reason) {
reload().always(function() {
def.reject(reason);
- })
+ });
},
on_success: def.resolve.bind(def),
});
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index 906464a5a26..c562fa388f0 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -1187,7 +1187,8 @@ var BasicModel = AbstractModel.extend({
}
var self = this;
- var list = this.localData[record._changes[fieldName] || record.data[fieldName]];
+ var localID = (record._changes && record._changes[fieldName]) || record.data[fieldName];
+ var list = this.localData[localID];
var field = record.fields[fieldName];
var fieldInfo = record.fieldsInfo[viewType || record.viewType][fieldName];
var view = fieldInfo.views && fieldInfo.views[fieldInfo.mode];
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js
index d4d3a6307f9..aacbb744252 100644
--- a/addons/web/static/tests/fields/relational_fields_tests.js
+++ b/addons/web/static/tests/fields/relational_fields_tests.js
@@ -30,6 +30,7 @@ QUnit.module('relational_fields', {
type: "selection",
selection: [['red', "Red"], ['black', "Black"]],
default: 'red',
+ string: "Color",
},
date: {string: "Some Date", type: "date"},
datetime: {string: "Datetime Field", type: 'datetime'},
@@ -1140,6 +1141,52 @@ QUnit.module('relational_fields', {
});
});
+ QUnit.test('pressing ENTER on a \'no_quick_create\' many2one should not trigger M2ODialog', function (assert) {
+ var done = assert.async();
+ assert.expect(1);
+
+ var M2O_DELAY = relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY;
+ relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY = 0;
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: '<form>' +
+ '<field name="trululu" options="{\'no_quick_create\': True}"/>' +
+ '<field name="foo"/>' +
+ '</form>',
+ archs: {
+ 'partner,false,form': '<form string="Partners"><field name="display_name"/></form>',
+ },
+ });
+
+ var $input = form.$('.o_field_many2one input');
+ $input.val("Something that does not exist").trigger('input');
+ $('.ui-autocomplete .ui-menu-item a:contains(Create and)').trigger('mouseenter');
+ concurrency.delay(0).then(function() {
+ $input.trigger($.Event('keydown', {
+ which: $.ui.keyCode.ENTER,
+ keyCode: $.ui.keyCode.ENTER,
+ }));
+ $input.trigger($.Event('keypress', {
+ which: $.ui.keyCode.ENTER,
+ keyCode: $.ui.keyCode.ENTER,
+ }));
+ $input.trigger($.Event('keyup', {
+ which: $.ui.keyCode.ENTER,
+ keyCode: $.ui.keyCode.ENTER,
+ }));
+ concurrency.delay(0).then(function() {
+ $input.blur();
+ assert.strictEqual($('.modal').length, 1,
+ "should have one modal in body");
+ form.destroy();
+ done();
+ });
+ });
+ });
+
QUnit.test('many2one in editable list + onchange, with enter [REQUIRE FOCUS]', function (assert) {
assert.expect(6);
var done = assert.async();
@@ -1472,11 +1519,11 @@ QUnit.module('relational_fields', {
}, true);
assert.strictEqual(form.$('td.o_data_cell:not(.o_handle_cell)').text(), "My little Foo Valueblipyop",
- "should have the 3 rows in the correct order")
+ "should have the 3 rows in the correct order");
form.$buttons.find('.o_form_button_edit').click();
assert.strictEqual(form.$('td.o_data_cell:not(.o_handle_cell)').text(), "My little Foo Valueblipyop",
- "should still have the 3 rows in the correct order")
+ "should still have the 3 rows in the correct order");
// Drag and drop the fourth line in second position
testUtils.dragAndDrop(
@@ -1489,11 +1536,11 @@ QUnit.module('relational_fields', {
"sequences values should be incremental starting from the previous minimum one");
assert.strictEqual(form.$('td.o_data_cell:not(.o_handle_cell)').text(), "blipMy little Foo Valueyop",
- "should have the 3 rows in the new order")
+ "should have the 3 rows in the new order");
form.$buttons.find('.o_form_button_save').click();
assert.strictEqual(form.$('td.o_data_cell:not(.o_handle_cell)').text(), "blipMy little Foo Valueyop",
- "should still have the 3 rows in the new order")
+ "should still have the 3 rows in the new order");
form.destroy();
});
@@ -6412,6 +6459,31 @@ QUnit.module('relational_fields', {
form.destroy();
});
+ QUnit.test('fieldradio widget has o_horizontal or o_vertical class', function (assert) {
+ assert.expect(2);
+
+ this.data.partner.fields.color2 = this.data.partner.fields.color;
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: '<form>' +
+ '<group>' +
+ '<field name="color" widget="radio"/>' +
+ '<field name="color2" widget="radio" options="{\'horizontal\': True}"/>' +
+ '</group>' +
+ '</form>',
+ });
+
+ var btn1 = form.$('div.o_field_radio.o_vertical');
+ var btn2 = form.$('div.o_field_radio.o_horizontal');
+
+ assert.strictEqual(btn1.length, 1, "should have o_vertical class");
+ assert.strictEqual(btn2.length, 1, "should have o_horizontal class");
+ form.destroy();
+ });
+
QUnit.test('fieldradio widget with numerical keys encoded as strings', function (assert) {
assert.expect(5);