| Index: static/js/main.js |
| =================================================================== |
| --- a/static/js/main.js |
| +++ b/static/js/main.js |
| @@ -44,10 +44,126 @@ |
| { |
| customSelectEls[i] |
| .addEventListener("click", onClickCustomSelect, false); |
| customSelectEls[i] |
| .nextElementSibling |
| .setAttribute("aria-hidden", "true"); |
| } |
| + // Accordion menu |
| + |
| + function Accordion(accordion) |
| + { |
| + this.accordion = accordion; |
| + |
| + var accordionButtons = this.accordion.getElementsByClassName('accordion-toggle-button'); |
| + for (var i = 0; i < accordionButtons.length; i++) |
| + { |
| + // Close all sections except the first |
| + if (i !== 0) |
| + { |
| + accordionButtons[i].setAttribute("aria-expanded", "false"); |
| + document |
| + .getElementById( accordionButtons[i].getAttribute("aria-controls") ) |
|
juliandoucette
2017/10/09 21:18:16
NIT: Extra whitespace inside brackets
(The same a
|
| + .setAttribute("hidden", "true"); |
| + } |
| + } |
| + |
| + this.accordion |
| + .addEventListener("click", this._onClick.bind(this), false); |
| + this.accordion |
| + .addEventListener("keydown", this._onKeyDown.bind(this), false); |
| + } |
| + |
| + Accordion.prototype.toggleSection = function(clickedButton) |
| + { |
| + // Hide currently expanded section |
| + var expandedButton = this.accordion.querySelector("button[aria-expanded='true']"); |
| + if (expandedButton) |
| + { |
| + expandedButton.setAttribute("aria-expanded", "false"); |
| + document |
| + .getElementById( expandedButton.getAttribute("aria-controls") ) |
| + .setAttribute("hidden", "true"); |
| + } |
| + |
| + // If currently expanded section is clicked |
| + if (expandedButton === clickedButton) return; |
| + |
| + // Expand new section |
| + clickedButton.setAttribute("aria-expanded", "true"); |
| + document |
| + .getElementById( clickedButton.getAttribute("aria-controls") ) |
| + .removeAttribute("hidden"); |
| + } |
| + |
| + Accordion.prototype.focusNextSection = function() |
| + { |
| + var currentFocus = document.activeElement; |
| + var nextheading = currentFocus.parentElement.nextElementSibling.nextElementSibling; |
| + |
| + if (nextheading) |
| + { |
| + nextheading // .accordion-heading |
| + .firstElementChild // .accordion-toggle-button |
| + .focus(); |
| + } |
| + else |
| + { |
| + this.accordion |
| + .firstElementChild // .accordion-heading |
| + .firstElementChild // .accordion-toggle-button |
| + .focus(); |
| + } |
| + } |
| + |
| + Accordion.prototype.focusPrevSection = function() |
| + { |
| + var currentFocus = document.activeElement; |
| + var prevAccordionBody = currentFocus.parentElement.previousElementSibling; |
| + |
| + if (prevAccordionBody) |
| + { |
| + prevAccordionBody // .accordion-body |
| + .previousElementSibling // .accordion-heading |
| + .firstElementChild // .accordion-toggle-button |
| + .focus(); |
| + } |
| + else |
| + { |
| + this.accordion |
| + .lastElementChild // .accordion-body |
| + .previousElementSibling // .accordion-heading |
| + .firstElementChild // .accordion-toggle-button |
| + .focus(); |
| + } |
| + } |
| + |
| + Accordion.prototype._onKeyDown = function(event) |
| + { |
| + if (!event.target.classList.contains("accordion-toggle-button")) return; |
| + |
| + if (event.key == "ArrowUp" || event.keyCode == 38) |
| + { |
| + this.focusPrevSection(); |
| + } |
| + else if (event.key == "ArrowDown" || event.keyCode == 40) |
| + { |
| + this.focusNextSection(); |
| + } |
| + } |
| + |
| + Accordion.prototype._onClick = function(event) |
| + { |
| + if (!event.target.classList.contains("accordion-toggle-button")) return; |
| + |
| + this.toggleSection(event.target); |
| + } |
| + |
| + var accordions = document.getElementsByClassName('accordion'); |
| + for (var i = 0; i < accordions.length; i++) |
| + { |
| + new Accordion(accordions[i]); |
| + } |
| + |
| }, false); |
| }()); |