From 3d60881d5d7e18a549dcf39f19c122f28336e7d3 Mon Sep 17 00:00:00 2001 From: Michael Hawkins Date: Mon, 18 May 2020 16:07:05 +0800 Subject: [PATCH] MDL-68612 user: Participants filter row accessibility improvements More clearly defining each filter row and its ability to remove filter selections for screen readers. --- lang/en/user.php | 2 + .../local/participantsfilter/selectors.min.js | Bin 1077 -> 1129 bytes .../participantsfilter/selectors.min.js.map | Bin 3995 -> 4130 bytes user/amd/build/participantsfilter.min.js | Bin 6305 -> 8141 bytes user/amd/build/participantsfilter.min.js.map | Bin 20484 -> 23084 bytes .../src/local/participantsfilter/selectors.js | 1 + user/amd/src/participantsfilter.js | 46 ++++++++++++-- user/classes/output/participants_filter.php | 1 + .../autocomplete_selection_items.mustache | 5 +- .../participantsfilter/filterrow.mustache | 58 ++++++++++-------- 10 files changed, 81 insertions(+), 32 deletions(-) diff --git a/lang/en/user.php b/lang/en/user.php index 5eee2cb2b43..ee3c7fdf6d8 100644 --- a/lang/en/user.php +++ b/lang/en/user.php @@ -29,7 +29,9 @@ $string['adverbfor_or'] = 'or'; $string['applyfilters'] = 'Apply filters'; $string['clearfilterrow'] = 'Remove filter row'; $string['clearfilters'] = 'Clear filters'; +$string['clearfilterselection'] = 'Remove "{$a}" from filter'; $string['countparticipantsfound'] = '{$a} participants found'; +$string['filterrowlegend'] = 'Filter {$a}'; $string['filtersetmatchdescription'] = 'How multiple filters should be combined'; $string['match'] = 'Match'; $string['matchofthefollowing'] = 'of the following:'; diff --git a/user/amd/build/local/participantsfilter/selectors.min.js b/user/amd/build/local/participantsfilter/selectors.min.js index 21be6651f9b3536a0d87c6b9bc521d4df7a7b72b..69b63a7f064bb9764f0c70f08450d2ca5c10dfc2 100644 GIT binary patch delta 63 zcmdnW@seZ13ua@TlFEWqpUmQt;MAPdYE#z>aU>}=~fC;#PF1prj*2WS8Q diff --git a/user/amd/build/participantsfilter.min.js b/user/amd/build/participantsfilter.min.js index bbb20c6b68e41b4667f88cafca3ea276528c9054..0269fe3efc5ad1c567cfed45722d88f5a9f13989 100644 GIT binary patch delta 2599 zcmZ`*&2!sC6dxtir1}1EY^S89irTu`Mpol8O@kdZQ=n4{bebXMt8Qpl(#lq1Nv^bV z;>Mm_xX}yjg%hR25e{@1E}h{DCuYiU;Q#}-!l8cv0|(wpc9JH}!K>B!y{Gr_`~9Sc zxt|ul`9bIkDEnTpx|A|I(Y2IalXX-uv{l(a1yfs-O;oVpVxd9_E+teb!=;Q0HSCL& zebMC!HXH3;gmtM~7FJokI}q$|pLM@32y1Na(7COOjM1h~Xz06Q750sW7p-ozIx=cn zp=(gvb49q>q-Eb*7hSS0-l$i}W#9LFS-R@haK$!7Oet}yRHU95RDFU?(e>P{O^J{7 z3K4BLpx8Btddt1)ik@#0U)%y)9sX+BD3J&DeOwnkeU%tA5S=ifVj0(nh{fV^-O;^@ z8rf6NUy+gM5L)(3Roay)B(Lab)3)SkjN;-7a3clOx80JYX%v$8ED@uvR_S*mkEm^i zc0GEsTJ=5ZaZ8nY%aNyQ;0kY;8dPk9$n#1zhoZo-2L#rPOa`ll2c`O<0U07gd+uI! zu|p!CYq%OO}Nj~D-K2hnwx8zivHI!=e%yJ4mBzNYDohJF#N72=j?8R^iz zcw4XlYaG{xHmjIg9F?!xrP&&)xr1Gw*@v1!z@8rR1fRXva{|`Q zp3{j?Yr~r-&7<4wyPng)l;3+!0&A}KrpIjcZbxCs7ip}*&f4)D^oX5k*p#G)7q_DxP!8$bm z&%q<913QU?ki9%K)!%OVc1>fw@sR;_y-jMeu9}!aT2!^{3MdShEL6~;9>=Q@Xk;CJ zyrEci$p+Qt+MT@zXRUfTeWQ8~OlR^60P`~DV`wR5tUh>8ol=FAh-*qnwOtpI;ZHP* z`bx9)ta(-)yy@%*q^{)_aGU)tE`Z3iPl~yfX-%tnpue+=yHE4ELQTdUTW|mpb@uNN zM`C99Vh1p7V{mXc1_8Vi3h(27P;xZkutHU`VUQ|+g`lQVV|Pa8kF6H*O0(Hi*7s9r zdzz!{*OB7EC`hwAqb~||wl!*?js0N`99No2W3v&NrkFdn0bqMN=5{F88b39$hxsv; zAB=z8!CXsCvs;Pd9saqW$aXl5?Z?=Ei3AieI*|jhd1WFC=~O4qb+EsmICZ26{kyln z)SZqE#Q4`0LotB^H?~aAh~64|pjg@-4JU}o-*Io*0gV+7wJ?^=!G}h1rBI2596mgd z+8ODFS`CA;ytzi|c`2qE$Q!`@O^$bETQu^ZA3nJq2E>>%&VsqPJbd4!&a6p3j?Y*0xcpV%-m`RF>icNr4Zih~XE2 zbsvlu_DmW?>Dj~$K#4UjF*BJI9QGuchWk&G8jLI6|CQ7x*Wm*R(%;?) delta 1249 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 delta 2954 zcmd5;OK)3M5Y}~ClBRi;B(~$2+Hq1y(;Jc|wwtuH;hb}w8pYYSRZUalIC1R6 zaUQOO%7O(iQK_?{fIwmkQo&FpeghJ81MKJ;v48~<5+InF;}%Cv5n{#WUi-|Pd3^KD z%>D3F$o#Z;mEjd9ipY;2_prDQ6bS}NuXBAX4EfkG;s$>;D#HkC^k zm!YNRQu*_m(*`UYEIgUXNwFh^85imi4|6T8%0C|*HQ?3SWAzash9hP~sHvMr7W^@D zRSGd@Dj~x1BE3>56Cp)E(^e8>UEZ-S;q7{_u>^PPR=Nt(Toi&;2j!$WE5z)oG-DMb z8L8mLT=c=-5r8U^=FJ6+^P>7LvXjg*SDf5wioDfxDwlv8Lfnt znuLzS{c=EG-il;ZloXR@5TCX=FGMWIp-$0pMyBYsBF*r)h+JixNjgz^c;)c#O$A11 zkxx!YxY;mtKFdejY$HTZJ2pf|S1IYG=q?Mi4K#~^GVDA1gV@qIU$-48(VbPuH}+j0 zX6r)WfzWQ*xUld*vD0;%VF}t<#kxD}(54y)jt6ta%apY`sSsNc3$uzgI!{6y1^7yl z)J6wsWJi{iI>Z`XdZ^qb3H?pSuTRh|s-@T>ZIzP@Zkp{YtP4swQigck!m32#q&Tr! zafk{^BglH}l-aR9p{qTSRaLq=Eqx(r_TX)D7+FzkY!4|(26O!9e%;<{@iy6-9`}#B zn%x(NSr^%cO~F8JN7>_vXjXAHLZ_i!>RcWmi8T60kKK-dz z*pBHwh{2sU|I{|?Jxu6F@|p5or%To(J|YFljX`8ZdO%lupee|?==M?}NVGee z<__vkm|K{DKSC4Z^vmYN3XF}UC*EedDrte&cAedI@TEBM;LFYHVy%|*{Zu#Crn%tb`BQZ z#~o<%4Ywa#l+Kp4pem7!wGR^23xlY@lYdhN;U{;;sGcWmN#RgnF|Ny!Qz*we) zZh9KEt}zF{d3?RY)6DeML}lV*%Tn?*r3pK=tSFZF8pzIJFrH3#royfS`P#N61L4$%uB3Rr>_SSeAef5>u?rmCQ}6>76lX?j6lxU z71;MOWuzks$_@C~_cUU5&*yT4<-fbLiFe#E<99kj60-g$93cx{_e%%*{K`Lfrs7j) z%n@fKHX1s`Wsbm>0lDr@CTyQ~FO#YDMUKAqM9G?kyWInx!Z;b(hn0Eo^mMz5 zl!fB)g&z(0Nkt=Md!{_obL&94`}kWmFc7Z=*VuX39ZQzK?f { * @return {Promise} */ const addFilterRow = () => { - return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {}) + const rownum = 1 + getFilterRegion().querySelectorAll(Selectors.filter.region).length; + return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {"rownumber": rownum}) .then(({html, js}) => { const newContentNodes = Templates.appendNodeContents(getFilterRegion(), html, js); @@ -157,7 +159,7 @@ export const init = participantsRegionId => { * * @param {HTMLElement} filterRow */ - const removeFilterRow = filterRow => { + const removeFilterRow = async filterRow => { // Remove the filter object. removeFilterObject(filterRow.dataset.filterType); @@ -169,19 +171,28 @@ export const init = participantsRegionId => { // Update the list of available filter types. updateFiltersOptions(); + + // Update filter fieldset legends. + const filterLegends = await getAvailableFilterLegends(); + + getFilterRegion().querySelectorAll(Selectors.filter.region).forEach((filterRow, index) => { + filterRow.querySelector('legend').innerText = filterLegends[index]; + }); + }; /** * Replace the specified filter row with a new one. * * @param {HTMLElement} filterRow + * @param {Number} rowNum The number used to label the filter fieldset legend (eg Row 1). Defaults to 1 (the first filter). * @return {Promise} */ - const replaceFilterRow = filterRow => { + const replaceFilterRow = (filterRow, rowNum = 1) => { // Remove the filter object. removeFilterObject(filterRow.dataset.filterType); - return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {}) + return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {"rownumber": rowNum}) .then(({html, js}) => { const newContentNodes = Templates.replaceNode(filterRow, html, js); @@ -302,6 +313,33 @@ export const init = participantsRegionId => { ); }; + /** + * Fetch the strings used to populate the fieldset legends for the maximum number of filters possible. + * + * @return {array} + */ + const getAvailableFilterLegends = async() => { + const maxFilters = document.querySelector(Selectors.data.typeListSelect).length - 1; + let requests = []; + + [...Array(maxFilters)].forEach((_, rowIndex) => { + requests.push({ + "key": "filterrowlegend", + "component": "core_user", + // Add 1 since rows begin at 1 (index begins at zero). + "param": rowIndex + 1 + }); + }); + + const legendStrings = await getStrings(requests) + .then(fetchedStrings => { + return fetchedStrings; + }) + .catch(Notification.exception); + + return legendStrings; + }; + // Add listeners for the main actions. filterSet.querySelector(Selectors.filterset.region).addEventListener('click', e => { if (e.target.closest(Selectors.filterset.actions.addRow)) { diff --git a/user/classes/output/participants_filter.php b/user/classes/output/participants_filter.php index 0ab5ed8f335..443c5a280e2 100644 --- a/user/classes/output/participants_filter.php +++ b/user/classes/output/participants_filter.php @@ -350,6 +350,7 @@ class participants_filter implements renderable, templatable { 'tableregionid' => $this->tableregionid, 'courseid' => $this->context->instanceid, 'filtertypes' => $this->get_filtertypes(), + 'rownumber' => 1, ]; return $data; diff --git a/user/templates/local/participantsfilter/autocomplete_selection_items.mustache b/user/templates/local/participantsfilter/autocomplete_selection_items.mustache index 9f358b6b2eb..732bb23f9ed 100644 --- a/user/templates/local/participantsfilter/autocomplete_selection_items.mustache +++ b/user/templates/local/participantsfilter/autocomplete_selection_items.mustache @@ -43,7 +43,10 @@ {{#items}} - {{label}} + {{label}} + {{/items}} {{^items}} diff --git a/user/templates/local/participantsfilter/filterrow.mustache b/user/templates/local/participantsfilter/filterrow.mustache index 9d2bdc6ddb6..2ae3c426bd9 100644 --- a/user/templates/local/participantsfilter/filterrow.mustache +++ b/user/templates/local/participantsfilter/filterrow.mustache @@ -29,37 +29,41 @@ "name": "status", "title": "Status" } - ] + ], + "rownumber": 1 } }}
-
-
- - -
+
+ {{#str}}filterrowlegend, core_user, {{rownumber}}{{/str}} +
+
+ + +
- - + + -
+
- -
-
-
{{#str}}adverbfor_andnot, core_user{{/str}}
-
{{#str}}adverbfor_or, core_user{{/str}}
-
{{#str}}adverbfor_and, core_user{{/str}}
-
+ +
+
+
{{#str}}adverbfor_andnot, core_user{{/str}}
+
{{#str}}adverbfor_or, core_user{{/str}}
+
{{#str}}adverbfor_and, core_user{{/str}}
+
+
-- 2.43.0