From 5838e47ab504340abc00ade9b8a18289aba1c03a Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Mon, 25 Mar 2019 16:44:32 +0000 Subject: [PATCH] [FIX] web: modal in modal => no block mobile On a form view: - we open a modal form view - in this modal we open a modal form view - we close that second modal => the modal is closed and the first one is still opened, but on mobile we can't scroll to above or below the modal. This is because bootstrap remove .modal-open class on body when we close the second modal, but this class is necessary to scroll (this is not much an issue on desktop since scroll is often not necessary). We already had a fix that was weakened in 02a063fd73. With this changeset, we keep .modal-open as long as a modal is opened. Without the change, added test failed with: 10. Modal is said opened (expected: true, result: false) opw-1948423 closes #32106 Signed-off-by: Nicolas Lempereur (nle) --- addons/web/static/src/js/core/dialog.js | 10 +-- .../tests/fields/relational_fields_tests.js | 61 +++++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/addons/web/static/src/js/core/dialog.js b/addons/web/static/src/js/core/dialog.js index 5ba24f57cad..5335689b0b0 100644 --- a/addons/web/static/src/js/core/dialog.js +++ b/addons/web/static/src/js/core/dialog.js @@ -204,13 +204,13 @@ var Dialog = Widget.extend({ this.$modal.remove(); } - if (!isFocusSet) { - var modals = $('body > .modal').filter(':visible'); - if (modals.length) { + var modals = $('body > .modal').filter(':visible'); + if (modals.length) { + if (!isFocusSet) { modals.last().focus(); - // Keep class modal-open (deleted by bootstrap hide fnct) on body to allow scrolling inside the modal - $('body').addClass('modal-open'); } + // Keep class modal-open (deleted by bootstrap hide fnct) on body to allow scrolling inside the modal + $('body').addClass('modal-open'); } }, /** diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index d913be66967..05d9a9cc34a 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -2916,6 +2916,67 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('focus when closing many2one modal in many2one modal', function (assert) { + assert.expect(12); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '', + res_id: 2, + archs: { + 'partner,false,form': '
' + }, + mockRPC: function (route, args) { + if (args.method === 'get_formview_id') { + return $.when(false); + } + return this._super(route, args); + }, + }); + + // Open many2one modal + form.$buttons.find('.btn.o_form_button_edit').click(); + form.$('.o_external_button').click(); + var $originalModal = $('.modal-dialog'); + var $focusedModal = $(document.activeElement).closest('.modal-dialog'); + + assert.equal($originalModal.length, 1, 'There should be one modal'); + assert.equal($originalModal[0], $focusedModal[0], 'Modal is focused'); + assert.ok($('body').hasClass('modal-open'), 'Modal is said opened'); + + // Open many2one modal of field in many2one modal + $originalModal.find('.o_external_button').click(); + var $modals = $('.modal-dialog'); + $focusedModal = $(document.activeElement).closest('.modal-dialog'); + + assert.equal($modals.length, 2, 'There should be two modals'); + assert.equal($modals[1], $focusedModal[0], 'Last modal is focused'); + assert.ok($('body').hasClass('modal-open'), 'Modal is said opened'); + + // Close second modal + $modals.last().find('button[class="close"]').click(); + var $modal = $('.modal-dialog'); + $focusedModal = $(document.activeElement).closest('.modal-dialog'); + + assert.equal($modal.length, 1, 'There should be one modal'); + assert.equal($modal[0], $originalModal[0], 'First modal is still opened'); + assert.equal($modal[0], $focusedModal[0], 'Modal is focused'); + assert.ok($('body').hasClass('modal-open'), 'Modal is said opened'); + + // Close first modal + $modal.find('button[class="close"]').click(); + $modal = $('.modal-dialog.modal-lg'); + + assert.equal($modal.length, 0, 'There should be no modal'); + assert.notOk($('body').hasClass('modal-open'), 'Modal is not said opened'); + + form.destroy(); + }); + QUnit.module('FieldOne2Many'); QUnit.test('New record with a o2m also with 2 new records, ordered, and resequenced', function (assert) {