| @@ -38,13 +38,36 @@ | ||
| 38 | 38 | if ($.fn.select2) { |
| 39 | 39 | $('select[multiple="multiple"]').each(function() { |
| 40 | 40 | if (!$(this).hasClass('select2-hidden-accessible')) { |
| 41 | 41 | |
| 42 | - $(this).select2({ | |
| 42 | + var $field = $(this); | |
| 43 | + var fieldLabel = $.trim($('label[for="' + $field.attr('id') + '"]').first().text()) | |
| 44 | + || $field.attr('placeholder') | |
| 45 | + || 'Select options'; | |
| 46 | + | |
| 47 | + $field.select2({ | |
| 43 | 48 | width: '100%', |
| 44 | - placeholder: $(this).attr('placeholder') || 'Select options', | |
| 49 | + placeholder: $field.attr('placeholder') || 'Select options', | |
| 45 | 50 | closeOnSelect: false, |
| 46 | 51 | allowClear: true |
| 52 | + }); | |
| 53 | + | |
| 54 | + // Name the search box Select2 builds for itself. Select2 4.0.13 | |
| 55 | + // renders `.select2-search__field` with no label and no aria-label, | |
| 56 | + // so a screen reader announces it as an unnamed text field. On a | |
| 57 | + // multiselect that box lives inside the selection control and is | |
| 58 | + // present from the moment Select2 initialises — not only while the | |
| 59 | + // dropdown is open — so it is labelled here, and again on open to | |
| 60 | + // cover the search field Select2 renders into the dropdown itself. | |
| 61 | + var labelSearchFields = function ($root) { | |
| 62 | + $root.find('.select2-search__field') | |
| 63 | + .filter(function () { return !this.getAttribute('aria-label'); }) | |
| 64 | + .attr('aria-label', fieldLabel); | |
| 65 | + }; | |
| 66 | + | |
| 67 | + labelSearchFields($field.next('.select2-container')); | |
| 68 | + $field.on('select2:open', function () { | |
| 69 | + labelSearchFields($('.select2-container--open')); | |
| 47 | 70 | }); |
| 48 | 71 | } |
| 49 | 72 | }); |
| 50 | 73 | } |