Merge branch 'MDL-68167-master' of git://github.com/rezaies/moodle

This commit is contained in:
Jun Pataleta 2020-10-30 13:17:02 +08:00
commit 48397d35ab
29 changed files with 131 additions and 89 deletions

View File

@ -56,7 +56,7 @@ Feature: Organize students into groups
And I should see "Student 0"
And I should see "Student 1"
And I should not see "Student 2"
And I click on "Remove \"Group 1\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "Group 1" "autocomplete_selection"
And I click on ".form-autocomplete-downarrow" "css_element" in the "Filter 1" "fieldset"
And I click on "Group 2" "list_item"
And I click on "Apply filters" "button"

View File

@ -80,6 +80,7 @@ $string['showadvanced'] = 'Show advanced';
$string['showless'] = 'Show less...';
$string['showmore'] = 'Show more...';
$string['somefieldsrequired'] = 'There are required fields in this form marked {$a}.';
$string['suggestions'] = 'Suggestions';
$string['time'] = 'Time';
$string['timeunit'] = 'Time unit';
$string['timing'] = 'Timing';

View File

@ -33,6 +33,7 @@ $string['clearfilterselection'] = 'Remove "{$a}" from filter';
$string['countparticipantsfound'] = '{$a} participants found';
$string['filterrowlegend'] = 'Filter {$a}';
$string['filtersetmatchdescription'] = 'How multiple filters should be combined';
$string['filtertype'] = 'Filter type';
$string['match'] = 'Match';
$string['matchofthefollowing'] = 'of the following:';
$string['moodlenetprofile'] = 'MoodleNet profile';

View File

