Index: static/js/main.js |
=================================================================== |
--- a/static/js/main.js |
+++ b/static/js/main.js |
@@ -44,10 +44,113 @@ |
{ |
customSelectEls[i] |
.addEventListener("click", onClickCustomSelect, false); |
customSelectEls[i] |
.nextElementSibling |
.setAttribute("aria-hidden", "true"); |
} |
+ |
+ // Accordion menu |
juliandoucette
2017/09/20 14:19:38
NIT: I prefer an OO approach (an Accordion Functio
ire
2017/09/25 11:25:18
Done.
|
+ |
+ function setupAccordionMenu(accordionEl) |
juliandoucette
2017/09/20 14:19:37
Suggest: "accordion"
"No hungarian notation, no s
ire
2017/09/25 11:25:18
Done. Does this apply to the "accordionButtons"? S
juliandoucette
2017/09/26 18:57:05
I don't think so. But it's hard to explain why :D
ire
2017/09/28 14:48:52
Haha okay. I don't think it applies either, but I
|
+ { |
+ var accordionButtons = accordionEl.getElementsByClassName('accordion-toggle-button'); |
+ |
+ for ( var i = 0; i < accordionButtons.length; i++ ) |
juliandoucette
2017/09/20 14:19:38
NIT: I think that we don't put spaces inside these
ire
2017/09/25 11:25:17
Done.
|
+ { |
+ accordionButtons[i] |
juliandoucette
2017/09/20 14:19:38
Suggest: Initialize state before adding event list
ire
2017/09/25 11:25:17
I don't have an opinion either way. Done.
juliandoucette
2017/09/26 18:57:06
You didn't do this?
ire
2017/09/28 14:48:52
Oops, missed this. Done now (I hope :p)
|
+ .addEventListener("click", toggleAccordionSection, false); |
+ accordionButtons[i] |
+ .addEventListener("keydown", navigateAccordionHeadings, false); |
+ |
+ // Close all sections besides the first |
juliandoucette
2017/09/20 14:19:37
Suggest: "except" instead of "besides" :D
"beside
ire
2017/09/25 11:25:18
I've been using "besides" wrong all my life :O hah
|
+ if ( i !== 0 ) |
+ { |
+ accordionButtons[i].setAttribute("aria-expanded", "false"); |
+ accordionButtons[i].setAttribute("aria-disabled", "false"); |
juliandoucette
2017/09/20 14:19:38
I think that aria-disabled is only appropriate whe
ire
2017/09/25 11:25:17
Yup, see my comment above.
|
+ document |
+ .getElementById( accordionButtons[i].getAttribute("aria-controls") ) |
+ .setAttribute("hidden", "true"); |
+ } |
+ } |
+ } |
+ |
+ function toggleAccordionSection() |
juliandoucette
2017/09/20 14:19:38
NIT: This function name sounds functional, but it'
ire
2017/09/25 11:25:17
I generally prefer explanatory names, particularly
juliandoucette
2017/09/26 18:57:05
I agree. But I think that the context is misleadin
ire
2017/09/28 14:48:52
Yes, I created the issue #5652 to refactor this an
|
+ { |
+ // Hide currently expanded section |
+ var accordion = this.parentElement.parentElement; |
+ var expandedButton = accordion.querySelector("button[aria-expanded='true']"); |
+ if ( expandedButton ) |
juliandoucette
2017/09/20 14:19:38
NIT/Suggest: Make it clearer that you are checking
ire
2017/09/25 11:25:18
Doesn't the name "expandedButton" do that?
juliandoucette
2017/09/26 18:57:05
Yes? :/ (I have no idea what I was thinking :D)
|
+ { |
+ expandedButton.setAttribute("aria-expanded", "false"); |
+ expandedButton.setAttribute("aria-disabled", "false"); |
+ document |
+ .getElementById( expandedButton.getAttribute("aria-controls") ) |
+ .setAttribute("hidden", "true"); |
+ } |
+ |
+ if ( expandedButton === this ) return; |
juliandoucette
2017/09/20 14:19:37
NIT/Suggest: Make it clearer that you are handling
ire
2017/09/25 11:25:18
Done.
|
+ |
+ // Expand new section |
+ this.setAttribute("aria-expanded", "true"); |
+ this.setAttribute("aria-disabled", "true"); |
+ document |
+ .getElementById( this.getAttribute("aria-controls") ) |
+ .removeAttribute("hidden"); |
juliandoucette
2017/09/20 14:19:38
NIT/Suggest: .focus() too? So that you could click
ire
2017/09/25 11:25:17
Why focus an element that isn't typically focusabl
juliandoucette
2017/09/26 18:57:05
I think that I was confused. What I was really sug
ire
2017/09/28 14:48:52
Now I think I'm confused :/
But currently, you ca
|
+ } |
+ |
+ function navigateAccordionHeadings(e) |
juliandoucette
2017/09/20 14:19:37
NIT/Suggest: "event"
Julian Doucette: Does our co
ire
2017/09/25 11:25:17
Done.
|
+ { |
+ if ( e.keyCode !== 38 && e.keyCode !== 40 ) return; |
juliandoucette
2017/09/20 14:19:38
NIT/Suggest: Prefer event.key and fall back to eve
ire
2017/09/25 11:25:17
Done.
|
+ |
+ var accordion = this.parentElement.parentElement; |
+ |
+ // Direction == up |
+ if ( e.keyCode == 38 ) |
juliandoucette
2017/09/20 14:19:38
NIT/Suggest: Name keycodes e.g. var KEY_UP = 38.
ire
2017/09/25 11:25:18
Done.
|
+ { |
+ var prevEl = this.parentElement.previousElementSibling; |
+ if ( prevEl ) |
juliandoucette
2017/09/20 14:19:38
NIT/Suggest: Make it clearer that you are checking
ire
2017/09/25 11:25:18
This would mean I cannot use the same variable nam
juliandoucette
2017/09/26 18:57:05
Acknowledged.
|
+ { |
+ prevEl // .accordion-body |
+ .previousElementSibling // .accordion-heading |
+ .firstElementChild // .accordion-toggle-button |
+ .focus(); |
+ } |
+ else |
+ { |
+ accordion |
+ .lastElementChild // .accordion-body |
+ .previousElementSibling // .accordion-heading |
+ .firstElementChild // .accordion-toggle-button |
+ .focus(); |
+ } |
+ } |
+ |
+ // Direction == down |
+ else if ( e.keyCode == 40 ) |
+ { |
+ var nextheading = this.parentElement.nextElementSibling.nextElementSibling; |
+ if ( nextheading ) |
+ { |
+ nextheading // .accordion-heading |
+ .firstElementChild // .accordion-toggle-button |
+ .focus(); |
+ } |
+ else |
+ { |
+ accordion |
+ .firstElementChild // .accordion-heading |
+ .firstElementChild // .accordion-toggle-button |
+ .focus(); |
+ } |
+ } |
+ } |
+ |
+ var accordionMenus = document.getElementsByClassName('accordion'); |
+ for (var i = 0; i < accordionMenus.length; i++) |
+ { |
+ setupAccordionMenu( accordionMenus[i] ); |
+ } |
+ |
}, false); |
}()); |