MDL-51821 forms: Better handling for deselecting items in autocomplete

Fixes 3 problems with deselecting items in an autocomplete field:

1. Keep track of whether items were in the offical suggestion list, or are newly created
   tags and remove the "newly created tags" from the suggestion list when they are
   deselected
2. Change the aria-role for the selected items list when items cannot be deselected (and
   do not treat it like a multiselect list).
3. When leaving and returning focus to the selected items list, remember the last
   active-descendant.
This commit is contained in:
Damyon Wiese 2015-10-19 14:02:42 +08:00
parent 3365244fda
commit bdd60287e5
3 changed files with 26 additions and 23 deletions

File diff suppressed because one or more lines are too long

View File

@ -92,6 +92,10 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
originalSelect.children('option').each(function(index, ele) {
if ($(ele).attr('value') == selectedItemValue) {
$(ele).prop('selected', false);
// We remove newly created custom tags from the suggestions list when they are deselected.
if ($(ele).attr('data-iscustom')) {
$(ele).remove();
}
}
});
}
@ -341,34 +345,18 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
option.attr('value', tag);
originalSelect.append(option);
option.prop('selected', true);
// We mark newly created custom options as we handle them differently if they are "deselected".
option.attr('data-iscustom', true);
}
}
});
// Get the selection element.
var newSelection = $(document.getElementById(selectionId));
// Build up a valid context to re-render the selection.
var items = [];
originalSelect.children('option').each(function(index, ele) {
if ($(ele).prop('selected')) {
items.push( { label: $(ele).html(), value: $(ele).attr('value') } );
}
});
var context = {
selectionId: selectionId,
items: items,
multiple: multiple
};
// Re-render the selection.
templates.render('core/form_autocomplete_selection', context).done(function(newHTML) {
// Update the page.
newSelection.empty().append($(newHTML).html());
}).fail(notification.exception);
updateSelectionList(selectionId, inputId, originalSelect, multiple);
// Clear the input field.
inputElement.val('');
// Close the suggestions list.
closeSuggestions(inputId, suggestionsId, selectionId);
// Trigger a change event so that the mforms javascript can check for required fields etc.
originalSelect.change();
};
/**
@ -385,6 +373,12 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
// Build up a valid context to re-render the template.
var items = [];
var newSelection = $(document.getElementById(selectionId));
var activeId = newSelection.attr('aria-activedescendant');
var activeValue = false;
if (activeId) {
activeValue = $(document.getElementById(activeId)).attr('data-value');
}
originalSelect.children('option').each(function(index, ele) {
if ($(ele).prop('selected')) {
items.push( { label: $(ele).html(), value: $(ele).attr('value') } );
@ -399,6 +393,15 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
templates.render('core/form_autocomplete_selection', context).done(function(newHTML) {
// Add it to the page.
newSelection.empty().append($(newHTML).html());
if (activeValue !== false) {
// Reselect any previously selected item.
newSelection.children('[aria-selected=true]').each(function(index, ele) {
if ($(ele).attr('data-value') === activeValue) {
activateSelection(index, selectionId);
}
});
}
}).fail(notification.exception);
// Because this function get's called after changing the selection, this is a good place
// to trigger a change notification.

View File

@ -36,7 +36,7 @@
{ "label": "Another item label with <strong>tags</strong>", "value": "4" }
]}
}}
<div class="form-autocomplete-selection {{#multiple}}form-autocomplete-multiple{{/multiple}}" id="{{selectionId}}" role="list" aria-atomic="true" tabindex="0" aria-multiselectable="true">
<div class="form-autocomplete-selection {{#multiple}}form-autocomplete-multiple{{/multiple}}" id="{{selectionId}}" role="list" aria-atomic="true" {{#multiple}}tabindex="0" aria-multiselectable="true"{{/multiple}}>
<span class="accesshide">{{#str}}selecteditems, form{{/str}}</span>
{{#items}}
<span role="listitem" data-value="{{value}}" aria-selected="true" class="label label-info">