@ -1,2 +1,2 @@
define ("core/custom_interaction_events",["jquery","core/key_codes"],function(a,b){var c={activate:"cie:activate",keyboardActivate:"cie:keyboardactivate",escape:"cie:escape",down:"cie:down",up:"cie:up",home:"cie:home",end:"cie:end",next:"cie:next",previous:"cie:previous",asterix:"cie:asterix",scrollLock:"cie:scrollLock",scrollTop:"cie:scrollTop",scrollBottom:"cie:scrollBottom",ctrlPageUp:"cie:ctrlPageUp",ctrlPageDown:"cie:ctrlPageDown",enter:"cie:enter",accessibleChange:"cie:accessibleChange"},d={},e=function(a,b){b=b||[];if(b.length&&-1!==b.indexOf(a)){return!0}return!1},f=function(a){return a.shiftKey||a.metaKey||a.altKey||a.ctrlKey},g=function(b,c){var e="";if(!c.hasOwnProperty("originalEvent")){e=""+b+c.type+c.timeStamp;if(!d.hasOwnProperty(e)){d[e]=!0;a(c.target).trigger(b,[{originalEvent:c}])}return}e="triggeredCustom_"+b;if(!c.originalEvent.hasOwnProperty(e)){c.originalEvent[e]=!0;a(c.target).trigger(b,[{originalEvent:c}])}},h=function(a,b,c){a.off("keydown."+b).on("keydown."+b,function(a){if(!f(a)){if(a.keyCode==c){g(b,a)}}})},i=function(a){a.off("click.cie.activate").on("click.cie.activate",function(a){g(c.activate,a)});a.off("keydown.cie.activate").on("keydown.cie.activate",function(a){if(!f(a)){if(a.keyCode==b.enter||a.keyCode==b.space){g(c.activate,a)}}})},j=function(a){a.off("keydown.cie.keyboardactivate").on("keydown.cie.keyboardactivate",function(a){if(!f(a)){if(a.keyCode==b.enter||a.keyCode==b.space){g(c.keyboardActivate,a)}}})},k=function(a){h(a,c.escape,b.escape)},l=function(a){h(a,c.down,b.arrowDown)},m=function(a){h(a,c.up,b.arrowUp)},n=function(a){h(a,c.home,b.home)},o=function(a){h(a,c.end,b.end)},p=function(d){var e="rtl"==a("html").attr("dir")?b.arrowLeft:b.arrowRight;h(d,c.next,e)},q=function(d){var e="rtl"==a("html").attr("dir")?b.arrowRight:b.arrowLeft;h(d,c.previous,e)},r=function(a){h(a,c.asterix,b.asterix)},s=function(a){a.off("scroll.cie.scrollTop").on("scroll.cie.scrollTop",function(b){var d=a.scrollTop();if(0===d){g(c.scrollTop,b)}})},t=function(a){a.off("scroll.cie.scrollBottom").on("scroll.cie.scrollBottom",function(b){var d=a.scrollTop(),e=a.innerHeight(),f=a[0].scrollHeight;if(d+e>=f){g(c.scrollBottom,b)}})},u=function(a){a.off("DOMMouseScroll.cie.DOMMouseScrollLock mousewheel.cie.mousewheelLock").on("DOMMouseScroll.cie.DOMMouseScrollLock mousewheel.cie.mousewheelLock",function(b){var d=a.scrollTop(),e=a[0].scrollHeight,f=a.height(),h="DOMMouseScroll"==b.type?-40*b.originalEvent.detail:b.originalEvent.wheelDelta,i=0<h;if(!i&&-h>e-f-d){a.scrollTop(e);b.stopPropagation();b.preventDefault();b.returnValue=!1;g(c.scrollLock,b);return!1}else if(i&&h>d){a.scrollTop(0);b.stopPropagation();b.preventDefault();b.returnValue=!1;g(c.scrollLock,b);return!1}return!0})},v=function(a){a.off("keydown.cie.ctrlpageup").on("keydown.cie.ctrlpageup",function(a){if(a.ctrlKey){if(a.keyCode==b.pageUp){g(c.ctrlPageUp,a)}}})},w=function(a){a.off("keydown.cie.ctrlpagedown").on("keydown.cie.ctrlpagedown",function(a){if(a.ctrlKey){if(a.keyCode==b.pageDown){g(c.ctrlPageDown,a)}}})},x=function(a){h(a,c.enter,b.enter)},y=function(d){var e=-1!==navigator.userAgent.indexOf("Macintosh"),f="ontouchstart"in window||"msMaxTouchPoints"in navigator&&0<navigator.msMaxTouchPoints;if(e||f){d.on("change",function(a){g(c.accessibleChange,a)})}else{d.on("focus",function(){a(this).data("initValue",this.value)});d.on("blur",function(b){var d=a(this).data("initValue");a(this).removeData("initValue");if(this.value!==d){g(c.accessibleChange,b)}});d.on("keydown",function(d){if(d.which===b.enter&&this.value!==a(this).data("initValue")){g(c.accessibleChange,d)}else if(d.which===b.escape){this.value=a(this).data("initValue")}});d.on("click",function(b){var d=a(this).data("initValue");if("undefined"!=typeof d&&d!=this.value){g(c.accessibleChange,b)}})}},z=function(){var a={};a[c.activate]=i;a[c.keyboardActivate]=j;a[c.escape]=k;a[c.down]=l;a[c.up]=m;a[c.home]=n;a[c.end]=o;a[c.next]=p;a[c.previous]=q;a[c.asterix]=r;a[c.scrollLock]=u;a[c.scrollTop]=s;a[c.scrollBottom]=t;a[c.ctrlPageUp]=v;a[c.ctrlPageDown]=w;a[c.enter]=x;a[c.accessibleChange]=y;return a};return{define:function define(b,c){b=a(b);c=c||[];if(!b.length||!c.length){return}a.each(z(),function(a,d){if(e(a,c)){d(b)}})},events:c}});
define ("core/custom_interaction_events",["jquery","core/key_codes"],function(a,b){var c={activate:"cie:activate",keyboardActivate:"cie:keyboardactivate",escape:"cie:escape",down:"cie:down",up:"cie:up",home:"cie:home",end:"cie:end",next:"cie:next",previous:"cie:previous",asterix:"cie:asterix",scrollLock:"cie:scrollLock",scrollTop:"cie:scrollTop",scrollBottom:"cie:scrollBottom",ctrlPageUp:"cie:ctrlPageUp",ctrlPageDown:"cie:ctrlPageDown",enter:"cie:enter",accessibleChange:"cie:accessibleChange"},d={},e=function(a,b){b=b||[];if(b.length&&-1!==b.indexOf(a)){return!0}return!1},f=function(a){return a.shiftKey||a.metaKey||a.altKey||a.ctrlKey},g=function(b,c){var e="";if(!c.hasOwnProperty("originalEvent")){e=""+b+c.type+c.timeStamp;if(!d.hasOwnProperty(e)){d[e]=!0;a(c.target).trigger(b,[{originalEvent:c}])}return}e="triggeredCustom_"+b;if(!c.originalEvent.hasOwnProperty(e)){c.originalEvent[e]=!0;a(c.target).trigger(b,[{originalEvent:c}])}},h=function(a,b,c){a.off("keydown."+b).on("keydown."+b,function(a){if(!f(a)){if(a.keyCode==c){g(b,a)}}})},i=function(a){a.off("click.cie.activate").on("click.cie.activate",function(a){g(c.activate,a)});a.off("keydown.cie.activate").on("keydown.cie.activate",function(a){if(!f(a)){if(a.keyCode==b.enter||a.keyCode==b.space){g(c.activate,a)}}})},j=function(a){a.off("keydown.cie.keyboardactivate").on("keydown.cie.keyboardactivate",function(a){if(!f(a)){if(a.keyCode==b.enter||a.keyCode==b.space){g(c.keyboardActivate,a)}}})},k=function(a){h(a,c.escape,b.escape)},l=function(a){h(a,c.down,b.arrowDown)},m=function(a){h(a,c.up,b.arrowUp)},n=function(a){h(a,c.home,b.home)},o=function(a){h(a,c.end,b.end)},p=function(d){var e="rtl"==a("html").attr("dir")?b.arrowLeft:b.arrowRight;h(d,c.next,e)},q=function(d){var e="rtl"==a("html").attr("dir")?b.arrowRight:b.arrowLeft;h(d,c.previous,e)},r=function(a){h(a,c.asterix,b.asterix)},s=function(a){a.off("scroll.cie.scrollTop").on("scroll.cie.scrollTop",function(b){var d=a.scrollTop();if(0===d){g(c.scrollTop,b)}})},t=function(a){a.off("scroll.cie.scrollBottom").on("scroll.cie.scrollBottom",function(b){var d=a.scrollTop(),e=a.innerHeight(),f=a[0].scrollHeight;if(d+e>=f){g(c.scrollBottom,b)}})},u=function(a){a.off("DOMMouseScroll.cie.DOMMouseScrollLock mousewheel.cie.mousewheelLock").on("DOMMouseScroll.cie.DOMMouseScrollLock mousewheel.cie.mousewheelLock",function(b){var d=a.scrollTop(),e=a[0].scrollHeight,f=a.height(),h="DOMMouseScroll"==b.type?-40*b.originalEvent.detail:b.originalEvent.wheelDelta,i=0<h;if(!i&&-h>e-f-d){a.scrollTop(e);b.stopPropagation();b.preventDefault();b.returnValue=!1;g(c.scrollLock,b);return!1}else if(i&&h>d){a.scrollTop(0);b.stopPropagation();b.preventDefault();b.returnValue=!1;g(c.scrollLock,b);return!1}return!0})},v=function(a){a.off("keydown.cie.ctrlpageup").on("keydown.cie.ctrlpageup",function(a){if(a.ctrlKey){if(a.keyCode==b.pageUp){g(c.ctrlPageUp,a)}}})},w=function(a){a.off("keydown.cie.ctrlpagedown").on("keydown.cie.ctrlpagedown",function(a){if(a.ctrlKey){if(a.keyCode==b.pageDown){g(c.ctrlPageDown,a)}}})},x=function(a){h(a,c.enter,b.enter)},y=function(d){var e=-1!==navigator.userAgent.indexOf("Macintosh"),f="ontouchstart"in window||"msMaxTouchPoints"in navigator&&0<navigator.msMaxTouchPoints;if(e||f){d.on("change",function(a){g(c.accessibleChange,a)})}else{d.on("focusin",function(b){a(b.target).data("initValue",b.target.value)});d.on("focusout",function(b){var d=a(b.target).data("initValue");a(b.target).removeData("initValue");if(b.target.value!==d){g(c.accessibleChange,b)}});d.on("keydown",function(d){if(d.which===b.enter&&d.target.value!==a(d.target).data("initValue")){g(c.accessibleChange,d)}else if(d.which===b.escape){d.target.value=a(d.target).data("initValue")}});d.on("click",function(b){var d=a(b.target).data("initValue");if("undefined"!=typeof d&&d!=b.target.value){g(c.accessibleChange,b)}})}},z=function(){var a={};a[c.activate]=i;a[c.keyboardActivate]=j;a[c.escape]=k;a[c.down]=l;a[c.up]=m;a[c.home]=n;a[c.end]=o;a[c.next]=p;a[c.previous]=q;a[c.asterix]=r;a[c.scrollLock]=u;a[c.scrollTop]=s;a[c.scrollBottom]=t;a[c.ctrlPageUp]=v;a[c.ctrlPageDown]=w;a[c.enter]=x;a[c.accessibleChange]=y;return a};return{define:function define(b,c){b=a(b);c=c||[];if(!b.length||!c.length){return}a.each(z(),function(a,d){if(e(a,c)){d(b)}})},events:c}});
//# sourceMappingURL=custom_interaction_events.min.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -431,27 +431,27 @@ define(['jquery', 'core/key_codes'], function($, keyCodes) {
triggerEvent(events.accessibleChange, e);
});
} else {
element.on('focus', function() {
$(this).data('initValue', this.value);
element.on('focusin', function(e) {
$(e.target).data('initValue', e.target.value);
});
element.on('blur', function(e) {
var initValue = $(this).data('initValue');
$(this).removeData('initValue');
if (this.value !== initValue) {
element.on('focusout', function(e) {
var initValue = $(e.target).data('initValue');
$(e.target).removeData('initValue');
if (e.target.value !== initValue) {
triggerEvent(events.accessibleChange, e);
}
});
element.on('keydown', function(e) {
if ((e.which === keyCodes.enter) && this.value !== $(this).data('initValue')) {
if ((e.which === keyCodes.enter) && e.target.value !== $(e.target).data('initValue')) {
triggerEvent(events.accessibleChange, e);
} else if (e.which === keyCodes.escape) {
this.value = $(this).data('initValue');
e.target.value = $(e.target).data('initValue');
}
});
element.on('click', function(e) {
var initValue = $(this).data('initValue');
var initValue = $(e.target).data('initValue');
// Some browsers trigger onclick before onblur, therefore it is possible that initValue is undefined.
if (typeof initValue !== 'undefined' && initValue != this.value) {
if (typeof initValue !== 'undefined' && initValue != e.target.value) {
triggerEvent(events.accessibleChange, e);
}
});

View File

@ -336,8 +336,12 @@ function($, log, str, templates, notification, LoadingIcon, Aria) {
var inputElement = $(document.getElementById(state.inputId));
var suggestionsElement = $(document.getElementById(state.suggestionsId));
// Announce the list of suggestions was closed, and read the current list of selections.
inputElement.attr('aria-expanded', false).attr('aria-activedescendant', state.selectionId);
if (inputElement.attr('aria-expanded') === "true") {
// Announce the list of suggestions was closed.
inputElement.attr('aria-expanded', false);
}
// Read the current list of selections.
inputElement.attr('aria-activedescendant', state.selectionId);
// Hide the suggestions list (from screen readers too).
Aria.hide(suggestionsElement.get());
@ -781,7 +785,7 @@ function($, log, str, templates, notification, LoadingIcon, Aria) {
var suggestionsElement = $(document.getElementById(state.suggestionsId));
// Remove any click handler first.
suggestionsElement.parent().prop("onclick", null).off("click");
suggestionsElement.parent().on('click', '[role=option]', function(e) {
suggestionsElement.parent().on('click', `#${state.suggestionsId} [role=option]`, function(e) {
var pendingPromise = addPendingJSPromise('form-autocomplete-parent');
// Handle clicks on suggestions.
var element = $(e.currentTarget).closest('[role=option]');
@ -802,23 +806,20 @@ function($, log, str, templates, notification, LoadingIcon, Aria) {
});
var selectionElement = $(document.getElementById(state.selectionId));
// Handle clicks on the selected items (will unselect an item).
selectionElement.on('click', '[role=listitem]', function(e) {
selectionElement.on('click', '[role=option]', function(e) {
var pendingPromise = addPendingJSPromise('form-autocomplete-clicks');
// Remove it from the selection.
pendingPromise.resolve(deselectItem(options, state, $(e.currentTarget), originalSelect));
});
// Remove the highlight of items when user tabs out the tag list.
selectionElement.on('blur', function(e) {
e.preventDefault();
$(this).children().attr('data-active-selection', false).attr('id', '');
});
// When tag list is focused, highlight the first item.
selectionElement.on('focus', function(e) {
e.preventDefault();
var element = $(this).children('[data-active-selection=true]');
if (element && element.length === 0) {
activateNextSelection(state);
// When listbox is focused, focus on the first option if there is no focused option.
selectionElement.on('focus', function() {
// Find the list of selections.
var selectionsElement = $(document.getElementById(state.selectionId));
// Find the active one.
var element = selectionsElement.children('[data-active-selection=true]');
if (!element.length) {
return activateSelection(0, state);
}
});
// Keyboard navigation for the selection list.

View File

@ -226,7 +226,7 @@ XPATH
/ancestor::*[contains(concat(' ', @class, ' '), ' fitem ')]
XPATH
, 'autocomplete_selection' => <<<XPATH
.//div[contains(concat(' ', normalize-space(@class), ' '), concat(' ', 'form-autocomplete-selection', ' '))]/span[@role='listitem'][contains(normalize-space(.), %locator%)]
.//div[contains(concat(' ', normalize-space(@class), ' '), concat(' ', 'form-autocomplete-selection', ' '))]/span[@role='option'][contains(normalize-space(.), %locator%)]
XPATH
, 'autocomplete_suggestions' => <<<XPATH
.//ul[contains(concat(' ', normalize-space(@class), ' '), concat(' ', 'form-autocomplete-suggestions', ' '))]/li[@role='option'][contains(normalize-space(.), %locator%)]

View File

@ -37,7 +37,14 @@
{ "label": "Another item label with <strong>tags</strong>", "value": "4" }
], "noSelectionString": "No selection" }
}}
<div class="form-autocomplete-selection w-100 {{#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>
<span class="sr-only" id="{{selectionId}}-label">{{#str}}selecteditems, form{{/str}}</span>
<div{{!
}} class="form-autocomplete-selection w-100 {{#multiple}}form-autocomplete-multiple{{/multiple}}"{{!
}} id="{{selectionId}}"{{!
}} aria-labelledby="{{selectionId}}-label"{{!
}} role="listbox"{{!
}} aria-atomic="true"{{!
}} tabindex="0"{{!
}} {{#multiple}}aria-multiselectable="true"{{/multiple}}>
{{> core/form_autocomplete_selection_items }}
</div>

View File

@ -38,7 +38,7 @@
], "noSelectionString": "No selection" }
}}
{{#items}}
<span role="listitem" data-value="{{value}}" aria-selected="true" class="badge badge-info mb-3 mr-1" style="font-size: 100%">
<span role="option" data-value="{{value}}" aria-selected="true" class="badge badge-info mb-3 mr-1" style="font-size: 100%">
<span aria-hidden="true">× </span>{{{label}}}
</span>
{{/items}}

View File

@ -35,7 +35,7 @@
{ "label": "Another item label with <strong>tags</strong>", "value": "4" }
]}
}}
<ul class="form-autocomplete-suggestions" id="{{suggestionsId}}" role="listbox" aria-hidden="true" tabindex="-1">
<ul class="form-autocomplete-suggestions" id="{{suggestionsId}}" role="listbox" aria-label="{{#str}}suggestions, form{{/str}}" aria-hidden="true" tabindex="-1">
{{#options}}
<li role="option" data-value="{{value}}">{{{label}}}</li>
{{/options}}

View File

@ -111,7 +111,7 @@ Feature: Mapping courses in a feedback
And I follow "Course feedback"
And I navigate to "Analysis" in current page administration
And I should see "All courses" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=listitem]" "css_element"
And I should see "All courses" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=option]" "css_element"
And I show chart data for the "multichoicerated" feedback
And I should see "1 (33.33 %)" in the "option a" "table_row"
And I should see "1 (33.33 %)" in the "option b" "table_row"
@ -123,7 +123,7 @@ Feature: Mapping courses in a feedback
And I click on "Back" "link" in the "region-main" "region"
And I set the field "Filter by course" to "Course 1"
And I press "Filter"
And I should see "Course 1" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=listitem]" "css_element"
And I should see "Course 1" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=option]" "css_element"
And I show chart data for the "multichoicerated" feedback
And I should see "0" in the "option a" "table_row"
And I should see "1 (50.00 %)" in the "option b" "table_row"
@ -193,7 +193,7 @@ Feature: Mapping courses in a feedback
And I am on site homepage
And I follow "Course feedback"
And I navigate to "Analysis" in current page administration
And I should see "All courses" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=listitem]" "css_element"
And I should see "All courses" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=option]" "css_element"
And I show chart data for the "multichoicerated" feedback
And I should see "0" in the "option a" "table_row"
And I should see "1 (33.33 %)" in the "option b" "table_row"

View File

@ -131,6 +131,7 @@ Feature: The forum search allows users to perform advanced searches for forum po
And I should see "Advanced search"
And I set the field "Is tagged with" to "SearchedTag"
And I click on "[data-value='SearchedTag']" "css_element"
And I press key "27" in the field "Is tagged with"
When I press "Search forums"
Then I should see "My subject"
And I should not see "Your subjective"

View File

@ -169,7 +169,8 @@ input[type="image"],
a.dropdown-toggle,
.modal-dialog[tabindex="0"],
.moodle-dialogue-base .closebutton,
button.close {
button.close,
.form-autocomplete-selection {
&.focus,
&:focus {
outline: 0;
@ -180,6 +181,12 @@ button.close {
}
}
// Accessible focus styling for autocomplete elements.
.form-autocomplete-suggestions li[aria-selected=true] {
outline: 0;
box-shadow: $input-btn-focus-box-shadow;
}
// Safari does not allow custom styling of checkboxes.
.safari {
input[type="checkbox"],

View File

@ -276,7 +276,7 @@ fieldset.coursesearchbox label {
min-height: 2 * $input-padding-y-sm + 2 * $font-size-base;
}
.form-autocomplete-selection [role=listitem] {
.form-autocomplete-selection [role=option] {
cursor: pointer;
white-space: inherit;
word-break: break-word;
@ -291,8 +291,8 @@ fieldset.coursesearchbox label {
min-width: 206px;
max-height: 20em;
overflow: auto;
padding: 0;
margin: 2px 0 0 0;
margin: $dropdown-spacer 0 0;
padding: $dropdown-padding-y 0;
z-index: 1;
}
@ -308,6 +308,9 @@ fieldset.coursesearchbox label {
background-color: $dropdown-link-active-bg;
color: $dropdown-link-active-color;
}
&::before {
content: "\200B";
}
}
.form-autocomplete-downarrow {
@ -323,10 +326,6 @@ fieldset.coursesearchbox label {
}
}
.form-autocomplete-selection:focus {
outline: 0;
box-shadow: $input-btn-focus-box-shadow;
}
/** Undo some bootstrap things */
.form-autocomplete-selection + input.form-control {
width: auto;

View File

@ -9786,7 +9786,9 @@ a.dropdown-toggle:focus,
.moodle-dialogue-base .closebutton.focus,
.moodle-dialogue-base .closebutton:focus,
button.close.focus,
button.close:focus {
button.close:focus,
.form-autocomplete-selection.focus,
.form-autocomplete-selection:focus {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
@ -9804,9 +9806,14 @@ input[type="image"]:focus:hover,
a.dropdown-toggle:focus:hover,
.modal-dialog[tabindex="0"]:focus:hover,
.moodle-dialogue-base .closebutton:focus:hover,
button.close:focus:hover {
button.close:focus:hover,
.form-autocomplete-selection:focus:hover {
text-decoration: none; }
.form-autocomplete-suggestions li[aria-selected=true] {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
.safari input[type="checkbox"].focus, .safari input[type="checkbox"]:focus,
.safari input[type="radio"].focus,
.safari input[type="radio"]:focus {
@ -16522,7 +16529,7 @@ fieldset.coursesearchbox label {
margin: 0.25rem;
min-height: 2.375rem; }
.form-autocomplete-selection [role=listitem] {
.form-autocomplete-selection [role=option] {
cursor: pointer;
white-space: inherit;
word-break: break-word;
@ -16536,8 +16543,8 @@ fieldset.coursesearchbox label {
min-width: 206px;
max-height: 20em;
overflow: auto;
padding: 0;
margin: 2px 0 0 0;
margin: 0.125rem 0 0;
padding: 0.5rem 0;
z-index: 1; }
.form-autocomplete-suggestions li {
@ -16549,6 +16556,8 @@ fieldset.coursesearchbox label {
.form-autocomplete-suggestions li:hover, .form-autocomplete-suggestions li:focus, .form-autocomplete-suggestions li[aria-selected="true"] {
background-color: #0f6fc5;
color: #fff; }
.form-autocomplete-suggestions li::before {
content: "\200B"; }
.form-autocomplete-downarrow {
color: #212529;
@ -16561,10 +16570,6 @@ fieldset.coursesearchbox label {
left: 0;
background-color: #fff; }
.form-autocomplete-selection:focus {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
/** Undo some bootstrap things */
.form-autocomplete-selection + input.form-control {
width: auto;

View File

@ -9990,7 +9990,9 @@ a.dropdown-toggle:focus,
.moodle-dialogue-base .closebutton.focus,
.moodle-dialogue-base .closebutton:focus,
button.close.focus,
button.close:focus {
button.close:focus,
.form-autocomplete-selection.focus,
.form-autocomplete-selection:focus {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
@ -10008,9 +10010,14 @@ input[type="image"]:focus:hover,
a.dropdown-toggle:focus:hover,
.modal-dialog[tabindex="0"]:focus:hover,
.moodle-dialogue-base .closebutton:focus:hover,
button.close:focus:hover {
button.close:focus:hover,
.form-autocomplete-selection:focus:hover {
text-decoration: none; }
.form-autocomplete-suggestions li[aria-selected=true] {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
.safari input[type="checkbox"].focus, .safari input[type="checkbox"]:focus,
.safari input[type="radio"].focus,
.safari input[type="radio"]:focus {
@ -16748,7 +16755,7 @@ fieldset.coursesearchbox label {
margin: 0.25rem;
min-height: 2.375rem; }
.form-autocomplete-selection [role=listitem] {
.form-autocomplete-selection [role=option] {
cursor: pointer;
white-space: inherit;
word-break: break-word;
@ -16762,8 +16769,8 @@ fieldset.coursesearchbox label {
min-width: 206px;
max-height: 20em;
overflow: auto;
padding: 0;
margin: 2px 0 0 0;
margin: 0.125rem 0 0;
padding: 0.5rem 0;
z-index: 1; }
.form-autocomplete-suggestions li {
@ -16775,6 +16782,8 @@ fieldset.coursesearchbox label {
.form-autocomplete-suggestions li:hover, .form-autocomplete-suggestions li:focus, .form-autocomplete-suggestions li[aria-selected="true"] {
background-color: #0f6fc5;
color: #fff; }
.form-autocomplete-suggestions li::before {
content: "\200B"; }
.form-autocomplete-downarrow {
color: #212529;
@ -16787,10 +16796,6 @@ fieldset.coursesearchbox label {
left: 0;
background-color: #fff; }
.form-autocomplete-selection:focus {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
/** Undo some bootstrap things */
.form-autocomplete-selection + input.form-control {
width: auto;

View File

@ -1,2 +1,2 @@
define ("core_user/local/participantsfilter/filter",["exports","core/form-autocomplete","./selectors","core/str"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=e(b);c=e(c);function e(a){return a&&a.__esModule?a:{default:a}}function f(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function g(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var i=a.apply(b,c);function g(a){f(i,d,e,g,h,"next",a)}function h(a){f(i,d,e,g,h,"throw",a)}g(void 0)})}}function h(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function i(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function j(a,b,c){if(b)i(a.prototype,b);if(c)i(a,c);return a}var k=function(a){return a.querySelectorAll(":checked")},l=function(){function a(b,c,d){h(this,a);this.filterType=b;this.rootNode=c;this.addValueSelector(d)}j(a,[{key:"tearDown",value:function tearDown(){}},{key:"addValueSelector",value:function(){var a=g(regeneratorRuntime.mark(function a(){var c=this,d,e,f,g=arguments;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d=0<g.length&&g[0]!==void 0?g[0]:[];e=this.getFilterValueNode();e.innerHTML=this.getSourceDataForFilter().outerHTML;f=e.querySelector("select");d.forEach(function(a){var b=f.querySelector("option[value=\"".concat(a,"\"]"));if(b){b.selected=!0}else if(!c.showSuggestions){b=document.createElement("option");b.value=a;b.innerHTML=a;b.selected=!0;f.append(b)}});a.t0=b.default;a.t1=f;a.t2="1"==f.dataset.allowCustom;a.next=10;return this.placeholder;case 10:a.t3=a.sent;a.t4=this.showSuggestions;a.t5=!f.multiple;a.t6={items:"core_user/local/participantsfilter/autocomplete_selection_items",layout:"core_user/local/participantsfilter/autocomplete_layout",selection:"core_user/local/participantsfilter/autocomplete_selection"};a.t0.enhance.call(a.t0,a.t1,a.t2,null,a.t3,!1,a.t4,null,a.t5,a.t6);case 15:case"end":return a.stop();}}},a,this)}));return function addValueSelector(){return a.apply(this,arguments)}}()},{key:"getSourceDataForFilter",value:function getSourceDataForFilter(){var a=this.rootNode.querySelector(c.default.filterset.regions.datasource);return a.querySelector(c.default.data.fields.byName(this.filterType))}},{key:"getFilterValueNode",value:function getFilterValueNode(){return this.filterRoot.querySelector(c.default.filter.regions.values)}},{key:"placeholder",get:function get(){return(0,d.get_string)("placeholdertypeorselect","core_user")}},{key:"showSuggestions",get:function get(){return!0}},{key:"filterRoot",get:function get(){return this.rootNode.querySelector(c.default.filter.byName(this.filterType))}},{key:"name",get:function get(){return this.filterType}},{key:"jointype",get:function get(){return parseInt(this.filterRoot.querySelector(c.default.filter.fields.join).value,10)}},{key:"rawValues",get:function get(){var a=this.getFilterValueNode(),b=a.querySelector("select");return Object.values(k(b)).map(function(a){return a.value})}},{key:"values",get:function get(){return this.rawValues.map(function(a){return parseInt(a,10)})}},{key:"filterValue",get:function get(){return{name:this.name,jointype:this.jointype,values:this.values}}}]);return a}();a.default=l;return a.default});
define ("core_user/local/participantsfilter/filter",["exports","core/form-autocomplete","./selectors","core/str"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=e(b);c=e(c);function e(a){return a&&a.__esModule?a:{default:a}}function f(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function g(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var i=a.apply(b,c);function g(a){f(i,d,e,g,h,"next",a)}function h(a){f(i,d,e,g,h,"throw",a)}g(void 0)})}}function h(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function i(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function j(a,b,c){if(b)i(a.prototype,b);if(c)i(a,c);return a}var k=function(a){return a.querySelectorAll(":checked")},l=function(){function a(b,c,d){h(this,a);this.filterType=b;this.rootNode=c;this.addValueSelector(d)}j(a,[{key:"tearDown",value:function tearDown(){}},{key:"addValueSelector",value:function(){var a=g(regeneratorRuntime.mark(function a(){var c=this,d,e,f,g,h=arguments;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d=0<h.length&&h[0]!==void 0?h[0]:[];e=this.getFilterValueNode();e.innerHTML=this.getSourceDataForFilter().outerHTML;f=e.querySelector("select");f.id="filter-value-"+f.getAttribute("data-field-name");g=document.createElement("label");g.setAttribute("for",f.id);g.classList.add("sr-only");g.innerText=f.getAttribute("data-field-title");e.appendChild(g);d.forEach(function(a){var b=f.querySelector("option[value=\"".concat(a,"\"]"));if(b){b.selected=!0}else if(!c.showSuggestions){b=document.createElement("option");b.value=a;b.innerHTML=a;b.selected=!0;f.append(b)}});a.t0=b.default;a.t1=f;a.t2="1"==f.dataset.allowCustom;a.next=16;return this.placeholder;case 16:a.t3=a.sent;a.t4=this.showSuggestions;a.t5=!f.multiple;a.t6={items:"core_user/local/participantsfilter/autocomplete_selection_items",layout:"core_user/local/participantsfilter/autocomplete_layout",selection:"core_user/local/participantsfilter/autocomplete_selection"};a.t0.enhance.call(a.t0,a.t1,a.t2,null,a.t3,!1,a.t4,null,a.t5,a.t6);case 21:case"end":return a.stop();}}},a,this)}));return function addValueSelector(){return a.apply(this,arguments)}}()},{key:"getSourceDataForFilter",value:function getSourceDataForFilter(){var a=this.rootNode.querySelector(c.default.filterset.regions.datasource);return a.querySelector(c.default.data.fields.byName(this.filterType))}},{key:"getFilterValueNode",value:function getFilterValueNode(){return this.filterRoot.querySelector(c.default.filter.regions.values)}},{key:"placeholder",get:function get(){return(0,d.get_string)("placeholdertypeorselect","core_user")}},{key:"showSuggestions",get:function get(){return!0}},{key:"filterRoot",get:function get(){return this.rootNode.querySelector(c.default.filter.byName(this.filterType))}},{key:"name",get:function get(){return this.filterType}},{key:"jointype",get:function get(){return parseInt(this.filterRoot.querySelector(c.default.filter.fields.join).value,10)}},{key:"rawValues",get:function get(){var a=this.getFilterValueNode(),b=a.querySelector("select");return Object.values(k(b)).map(function(a){return a.value})}},{key:"values",get:function get(){return this.rawValues.map(function(a){return parseInt(a,10)})}},{key:"filterValue",get:function get(){return{name:this.name,jointype:this.jointype,values:this.values}}}]);return a}();a.default=l;return a.default});
//# sourceMappingURL=filter.min.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -91,6 +91,18 @@ export default class {
const dataSource = filterValueNode.querySelector('select');
// Set an ID for this filter value element.
dataSource.id = 'filter-value-' + dataSource.getAttribute('data-field-name');
// Create a hidden label for the filter value.
const filterValueLabel = document.createElement('label');
filterValueLabel.setAttribute('for', dataSource.id);
filterValueLabel.classList.add('sr-only');
filterValueLabel.innerText = dataSource.getAttribute('data-field-title');
// Append this label to the filter value container.
filterValueNode.appendChild(filterValueLabel);
// If there are any initial values then attempt to apply them.
initialValues.forEach(filterValue => {
let selectedOption = dataSource.querySelector(`option[value="${filterValue}"]`);

View File

@ -30,6 +30,8 @@ import Notification from 'core/notification';
import Pending from 'core/pending';
import Selectors from './local/participantsfilter/selectors';
import Templates from 'core/templates';
import CustomEvents from 'core/custom_interaction_events';
import jQuery from 'jquery';
/**
* Initialise the participants filter on the element with the given id.
@ -475,7 +477,9 @@ export const init = participantsRegionId => {
});
// Add listeners for the filter type selection.
filterSet.querySelector(Selectors.filterset.regions.filterlist).addEventListener('change', e => {
let filterRegion = jQuery(getFilterRegion());
CustomEvents.define(filterRegion, [CustomEvents.events.accessibleChange]);
filterRegion.on(CustomEvents.events.accessibleChange, e => {
const typeField = e.target.closest(Selectors.filter.fields.type);
if (typeField && typeField.value) {
const filter = e.target.closest(Selectors.filter.region);

View File

@ -37,13 +37,15 @@
{ "label": "Another item label with <strong>tags</strong>", "value": "4" }
], "noSelectionString": "No selection" }
}}
<span class="sr-only" id="{{selectionId}}-label">{{#str}}selecteditems, form{{/str}}</span>
<div{{!
}} class="d-inline-block mb-0{{#multiple}} form-autocomplete-multiple h5{{/multiple}}"{{!
}} class="form-autocomplete-selection d-inline-block my-0{{#multiple}} form-autocomplete-multiple h5{{/multiple}}"{{!
}} id="{{selectionId}}"{{!
}} role="list"{{!
}} aria-labelledby="{{selectionId}}-label"{{!
}} role="listbox"{{!
}} aria-atomic="true"{{!
}}{{#multiple}} tabindex="0" {{/multiple}}{{!
}} tabindex="0"{{!
}}{{#multiple}} aria-multiselectable="true"{{/multiple}}{{!
}}>
<span class="accesshide">{{#str}}selecteditems, form{{/str}}</span>
{{> core/form_autocomplete_selection_items }}
</div>

View File

@ -41,12 +41,9 @@
}
}}
{{#items}}
<span role="listitem" data-value="{{value}}" aria-selected="true"
class="badge badge-secondary clickable text-wrap text-break line-height-4 mr-2 my-1">
{{label}}
<button class="btn btn-link text-reset p-0" aria-label='{{#str}}clearfilterselection, core_user, {{label}}{{/str}}'>
<i class="icon fa fa-times pl-2 mr-0"></i>
</button>
<span role="option" data-value="{{value}}" aria-selected="true"
class="badge badge-secondary clickable text-wrap text-break line-height-4 m-1">
{{label}}<i class="icon fa fa-times pl-2 mr-0"></i>
</span>
{{/items}}
{{^items}}

View File

@ -46,7 +46,7 @@
</select>
</div>
<label class="sr-only pt-2" for="core_user-local-participantsfilter-filterrow-filtertype-{{uniqid}}">filtertype</label>
<label class="sr-only pt-2" for="core_user-local-participantsfilter-filterrow-filtertype-{{uniqid}}">{{#str}}filtertype, core_user{{/str}}</label>
<select class="custom-select mb-1 mb-md-0 mr-md-2" data-filterfield="type" id="core_user-local-participantsfilter-filterrow-filtertype-{{uniqid}}">
<option value="">{{#str}}selectfiltertype, core_user{{/str}}</option>
{{#filtertypes}}

View File

@ -290,7 +290,7 @@ Feature: Course participants can be filtered
And I should not see "Student 2" in the "participants" "table"
And I should not see "Student 4" in the "participants" "table"
# Change the active status filter to inactive.
And I click on "Remove \"Active\" from filter" "button" in the "Filter 2" "fieldset"
And I click on "Active" "autocomplete_selection"
And I click on ".form-autocomplete-downarrow" "css_element" in the "Filter 2" "fieldset"
And I click on "Inactive" "list_item"
And I click on "Apply filters" "button"
@ -540,7 +540,7 @@ Feature: Course participants can be filtered
And I should not see "Student 2" in the "participants" "table"
And I should not see "Teacher 1" in the "participants" "table"
# Search by idnumber (only).
And I click on "Remove \"student1@example.com\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "student1@example.com" "autocomplete_selection"
And I set the field "Type..." to "SID"
And I press key "13" in the field "Type..."
And I click on "Apply filters" "button"
@ -550,7 +550,7 @@ Feature: Course participants can be filtered
And I should see "Student 4" in the "participants" "table"
And I should not see "Teacher 1" in the "participants" "table"
# Search by city (only).
And I click on "Remove \"SID\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "SID" "autocomplete_selection"
And I set the field "Type..." to "SCITY"
And I press key "13" in the field "Type..."
And I click on "Apply filters" "button"
@ -560,13 +560,13 @@ Feature: Course participants can be filtered
And I should see "Student 4" in the "participants" "table"
And I should not see "Teacher 1" in the "participants" "table"
# Search by country text (only) - should not match.
And I click on "Remove \"SCITY\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "SCITY" "autocomplete_selection"
And I set the field "Type..." to "GB"
And I press key "13" in the field "Type..."
And I click on "Apply filters" "button"
And I should see "Nothing to display"
# Check no match.
And I click on "Remove \"GB\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "GB" "autocomplete_selection"
And I set the field "Type..." to "NOTHING"
And I press key "13" in the field "Type..."
And I click on "Apply filters" "button"
@ -594,25 +594,25 @@ Feature: Course participants can be filtered
And I should not see "Student 4" in the "participants" "table"
And I should see "Teacher 1" in the "participants" "table"
# Search for other fields - should only see own results.
And I click on "Remove \"@example.\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "@example." "autocomplete_selection"
And I set the field "Type..." to "SID"
And I press key "13" in the field "Type..."
And I click on "Apply filters" "button"
And I should see "Nothing to display"
And I click on "Remove \"SID\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "SID" "autocomplete_selection"
And I set the field "Type..." to "TID"
And I press key "13" in the field "Type..."
And I click on "Apply filters" "button"
And I should see "Teacher 1" in the "participants" "table"
And I should not see "Student 1" in the "participants" "table"
And I click on "Remove \"TID\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "TID" "autocomplete_selection"
And I set the field "Type..." to "CITY"
And I press key "13" in the field "Type..."
And I click on "Apply filters" "button"
And I should see "Teacher 1" in the "participants" "table"
And I should not see "Student 1" in the "participants" "table"
# Check no match.
And I click on "Remove \"CITY\" from filter" "button" in the "Filter 1" "fieldset"
And I click on "CITY" "autocomplete_selection"
And I set the field "Type..." to "NOTHING"
And I press key "13" in the field "Type..."
And I click on "Apply filters" "button"