Remove dead code

This commit is contained in:
Seamus Johnston 2023-02-02 16:04:42 -06:00
parent 0e3f68622f
commit c2feb1fc16
No known key found for this signature in database
GPG key ID: 2F21225985069105
7 changed files with 15 additions and 206 deletions

View file

@ -6,17 +6,9 @@
* Initialization (run-on-load) stuff goes at the bottom.
*/
/** Strings announced to assistive technology users. */
var ARIA = {
QUESTION_REMOVED: "Previous follow-up question removed",
QUESTION_ADDED: "New follow-up question required"
}
var DEFAULT_ERROR = "Please check this field for errors.";
var REQUIRED = "required";
var INPUT = "input";
// <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
// Helper functions.
@ -38,104 +30,24 @@ function makeVisible(el) {
el.style.visibility = "visible";
}
/** Executes `func` once per selected child of a given element. */
function forEachChild(el, selector, func) {
const children = el.querySelectorAll(selector);
for (const child of children) {
func(child)
}
}
/** Removes `required` attribute from input. */
const removeRequired = input => input.removeAttribute(REQUIRED);
/** Adds `required` attribute to input. */
const setRequired = input => input.setAttribute(REQUIRED, "");
/** Removes `checked` attribute from input. */
const removeChecked = input => input.checked = false;
/** Adds `checked` attribute to input. */
const setChecked = input => input.checked = true;
/** Creates and returns a live region element. */
function createLiveRegion(id) {
const liveRegion = document.createElement("div");
liveRegion.setAttribute("role", "region");
liveRegion.setAttribute("aria-live", "polite");
liveRegion.setAttribute("id", id + "-live-region");
liveRegion.classList.add("sr-only");
liveRegion.classList.add("usa-sr-only");
document.body.appendChild(liveRegion);
return liveRegion;
}
/** Currently selected radio buttons. */
var selected = {};
/** Mapping of radio buttons to the toggleables they control. */
var radioToggles = {};
/**
* Tracks state of selected radio button.
*
* This is required due to JavaScript not having a native
* event trigger for "deselect" on radio buttons. Tracking
* which button has been deselected (and hiding the associated
* toggleable) is a manual task.
* */
function rememberSelected(radioButton) {
selected[radioButton.name] = radioButton;
}
/** Announces changes to assistive technology users. */
function announce(id, text) {
const liveRegion = document.getElementById(id + "-live-region");
let liveRegion = document.getElementById(id + "-live-region");
if (!liveRegion) liveRegion = createLiveRegion(id);
liveRegion.innerHTML = text;
}
/**
* Used by an event handler to hide HTML.
*
* Hides any previously visible HTML associated with
* previously selected radio buttons.
*/
function hideToggleable(e) {
// has any button in this radio button group been selected?
const selectionExists = e.target.name in selected;
if (selectionExists) {
// does the selection have any hidden content associated with it?
const hasToggleable = selected[e.target.name].id in radioToggles;
if (hasToggleable) {
const prevRadio = selected[e.target.name];
const prevToggleable = radioToggles[prevRadio.id];
// is this event handler for a different button?
const selectionHasChanged = (e.target != prevRadio);
// is the previous button's content still visible?
const prevSelectionVisible = (prevToggleable.style.visibility !== "hidden");
if (selectionHasChanged && prevSelectionVisible) {
makeHidden(prevToggleable);
forEachChild(prevToggleable, INPUT, removeChecked);
forEachChild(prevToggleable, INPUT, removeRequired);
announce(prevToggleable.id, ARIA.QUESTION_REMOVED);
}
}
}
}
function revealToggleable(e) {
// if the currently selected radio button has a toggle
// make it visible
if (e.target.id in radioToggles) {
const toggleable = radioToggles[e.target.id];
rememberSelected(e.target);
if (e.target.required) forEachChild(toggleable, INPUT, setRequired);
makeVisible(toggleable);
announce(toggleable.id, ARIA.QUESTION_ADDED);
}
}
/**
* Slow down event handlers by limiting how frequently they fire.
*
@ -200,13 +112,6 @@ const checkDomainAvailability = debounce(_checkDomainAvailability);
// <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
// Event handlers.
/** On radio button selection change, handles associated toggleables. */
function handleToggle(e) {
// hide any previously visible HTML associated with previously selected radio buttons
hideToggleable(e);
// display any HTML associated with the newly selected radio button
revealToggleable(e);
}
/** On input change, handles running any associated validators. */
function handleInputValidation(e) {
@ -241,56 +146,5 @@ function handleInputValidation(e) {
}
})();
/**
* An IIFE that will hide any elements with `hide-on-load` attribute.
*
* Why not start with `hidden`? Because this is for use with form questions:
* if Javascript fails, users will still need access to those questions.
*/
(function hiddenInit() {
"use strict";
const hiddens = document.querySelectorAll('[hide-on-load]');
for(const hidden of hiddens) {
makeHidden(hidden);
forEachChild(hidden, INPUT, removeRequired);
}
})();
/**
* An IIFE that adds onChange listeners to radio buttons.
*
* An element with `toggle-by="<id>,<id>"` will be hidden/shown
* by a radio button with `id="<id>"`.
*
* It also inserts the ARIA live region to be used when
* announcing show/hide to screen reader users.
*/
(function toggleInit() {
"use strict";
// get elements to show/hide
const toggleables = document.querySelectorAll('[toggle-by]');
for(const toggleable of toggleables) {
// get the (comma-seperated) list of radio button ids
// which trigger this toggleable to become visible
const attribute = toggleable.getAttribute("toggle-by") || "";
if (!attribute.length) continue;
const radioIDs = attribute.split(",");
createLiveRegion(toggleable.id)
for (const id of radioIDs) {
radioToggles[id] = toggleable;
// if it is already selected, track that
const radioButton = document.getElementById(id);
if (radioButton.checked) rememberSelected(radioButton);
}
}
// all radio buttons must react to selection changes
const radioButtons = document.querySelectorAll('input[type="radio"]');
for (const radioButton of Array.from(radioButtons)) {
radioButton.addEventListener('change', handleToggle);
}
})();

