From ef540eb006abac0d318f2a708384d125f6203662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Gonz=C3=A1lez?= <lgonzalez@vauxoo.com> Date: Thu, 22 Mar 2018 07:18:35 -0400 Subject: [PATCH] [FIX] web: Make accessible with keyboard the delete button on o2m fields (#23719) * [FIX] web: Make accessible with keyboard the delete button on o2m fields Currently, the delete button in one2many fields (trash icon) is not reachable when using the keyboard, because it's neither a link, nor a button or any other interactable HTML element, but a `<span>`. This change causes that button to be an actual HTML button keeping the same appearance, so it may be reached when using the keyboard. * [FIX] web: Modify test to expect button instead of span as o2m trash icon Since buttons to delete records in o2m fields (the trash icon) were changed from `<span>` to `<button>` to be able to access them with the keyboard, the test need to be modified so it expect the new element type and doesn't break. --- .../js/views/list/list_editable_renderer.js | 3 ++- addons/web/static/src/less/list_view.less | 8 ++++++++ .../tests/fields/relational_fields_tests.js | 20 +++++++++---------- .../test_new_api/static/tests/x2many.js | 2 +- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index 48078e2a22c1..64cfa8a1f301 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -498,7 +498,8 @@ ListRenderer.include({ _renderRow: function (record, index) { var $row = this._super.apply(this, arguments); if (this.addTrashIcon) { - var $icon = $('<span>', {class: 'fa fa-trash-o', name: 'delete'}); + var $icon = $('<button>', {class: 'fa fa-trash-o o_list_record_delete_btn', name: 'delete', + 'aria-label': _t('Delete row ') + (index+1)}); var $td = $('<td>', {class: 'o_list_record_delete'}).append($icon); $row.append($td); } diff --git a/addons/web/static/src/less/list_view.less b/addons/web/static/src/less/list_view.less index 395bf633e454..0948b566e621 100644 --- a/addons/web/static/src/less/list_view.less +++ b/addons/web/static/src/less/list_view.less @@ -70,6 +70,14 @@ width: 1px; // to prevent the column to expand } + .o_list_record_delete_btn { + padding: 0px; + background-style: none; + border-style: none; + height: 0px; + display: table-cell; + } + // Decoration of the row .text-bf { font-weight: bold; diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 731de4341210..933a76097d8b 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -3890,12 +3890,12 @@ QUnit.module('relational_fields', { }); form.$buttons.find('.o_form_button_edit').click(); - assert.strictEqual(form.$('td.o_list_record_delete span').length, 2, + assert.strictEqual(form.$('td.o_list_record_delete button').length, 2, "should have 2 delete buttons"); - form.$('td.o_list_record_delete span').first().click(); + form.$('td.o_list_record_delete button').first().click(); - assert.strictEqual(form.$('td.o_list_record_delete span').length, 1, + assert.strictEqual(form.$('td.o_list_record_delete button').length, 1, "should have 1 delete button (a record is supposed to have been unlinked)"); // save and check that the correct command has been generated @@ -3933,12 +3933,12 @@ QUnit.module('relational_fields', { }); form.$buttons.find('.o_form_button_edit').click(); - assert.strictEqual(form.$('td.o_list_record_delete span').length, 2, + assert.strictEqual(form.$('td.o_list_record_delete button').length, 2, "should have 2 delete buttons"); - form.$('td.o_list_record_delete span').first().click(); + form.$('td.o_list_record_delete button').first().click(); - assert.strictEqual(form.$('td.o_list_record_delete span').length, 1, + assert.strictEqual(form.$('td.o_list_record_delete button').length, 1, "should have 1 delete button (a record is supposed to have been deleted)"); // save and check that the correct command has been generated @@ -6682,8 +6682,8 @@ QUnit.module('relational_fields', { form.$('input.o_field_integer[name="int_field"]').val('0').trigger('input'); // delete and start over - form.$('.o_list_record_delete:first span').click(); - form.$('.o_list_record_delete:first span').click(); + form.$('.o_list_record_delete:first button').click(); + form.$('.o_list_record_delete:first button').click(); // enable the many2many onchange form.$('input.o_field_integer[name="int_field"]').val('10').trigger('input'); @@ -8416,7 +8416,7 @@ QUnit.module('relational_fields', { mode: 'edit', }, }); - form.$('span[name="delete"]').first().click(); + form.$('button[name="delete"]').first().click(); assert.strictEqual(form.$('.o_data_row').text(), 'from onchange', 'onchange has been properly applied'); form.destroy(); @@ -8456,7 +8456,7 @@ QUnit.module('relational_fields', { mode: 'edit', }, }); - form.$('span[name="delete"]').first().click(); + form.$('button[name="delete"]').first().click(); assert.strictEqual(form.$('.o_data_row').text(), 'from onchange id2from onchange id3', 'onchange has been properly applied'); form.destroy(); diff --git a/odoo/addons/test_new_api/static/tests/x2many.js b/odoo/addons/test_new_api/static/tests/x2many.js index ea976330eb95..30f351c21f67 100644 --- a/odoo/addons/test_new_api/static/tests/x2many.js +++ b/odoo/addons/test_new_api/static/tests/x2many.js @@ -408,7 +408,7 @@ odoo.define('web.test.x2many', function (require) { trigger: '.ui-autocomplete a:first', }, { // remove record content: "delete the last item in the editable list", - trigger: '.o_list_view .o_data_row td.o_list_record_delete span:visible:last', + trigger: '.o_list_view .o_data_row td.o_list_record_delete button:visible:last', }, { content: "test one2many onchange after delete", trigger: '.o_content:not(:has(textarea[name="message_concat"]:propValueContains(Administrator:d)))', -- GitLab