diff --git a/addons/web/static/src/js/views/calendar/calendar_view.js b/addons/web/static/src/js/views/calendar/calendar_view.js
index 7f58ca55632..bfeb5c5cbbb 100644
--- a/addons/web/static/src/js/views/calendar/calendar_view.js
+++ b/addons/web/static/src/js/views/calendar/calendar_view.js
@@ -112,8 +112,20 @@ var CalendarView = AbstractView.extend({
//if quick_add = is NOT False and IS specified in view, we this one for widgets.QuickCreate'
this.controllerParams.quickAddPop = (!('quick_add' in attrs) || utils.toBoolElse(attrs.quick_add+'', true));
this.controllerParams.disableQuickCreate = params.disable_quick_create || !this.controllerParams.quickAddPop;
- // If this field is set ot true, we don't open the event in form view, but in a popup with the view_id passed by this parameter
- this.controllerParams.formViewId = !attrs.form_view_id || !utils.toBoolElse(attrs.form_view_id, true) ? false : attrs.form_view_id;
+
+ // If form_view_id is set, then the calendar view will open a form view
+ // with this id, when it needs to edit or create an event.
+ this.controllerParams.formViewId =
+ attrs.form_view_id ? parseInt(attrs.form_view_id, 10) : false;
+ if (!this.controllerParams.formViewId && params.action) {
+ var formViewDescr = _.find(params.action.views, function (v) {
+ return v[1] === 'form';
+ });
+ if (formViewDescr) {
+ this.controllerParams.formViewId = formViewDescr[0];
+ }
+ }
+
this.controllerParams.readonlyFormViewId = !attrs.readonly_form_view_id || !utils.toBoolElse(attrs.readonly_form_view_id, true) ? false : attrs.readonly_form_view_id;
this.controllerParams.eventOpenPopup = utils.toBoolElse(attrs.event_open_popup || '', false);
this.controllerParams.mapping = mapping;
diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js
index a47cd71fe48..08f3bb95c77 100644
--- a/addons/web/static/tests/helpers/mock_server.js
+++ b/addons/web/static/tests/helpers/mock_server.js
@@ -110,14 +110,14 @@ var MockServer = Class.extend({
console.log('%c[rpc] response' + route, 'color: blue; font-weight: bold;', JSON.parse(resultString));
}
return JSON.parse(resultString);
- }).fail(function (result) {
+ }, function (result, event) {
var errorString = JSON.stringify(result || false);
if (logLevel === 1) {
console.log('Mock: (ERROR)' + route, JSON.parse(errorString));
} else if (logLevel === 2) {
console.log('%c[rpc] response (error) ' + route, 'color: orange; font-weight: bold;', JSON.parse(errorString));
}
- return JSON.parse(errorString);
+ return $.Deferred().reject(errorString, event || $.Event());
});
},
diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js
index b6bebc0f4a2..4840e05af02 100644
--- a/addons/web/static/tests/views/calendar_tests.js
+++ b/addons/web/static/tests/views/calendar_tests.js
@@ -1766,6 +1766,101 @@ QUnit.module('Views', {
calendar.destroy();
});
+
+ QUnit.test('form_view_id attribute works (for creating events)', function (assert) {
+ assert.expect(1);
+
+ var calendar = createView({
+ View: CalendarView,
+ model: 'event',
+ data: this.data,
+ arch: ''+
+ ''+
+ '',
+ archs: archs,
+ viewOptions: {
+ initialDate: initialDate,
+ },
+ mockRPC: function (route, args) {
+ if (args.method === "create") {
+ // we simulate here the case where a create call with just
+ // the field name fails. This is a normal flow, the server
+ // reject the create rpc (quick create), then the web client
+ // fall back to a form view. This happens typically when a
+ // model has required fields
+ return $.Deferred().reject('None shall pass!');
+ }
+ return this._super(route, args);
+ },
+ intercepts: {
+ do_action: function (event) {
+ assert.strictEqual(event.data.action.views[0][0], 42,
+ "should do a do_action with view id 42");
+ },
+ },
+ });
+
+ var $cell = calendar.$('.fc-day-grid .fc-row:eq(2) .fc-day:eq(2)');
+ testUtils.triggerMouseEvent($cell, "mousedown");
+ testUtils.triggerMouseEvent($cell, "mouseup");
+ var $input = $('.modal-body input:first');
+ $input.val("It's just a fleshwound").trigger('input');
+ $('.modal button.btn:contains(Create)').trigger('click');
+
+ calendar.destroy();
+ });
+
+ QUnit.test('calendar fallback to form view id in action if necessary', function (assert) {
+ assert.expect(1);
+
+ var calendar = createView({
+ View: CalendarView,
+ model: 'event',
+ data: this.data,
+ arch: ' '+
+ ''+
+ '',
+ archs: archs,
+ viewOptions: {
+ initialDate: initialDate,
+ action: {views: [[1, 'kanban'], [43, 'form']]}
+ },
+ mockRPC: function (route, args) {
+ if (args.method === "create") {
+ // we simulate here the case where a create call with just
+ // the field name fails. This is a normal flow, the server
+ // reject the create rpc (quick create), then the web client
+ // fall back to a form view. This happens typically when a
+ // model has required fields
+ return $.Deferred().reject('None shall pass!');
+ }
+ return this._super(route, args);
+ },
+ intercepts: {
+ do_action: function (event) {
+ assert.strictEqual(event.data.action.views[0][0], 43,
+ "should do a do_action with view id 43");
+ },
+ },
+ });
+
+ var $cell = calendar.$('.fc-day-grid .fc-row:eq(2) .fc-day:eq(2)');
+ testUtils.triggerMouseEvent($cell, "mousedown");
+ testUtils.triggerMouseEvent($cell, "mouseup");
+ var $input = $('.modal-body input:first');
+ $input.val("It's just a fleshwound").trigger('input');
+ $('.modal button.btn:contains(Create)').trigger('click');
+
+ calendar.destroy();
+ });
+
});
});
diff --git a/doc/reference/views.rst b/doc/reference/views.rst
index d53ff2b6ce7..d23a0db9da3 100644
--- a/doc/reference/views.rst
+++ b/doc/reference/views.rst
@@ -954,7 +954,9 @@ calendar view are:
``readonly_form_view_id``
view to open in readonly mode
``form_view_id``
- view to open when the user create or edit an event
+ view to open when the user create or edit an event. Note that if this attribute
+ is not set, the calendar view will fall back to the id of the form view in the
+ current action, if any.
``event_open_popup``
If the option 'event_open_popup' is set to true, then the calendar view will
open events (or records) in a FormViewDialog. Otherwise, it will open events