View file

@ -1,5 +1,5 @@
{% extends 'base.html' %}
{% load static widget_tweaks dynamic_question_tags namespaced_urls %}
{% load static form_helpers url_helpers %}
{% block title %}Apply for a .gov domain {{form_titles|get_item:steps.current}}{% endblock %}
{% block content %}

View file

@ -1,5 +1,5 @@
{% extends 'application_form.html' %}
{% load static namespaced_urls %}
{% load static url_helpers %}
{% block form_fields %}
{% csrf_token %}

View file

@ -1,4 +1,4 @@
{% load static namespaced_urls %}
{% load static url_helpers %}
<div class="margin-bottom-4 tablet:margin-bottom-0">
<nav aria-label="Form steps,">

View file

@ -1,54 +0,0 @@
from django import template
from django.forms import BaseFormSet
from django.utils.html import format_html
register = template.Library()
@register.filter
def isformset(value):
return isinstance(value, BaseFormSet)
@register.simple_tag
def radio_buttons_by_value(boundfield):
"""
Returns radio button subwidgets indexed by their value.
This makes it easier to visually identify the choices when
using them in templates.
"""
return {w.data["value"]: w for w in boundfield.subwidgets}
@register.simple_tag
def trigger(boundfield, *triggers):
"""
Inserts HTML to link a dynamic question to its trigger(s).
Currently only works for radio buttons.
Also checks whether the question should be hidden on page load.
If the question is already answered or if the question's
trigger is already selected, it should not be hidden.
Returns HTML attributes which will be read by a JavaScript
helper, if the user has JavaScript enabled.
"""
ids = []
hide_on_load = True
for choice in boundfield.subwidgets:
if choice.data["selected"]:
hide_on_load = False
for trigger in triggers:
ids.append(trigger.id_for_label)
if trigger.data["selected"]:
hide_on_load = False
html = format_html(
'toggle-by="{}"{}', ",".join(ids), " hide-on-load" if hide_on_load else ""
)
return html

View file

@ -0,0 +1,9 @@
from django import template
from django.forms import BaseFormSet
register = template.Library()
@register.filter
def isformset(value):
return isinstance(value, BaseFormSet)