accessibility: Manage keyboard focus on help modal dialog (LMS-581)
Modal dialogs should manage keyboard focus, ensuring that users can't tab out of the modal dialog and back into the page itself (effectively moving “behind” the dimmed modal). On the last focusable element of the dialog, return focus back to the first focusable element. Also move the close button to the start of the dialog's section, making it the first focusable URL, to ensure focus matches the visual representation of the dialog.
This commit is contained in:
@@ -14,6 +14,9 @@
|
||||
|
||||
<section id="help-modal" class="modal" aria-hidden="true">
|
||||
<div class="inner-wrapper" id="help_wrapper">
|
||||
## TODO: find a way to refactor this
|
||||
<a href="#" role="button" class="close-modal" tabindex="0" title="${_('Close Modal')}">✕</a>
|
||||
|
||||
<header>
|
||||
<h2>${_('{span_start}{platform_name}{span_end} Help').format(span_start='<span class="edx">', span_end='</span>', platform_name=settings.PLATFORM_NAME)}</h2>
|
||||
<hr>
|
||||
@@ -47,12 +50,11 @@ discussion_link = get_discussion_link(course) if course else None
|
||||
<a href="#" id="feedback_link_suggestion">${_('Make a suggestion')}</a>
|
||||
<a href="#" id="feedback_link_question">${_('Ask a question')}</a>
|
||||
</div>
|
||||
|
||||
## TODO: find a way to refactor this
|
||||
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">✕</a>
|
||||
</div>
|
||||
|
||||
<div class="inner-wrapper" id="feedback_form_wrapper">
|
||||
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">✕</a>
|
||||
|
||||
<header></header>
|
||||
|
||||
<form id="feedback_form" class="feedback_form" method="post" data-remote="true" action="/submit_feedback">
|
||||
@@ -73,14 +75,14 @@ discussion_link = get_discussion_link(course) if course else None
|
||||
<input name="course_id" type="hidden" value="${course.id | h}">
|
||||
% endif
|
||||
<div class="submit">
|
||||
<input name="submit" type="submit" value="Submit">
|
||||
<input name="submit" type="submit" value="Submit" id="feedback_submit">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">✕</a>
|
||||
</div>
|
||||
|
||||
<div class="inner-wrapper" id="feedback_success_wrapper" tabindex="-1">
|
||||
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">✕</a>
|
||||
|
||||
<header>
|
||||
<h2>${_('Thank You!')}</h2>
|
||||
<hr>
|
||||
@@ -104,22 +106,31 @@ discussion_link = get_discussion_link(course) if course else None
|
||||
).format(
|
||||
open_time=open_time,
|
||||
close_time=close_time,
|
||||
link_start='<a href="{}" target="_blank">'.format(marketing_link('FAQ')),
|
||||
link_start='<a href="{}" target="_blank" id="feedback-faq-link">'.format(marketing_link('FAQ')),
|
||||
link_end='</a>'
|
||||
)}
|
||||
</p>
|
||||
|
||||
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">✕</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var onModalClose = function() {
|
||||
$(".help-modal .close-modal").off("click");
|
||||
$("#lean_overlay").off("click");
|
||||
$("#help-modal").attr("aria-hidden", "true");
|
||||
};
|
||||
$(".help-modal .close-modal").off("click");
|
||||
$("#lean_overlay").off("click");
|
||||
$("#help-modal").attr("aria-hidden", "true");
|
||||
$(".help-tab").focus();
|
||||
},
|
||||
cycle_modal_tab = function(from_element_name, to_element_name) {
|
||||
$(from_element_name).on('keydown', function(e) {
|
||||
var keyCode = e.keyCode || e.which;
|
||||
if (keyCode === 9) {
|
||||
e.preventDefault();
|
||||
$(to_element_name).focus();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$(".help-tab").click(function() {
|
||||
$(".field-error").removeClass("field-error");
|
||||
$("#feedback_form")[0].reset();
|
||||
@@ -131,6 +142,7 @@ discussion_link = get_discussion_link(course) if course else None
|
||||
$("#help-modal").attr("aria-hidden", "false");
|
||||
$("#help-modal .close-modal").click(onModalClose);
|
||||
$("#lean_overlay").click(onModalClose);
|
||||
$("#help_wrapper .close-modal").focus();
|
||||
});
|
||||
showFeedback = function(event, issue_type, title, subject_label, details_label) {
|
||||
$("#help_wrapper").css("display", "none");
|
||||
@@ -139,8 +151,12 @@ discussion_link = get_discussion_link(course) if course else None
|
||||
$("#feedback_form_wrapper header").html("<h2>" + title + "</h2><hr>");
|
||||
$("#feedback_form_wrapper label[data-field='subject']").html(subject_label);
|
||||
$("#feedback_form_wrapper label[data-field='details']").html(details_label);
|
||||
$("#feedback_form_wrapper .close-modal").focus();
|
||||
event.preventDefault();
|
||||
};
|
||||
cycle_modal_tab("#feedback_link_question", "#help_wrapper .close-modal");
|
||||
cycle_modal_tab("#feedback_submit", "#feedback_form_wrapper .close-modal");
|
||||
cycle_modal_tab("#feedback_faq_link", "#feedback_success_wrapper .close-modal");
|
||||
$("#feedback_link_problem").click(function(event) {
|
||||
showFeedback(
|
||||
event,
|
||||
|
||||
Reference in New Issue
Block a user