Commit aee5af53 by Xavier Antoviaque

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.
parent 23eab5c5
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
<section id="help-modal" class="modal" aria-hidden="true"> <section id="help-modal" class="modal" aria-hidden="true">
<div class="inner-wrapper" id="help_wrapper"> <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')}">&#10005;</a>
<header> <header>
<h2>${_('{span_start}{platform_name}{span_end} Help').format(span_start='<span class="edx">', span_end='</span>', platform_name=settings.PLATFORM_NAME)}</h2> <h2>${_('{span_start}{platform_name}{span_end} Help').format(span_start='<span class="edx">', span_end='</span>', platform_name=settings.PLATFORM_NAME)}</h2>
<hr> <hr>
...@@ -47,12 +50,11 @@ discussion_link = get_discussion_link(course) if course else None ...@@ -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_suggestion">${_('Make a suggestion')}</a>
<a href="#" id="feedback_link_question">${_('Ask a question')}</a> <a href="#" id="feedback_link_question">${_('Ask a question')}</a>
</div> </div>
## TODO: find a way to refactor this
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">&#10005;</a>
</div> </div>
<div class="inner-wrapper" id="feedback_form_wrapper"> <div class="inner-wrapper" id="feedback_form_wrapper">
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">&#10005;</a>
<header></header> <header></header>
<form id="feedback_form" class="feedback_form" method="post" data-remote="true" action="/submit_feedback"> <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 ...@@ -73,14 +75,14 @@ discussion_link = get_discussion_link(course) if course else None
<input name="course_id" type="hidden" value="${course.id | h}"> <input name="course_id" type="hidden" value="${course.id | h}">
% endif % endif
<div class="submit"> <div class="submit">
<input name="submit" type="submit" value="Submit"> <input name="submit" type="submit" value="Submit" id="feedback_submit">
</div> </div>
</form> </form>
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">&#10005;</a>
</div> </div>
<div class="inner-wrapper" id="feedback_success_wrapper" tabindex="-1"> <div class="inner-wrapper" id="feedback_success_wrapper" tabindex="-1">
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">&#10005;</a>
<header> <header>
<h2>${_('Thank You!')}</h2> <h2>${_('Thank You!')}</h2>
<hr> <hr>
...@@ -104,22 +106,31 @@ discussion_link = get_discussion_link(course) if course else None ...@@ -104,22 +106,31 @@ discussion_link = get_discussion_link(course) if course else None
).format( ).format(
open_time=open_time, open_time=open_time,
close_time=close_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>' link_end='</a>'
)} )}
</p> </p>
<a href="#" role="button" class="close-modal" title="${_('Close Modal')}">&#10005;</a>
</div> </div>
</section> </section>
<script type="text/javascript"> <script type="text/javascript">
(function() { (function() {
var onModalClose = function() { var onModalClose = function() {
$(".help-modal .close-modal").off("click"); $(".help-modal .close-modal").off("click");
$("#lean_overlay").off("click"); $("#lean_overlay").off("click");
$("#help-modal").attr("aria-hidden", "true"); $("#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() { $(".help-tab").click(function() {
$(".field-error").removeClass("field-error"); $(".field-error").removeClass("field-error");
$("#feedback_form")[0].reset(); $("#feedback_form")[0].reset();
...@@ -131,6 +142,7 @@ discussion_link = get_discussion_link(course) if course else None ...@@ -131,6 +142,7 @@ discussion_link = get_discussion_link(course) if course else None
$("#help-modal").attr("aria-hidden", "false"); $("#help-modal").attr("aria-hidden", "false");
$("#help-modal .close-modal").click(onModalClose); $("#help-modal .close-modal").click(onModalClose);
$("#lean_overlay").click(onModalClose); $("#lean_overlay").click(onModalClose);
$("#help_wrapper .close-modal").focus();
}); });
showFeedback = function(event, issue_type, title, subject_label, details_label) { showFeedback = function(event, issue_type, title, subject_label, details_label) {
$("#help_wrapper").css("display", "none"); $("#help_wrapper").css("display", "none");
...@@ -139,8 +151,12 @@ discussion_link = get_discussion_link(course) if course else 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 header").html("<h2>" + title + "</h2><hr>");
$("#feedback_form_wrapper label[data-field='subject']").html(subject_label); $("#feedback_form_wrapper label[data-field='subject']").html(subject_label);
$("#feedback_form_wrapper label[data-field='details']").html(details_label); $("#feedback_form_wrapper label[data-field='details']").html(details_label);
$("#feedback_form_wrapper .close-modal").focus();
event.preventDefault(); 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) { $("#feedback_link_problem").click(function(event) {
showFeedback( showFeedback(
event, event,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment