Commit 6cbdee92 authored by webchick's avatar webchick

Issue #3033943 by seanB, andrewmacpherson, phenaproxima, rainbreaw:...

Issue #3033943 by seanB, andrewmacpherson, phenaproxima, rainbreaw: MediaLibraryWidget selected items count is not conveyed to assistive tech correctly
parent 946dc09b
...@@ -298,28 +298,28 @@ ...@@ -298,28 +298,28 @@
* @param {number} remaining * @param {number} remaining
* The number of remaining slots. * The number of remaining slots.
*/ */
function updateSelectionInfo(remaining) { function updateSelectionCount(remaining) {
const $buttonPane = $( // When the remaining number of items is a negative number, we allow an
'.media-library-widget-modal .ui-dialog-buttonpane', // unlimited number of items. In that case we don't want to show the
); // number of remaining slots.
if (!$buttonPane.length) { const selectItemsText =
return; remaining < 0
} ? Drupal.formatPlural(
currentSelection.length,
// Add the selection count. '1 item selected',
const latestCount = Drupal.theme( '@count items selected',
'mediaLibrarySelectionCount', )
Drupal.MediaLibrary.currentSelection, : Drupal.formatPlural(
remaining, remaining,
); '@selected of @count item selected',
const $existingCount = $buttonPane.find( '@selected of @count items selected',
'.media-library-selected-count', {
); '@selected': currentSelection.length,
if ($existingCount.length) { },
$existingCount.replaceWith(latestCount); );
} else { // The selected count div could have been created outside of the
$buttonPane.append(latestCount); // context, so we unfortunately can't use context here.
} $('.js-media-library-selected-count').html(selectItemsText);
} }
// Update the selection array and the hidden form field when a media item // Update the selection array and the hidden form field when a media item
...@@ -351,21 +351,26 @@ ...@@ -351,21 +351,26 @@
$('.js-media-library-add-form-current-selection').val( $('.js-media-library-add-form-current-selection').val(
currentSelection.join(), currentSelection.join(),
); );
// Update the number of selected items in the button pane.
updateSelectionInfo(settings.media_library.selection_remaining);
// Prevent users from selecting more items than allowed.
if (
currentSelection.length === settings.media_library.selection_remaining
) {
disableItems($mediaItems.not(':checked'));
enableItems($mediaItems.filter(':checked'));
} else {
enableItems($mediaItems);
}
}); });
// The hidden selection form field changes when the selection is updated.
$('#media-library-modal-selection', $form)
.once('media-library-selection-change')
.on('change', e => {
updateSelectionCount(settings.media_library.selection_remaining);
// Prevent users from selecting more items than allowed.
if (
currentSelection.length ===
settings.media_library.selection_remaining
) {
disableItems($mediaItems.not(':checked'));
enableItems($mediaItems.filter(':checked'));
} else {
enableItems($mediaItems);
}
});
// Apply the current selection to the media library view. Changing the // Apply the current selection to the media library view. Changing the
// checkbox values triggers the change event for the media items. The // checkbox values triggers the change event for the media items. The
// change event handles updating the hidden selection field for the form. // change event handles updating the hidden selection field for the form.
...@@ -376,12 +381,21 @@ ...@@ -376,12 +381,21 @@
.trigger('change'); .trigger('change');
}); });
// Hide selection button if nothing is selected. We can't use the // Add the selection count to the button pane when a media library dialog
// context here because the dialog copies the select button. // is created.
$(window) $(window)
.once('media-library-toggle-buttons') .once('media-library-selection-info')
.on('dialog:aftercreate', () => { .on('dialog:aftercreate', () => {
updateSelectionInfo(settings.media_library.selection_remaining); // Since the dialog HTML is not part of the context, we can't use
// context here.
const $buttonPane = $(
'.media-library-widget-modal .ui-dialog-buttonpane',
);
if (!$buttonPane.length) {
return;
}
$buttonPane.append(Drupal.theme('mediaLibrarySelectionCount'));
updateSelectionCount(settings.media_library.selection_remaining);
}); });
}, },
}; };
...@@ -407,32 +421,10 @@ ...@@ -407,32 +421,10 @@
/** /**
* Theme function for the selection count. * Theme function for the selection count.
* *
* @param {Array.<number>} selection
* An array containing the selected media item IDs.
* @param {number} remaining
* The number of remaining slots.
*
* @return {string} * @return {string}
* The corresponding HTML. * The corresponding HTML.
*/ */
Drupal.theme.mediaLibrarySelectionCount = function(selection, remaining) { Drupal.theme.mediaLibrarySelectionCount = function() {
// When the remaining number of items is -1, we allow an unlimited number of return `<div class="media-library-selected-count js-media-library-selected-count" role="status" aria-live="polite" aria-atomic="true"></div>`;
// items. In that case we don't want to show the number of remaining slots.
let selectItemsText = Drupal.formatPlural(
remaining,
'@selected of @count item selected',
'@selected of @count items selected',
{
'@selected': selection.length,
},
);
if (remaining === -1) {
selectItemsText = Drupal.formatPlural(
selection.length,
'1 item selected',
'@count items selected',
);
}
return `<div class="media-library-selected-count" aria-live="polite">${selectItemsText}</div>`;
}; };
})(jQuery, Drupal, window); })(jQuery, Drupal, window);
...@@ -153,19 +153,12 @@ ...@@ -153,19 +153,12 @@
$items.prop('disabled', false).closest('.js-media-library-item').removeClass('media-library-item--disabled'); $items.prop('disabled', false).closest('.js-media-library-item').removeClass('media-library-item--disabled');
} }
function updateSelectionInfo(remaining) { function updateSelectionCount(remaining) {
var $buttonPane = $('.media-library-widget-modal .ui-dialog-buttonpane'); var selectItemsText = remaining < 0 ? Drupal.formatPlural(currentSelection.length, '1 item selected', '@count items selected') : Drupal.formatPlural(remaining, '@selected of @count item selected', '@selected of @count items selected', {
if (!$buttonPane.length) { '@selected': currentSelection.length
return; });
}
var latestCount = Drupal.theme('mediaLibrarySelectionCount', Drupal.MediaLibrary.currentSelection, remaining); $('.js-media-library-selected-count').html(selectItemsText);
var $existingCount = $buttonPane.find('.media-library-selected-count');
if ($existingCount.length) {
$existingCount.replaceWith(latestCount);
} else {
$buttonPane.append(latestCount);
}
} }
$mediaItems.once('media-item-change').on('change', function (e) { $mediaItems.once('media-item-change').on('change', function (e) {
...@@ -183,8 +176,10 @@ ...@@ -183,8 +176,10 @@
$form.find('#media-library-modal-selection').val(currentSelection.join()).trigger('change'); $form.find('#media-library-modal-selection').val(currentSelection.join()).trigger('change');
$('.js-media-library-add-form-current-selection').val(currentSelection.join()); $('.js-media-library-add-form-current-selection').val(currentSelection.join());
});
updateSelectionInfo(settings.media_library.selection_remaining); $('#media-library-modal-selection', $form).once('media-library-selection-change').on('change', function (e) {
updateSelectionCount(settings.media_library.selection_remaining);
if (currentSelection.length === settings.media_library.selection_remaining) { if (currentSelection.length === settings.media_library.selection_remaining) {
disableItems($mediaItems.not(':checked')); disableItems($mediaItems.not(':checked'));
...@@ -198,8 +193,13 @@ ...@@ -198,8 +193,13 @@
$form.find('input[type="checkbox"][value="' + value + '"]').prop('checked', true).trigger('change'); $form.find('input[type="checkbox"][value="' + value + '"]').prop('checked', true).trigger('change');
}); });
$(window).once('media-library-toggle-buttons').on('dialog:aftercreate', function () { $(window).once('media-library-selection-info').on('dialog:aftercreate', function () {
updateSelectionInfo(settings.media_library.selection_remaining); var $buttonPane = $('.media-library-widget-modal .ui-dialog-buttonpane');
if (!$buttonPane.length) {
return;
}
$buttonPane.append(Drupal.theme('mediaLibrarySelectionCount'));
updateSelectionCount(settings.media_library.selection_remaining);
}); });
} }
}; };
...@@ -212,13 +212,7 @@ ...@@ -212,13 +212,7 @@
} }
}; };
Drupal.theme.mediaLibrarySelectionCount = function (selection, remaining) { Drupal.theme.mediaLibrarySelectionCount = function () {
var selectItemsText = Drupal.formatPlural(remaining, '@selected of @count item selected', '@selected of @count items selected', { return '<div class="media-library-selected-count js-media-library-selected-count" role="status" aria-live="polite" aria-atomic="true"></div>';
'@selected': selection.length
});
if (remaining === -1) {
selectItemsText = Drupal.formatPlural(selection.length, '1 item selected', '@count items selected');
}
return '<div class="media-library-selected-count" aria-live="polite">' + selectItemsText + '</div>';
}; };
})(jQuery, Drupal, window); })(jQuery, Drupal, window);
\ No newline at end of file
...@@ -545,7 +545,9 @@ public function testWidget() { ...@@ -545,7 +545,9 @@ public function testWidget() {
// Assert the number of selected items is displayed correctly. // Assert the number of selected items is displayed correctly.
$assert_session->elementExists('css', '.media-library-selected-count'); $assert_session->elementExists('css', '.media-library-selected-count');
$assert_session->elementTextContains('css', '.media-library-selected-count', '0 of 2 items selected'); $assert_session->elementTextContains('css', '.media-library-selected-count', '0 of 2 items selected');
$assert_session->elementAttributeContains('css', '.media-library-selected-count', 'role', 'status');
$assert_session->elementAttributeContains('css', '.media-library-selected-count', 'aria-live', 'polite'); $assert_session->elementAttributeContains('css', '.media-library-selected-count', 'aria-live', 'polite');
$assert_session->elementAttributeContains('css', '.media-library-selected-count', 'aria-atomic', 'true');
// Select a media item, assert the hidden selection field contains the ID of // Select a media item, assert the hidden selection field contains the ID of
// the selected item. // the selected item.
$checkboxes = $page->findAll('css', '.media-library-view .js-click-to-select-checkbox input'); $checkboxes = $page->findAll('css', '.media-library-view .js-click-to-select-checkbox input');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment