aboutsummaryrefslogtreecommitdiff
path: root/resources/assets/javascripts
diff options
context:
space:
mode:
authorRasmus Fuhse <fuhse@data-quest.de>2024-05-28 12:58:57 +0000
committerRasmus Fuhse <fuhse@data-quest.de>2024-05-28 12:58:57 +0000
commite9806e73f7d91f0810a298bc6c9139e6da138575 (patch)
treedea1ecaa88f35339ac8513e71ec09ab18816dcfe /resources/assets/javascripts
parent334a223e13db9110f255b4e5f56de4666aa8db49 (diff)
Resolve "Barrierefreiheit: Globale Suche nicht barrierefrei nutzbar"
Closes #4072 Merge request studip/studip!2918
Diffstat (limited to 'resources/assets/javascripts')
-rw-r--r--resources/assets/javascripts/bootstrap/global_search.js45
-rw-r--r--resources/assets/javascripts/lib/global_search.js14
2 files changed, 53 insertions, 6 deletions
diff --git a/resources/assets/javascripts/bootstrap/global_search.js b/resources/assets/javascripts/bootstrap/global_search.js
index 4d0738e..a85f2f0 100644
--- a/resources/assets/javascripts/bootstrap/global_search.js
+++ b/resources/assets/javascripts/bootstrap/global_search.js
@@ -36,6 +36,51 @@ STUDIP.domReady(() => {
return false;
}
});
+ $('#globalsearch-input').on('keypress', function(e) {
+ if (e.which === 13) {
+ STUDIP.GlobalSearch.doSearch();
+ return false;
+ }
+ });
+ $('#globalsearch-searchbar').on('keydown', function(e) {
+ if (e.originalEvent.code === 'ArrowDown') {
+ if ($('#globalsearch-list [role=listitem]:focus').length === 0) {
+ $('#globalsearch-list [role=listitem]:visible').first().focus();
+ } else {
+ let n = $('#globalsearch-list [role=listitem]:focus').next();
+ if (n.length > 0 && n.is('[role=listitem]:visible')) {
+ n.focus();
+ } else {
+ n = $('#globalsearch-list [role=listitem]:focus').parent().next().find('[role=listitem]:visible').first();
+ if (n.length > 0) {
+ n.focus();
+ } else {
+ $('#globalsearch-list [role=listitem]:visible').first().focus();
+ }
+ }
+ }
+ return false;
+ }
+ if (e.originalEvent.code === 'ArrowUp') {
+ if ($('#globalsearch-list [role=listitem]:focus').length === 0) {
+ $('#globalsearch-list [role=listitem]:visible').last().focus();
+ } else {
+ let n = $('#globalsearch-list [role=listitem]:focus').prev();
+ if (n.length > 0 && n.is('[role=listitem]:visible')) {
+ n.focus();
+ } else {
+ n = $('#globalsearch-list [role=listitem]:focus').parent().prev().find('[role=listitem]:visible').last();
+ if (n.length > 0) {
+ n.focus();
+ } else {
+ $('#globalsearch-list [role=listitem]:visible').last().focus();
+ }
+ }
+ }
+ return false;
+ }
+ });
+
// Close search on click on page.
$('#navigation-level-1, #current-page-structure, #main-footer').on('click', function() {
diff --git a/resources/assets/javascripts/lib/global_search.js b/resources/assets/javascripts/lib/global_search.js
index 05a53aa..394b7e3 100644
--- a/resources/assets/javascripts/lib/global_search.js
+++ b/resources/assets/javascripts/lib/global_search.js
@@ -9,6 +9,7 @@ const GlobalSearch = {
*/
toggleSearchBar: function(visible, cleanup) {
$('#globalsearch-searchbar').toggleClass('is-visible', visible);
+ $('#globalsearch-input').attr('aria-expanded', visible ? 'true' : 'false');
$('#globalsearch-input').toggleClass('hidden-small-down', !visible);
$('#globalsearch-icon').toggleClass('hidden-small-down', visible);
$('#globalsearch-clear').toggleClass('hidden-small-down', !visible);
@@ -70,7 +71,7 @@ const GlobalSearch = {
// Iterate over each result category.
$.each(json, function(name, value) {
// Create an <article> for category.
- var category = $(`<article id="globalsearch-${name}">`),
+ var category = $(`<article id="globalsearch-${name}" role="list">`),
header = $('<header>').appendTo(category),
counter = 0;
@@ -96,7 +97,7 @@ const GlobalSearch = {
// Process results and create corresponding entries.
$.each(value.content, function(index, result) {
// Create single result entry.
- var single = $('<section>'),
+ var single = $(`<a href="${result.url}" role="listitem" ${dataDialog}>`),
data = $('<div class="globalsearch-result-data">'),
details = $('<div class="globalsearch-result-details">');
@@ -107,17 +108,17 @@ const GlobalSearch = {
// Which result types should be opened via dialog?
const openInDialog = ['GlobalSearchFiles', 'GlobalSearchMessages'];
var dataDialog = (openInDialog.indexOf(name) >= 0 ? dataDialog = 'data-dialog' : dataDialog = '');
- var link = $(`<a href="${result.url}" ${dataDialog}>`).appendTo(single);
+ //var link = $(`<a href="${result.url}" ${dataDialog}>`).appendTo(single);
// Optional image...
if (result.img !== null) {
$(`<img src="${result.img}" alt="">`)
.wrap('<div class="globalsearch-result-img">')
.parent() // Element is now the wrapper
- .appendTo(link);
+ .appendTo(single);
}
- link.append(data);
+ single.append(data);
// Name/title
$('<div class="globalsearch-result-title">')
@@ -144,7 +145,7 @@ const GlobalSearch = {
if (result.date !== null) {
$('<div class="globalsearch-result-time">')
.html(result.date)
- .appendTo(link);
+ .appendTo(single);
}
// "Expand" attribute for further, result-related search
@@ -178,6 +179,7 @@ const GlobalSearch = {
GlobalSearch.lastSearch = null;
$('#globalsearch-searchbar').removeClass('is-visible has-value');
+ $('#globalsearch-input').attr('aria-expanded', 'false');
$('#globalsearch-input').val('');
$('#globalsearch-results').html('');
$('#globalsearch-input').focus();