Convert clickable divs to buttons or add role="button" for keyboard accessibility

This commit is contained in:
2026-04-16 07:59:57 +08:00
parent 220dbaa683
commit 090acbd66b
12 changed files with 75 additions and 47 deletions
+2 -2
View File
@@ -48,7 +48,7 @@ class AccountForm {
/**
* The control of the base account
* @type {HTMLDivElement}
* @type {HTMLButtonElement}
*/
#baseControl;
@@ -60,7 +60,7 @@ class AccountForm {
/**
* The base account
* @type {HTMLDivElement}
* @type {HTMLSpanElement}
*/
#base;
@@ -701,12 +701,23 @@ class DebitCreditSubForm {
this.#element.classList.add("accounting-not-empty");
this.currency.form.lineItemEditor.onAddNew(this);
};
this.#element.role = "button";
this.#element.tabIndex = 0;
this.#element.onkeydown = (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
this.#element.click();
}
};
} else {
this.#element.classList.add("accounting-not-empty");
this.#element.classList.remove("accounting-clickable");
delete this.#element.dataset.bsToggle;
delete this.#element.dataset.bsTarget;
this.#element.onclick = null;
this.#element.removeAttribute("role");
this.#element.tabIndex = -1;
this.#element.onkeydown = null;
}
setElementShown(this.#content, this.lineItems.length !== 0);
}
@@ -986,6 +997,12 @@ class LineItemSubForm {
this.#element.parentElement.removeChild(this.#element);
this.debitCreditSubForm.deleteLineItem(this);
};
this.#control.onkeydown = (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
this.#control.click();
}
};
}
/**
@@ -66,13 +66,13 @@ class JournalEntryLineItemEditor {
/**
* The control of the original line item
* @type {HTMLDivElement}
* @type {HTMLButtonElement}
*/
#originalLineItemControl;
/**
* The original line item
* @type {HTMLDivElement}
* @type {HTMLSpanElement}
*/
#originalLineItemText;
@@ -90,13 +90,13 @@ class JournalEntryLineItemEditor {
/**
* The control of the description
* @type {HTMLDivElement}
* @type {HTMLButtonElement}
*/
#descriptionControl;
/**
* The description
* @type {HTMLDivElement}
* @type {HTMLSpanElement}
*/
#descriptionText;
@@ -108,13 +108,13 @@ class JournalEntryLineItemEditor {
/**
* The control of the account
* @type {HTMLDivElement}
* @type {HTMLButtonElement}
*/
#accountControl;
/**
* The account
* @type {HTMLDivElement}
* @type {HTMLSpanElement}
*/
#accountText;
+17 -6
View File
@@ -298,6 +298,14 @@ class RecurringExpenseIncomeSubForm {
this.#element.dataset.bsTarget = `#${this.editor.modal.id}`;
this.#element.onclick = () => this.editor.onAddNew();
this.#content.classList.add("d-none");
this.#element.role = "button";
this.#element.tabIndex = 0;
this.#element.onkeydown = (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
this.#element.click();
}
};
} else {
this.#element.classList.add("accounting-not-empty");
this.#element.classList.remove("accounting-clickable");
@@ -305,6 +313,9 @@ class RecurringExpenseIncomeSubForm {
delete this.#element.dataset.bsTarget;
this.#element.onclick = null;
this.#content.classList.remove("d-none");
this.#element.removeAttribute("role");
this.#element.tabIndex = -1;
this.#element.onkeydown = null;
}
}
@@ -375,7 +386,7 @@ class RecurringItemSubForm {
/**
* The control
* @type {HTMLDivElement}
* @type {HTMLButtonElement}
*/
#control;
@@ -399,7 +410,7 @@ class RecurringItemSubForm {
/**
* The text display of the name
* @type {HTMLDivElement}
* @type {HTMLSpanElement}
*/
#nameText;
@@ -411,7 +422,7 @@ class RecurringItemSubForm {
/**
* The text display of the account
* @type {HTMLDivElement}
* @type {HTMLSpanElement}
*/
#accountText;
@@ -423,7 +434,7 @@ class RecurringItemSubForm {
/**
* The text display of the description template
* @type {HTMLDivElement}
* @type {HTMLSpanElement}
*/
#descriptionTemplateText;
@@ -595,13 +606,13 @@ class RecurringItemEditor {
/**
* The control of the account
* @type {HTMLDivElement}
* @type {HTMLButtonElement}
*/
#accountControl;
/**
* The text display of the account
* @type {HTMLDivElement}
* @type {HTMLSpanElement}
*/
#accountContainer;
@@ -41,9 +41,9 @@ First written: 2023/2/1
{% endif %}
<div class="form-floating mb-3">
<input id="accounting-base-code" type="hidden" name="base_code" value="{{ form.base_code.data|accounting_default }}">
<div id="accounting-base-control" class="form-control accounting-clickable accounting-material-text-field {% if form.base_code.data %} accounting-not-empty {% endif %} {% if form.base_code.errors %} is-invalid {% endif %}" data-bs-toggle="modal" data-bs-target="#accounting-base-selector-modal">
<label class="form-label" for="accounting-base">{{ A_("Base account") }}</label>
<div id="accounting-base">
<button id="accounting-base-control" class="form-control text-start accounting-material-text-field {% if form.base_code.data %} accounting-not-empty {% endif %} {% if form.base_code.errors %} is-invalid {% endif %}" type="button" data-bs-toggle="modal" data-bs-target="#accounting-base-selector-modal">
<span class="form-label">{{ A_("Base account") }}</span>
<span id="accounting-base">
{% if form.base_code.data %}
{% if form.base_code.errors %}
{{ A_("(Unknown)") }}
@@ -51,8 +51,8 @@ First written: 2023/2/1
{{ form.selected_base }}
{% endif %}
{% endif %}
</div>
</div>
</span>
</button>
<div id="accounting-base-error" class="invalid-feedback">{% if form.base_code.errors %}{{ form.base_code.errors[0] }}{% endif %}</div>
</div>
@@ -20,8 +20,8 @@ Author: imacat@mail.imacat.idv.tw (imacat)
First written: 2023/3/21
#}
<div class="mb-2">
<div id="accounting-currency-{{ currency_index }}-{{ debit_credit }}" class="form-control accounting-material-text-field {% if line_item_forms %} accounting-not-empty {% else %} accounting-clickable {% endif %} {% if debit_errors %} is-invalid {% endif %}">
<label class="form-label" for="accounting-currency-{{ currency_index }}-{{ debit_credit }}">{{ header }}</label>
<div id="accounting-currency-{{ currency_index }}-{{ debit_credit }}" class="form-control accounting-material-text-field {% if line_item_forms %} accounting-not-empty {% else %} accounting-clickable {% endif %} {% if debit_errors %} is-invalid {% endif %}" {% if line_item_forms %} tabindex="-1" {% else %} role="button" tabindex="0" {% endif %}>
<span class="form-label">{{ header }}</span>
<div id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-content" class="mt-2 {% if not line_item_forms %} d-none {% endif %}">
<ul id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-list" class="list-group accounting-line-item-list">
{% for line_item_form in line_item_forms %}
@@ -30,7 +30,7 @@ First written: 2023/2/25
<input id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-description" type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-description" value="{{ form.description.data|accounting_default }}">
<input id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-amount" type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-amount" value="{{ form.amount.data|accounting_journal_entry_format_amount_input }}" data-min="{{ form.offset_total|accounting_default("0") }}">
<div class="accounting-line-item-content">
<div id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-control" class="form-control clickable d-flex justify-content-between {% if form.all_errors %} is-invalid {% endif %}" data-bs-toggle="modal" data-bs-target="#accounting-line-item-editor-modal">
<div id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-control" class="form-control clickable d-flex justify-content-between {% if form.all_errors %} is-invalid {% endif %}" role="button" tabindex="0" data-bs-toggle="modal" data-bs-target="#accounting-line-item-editor-modal">
<div>
<div class="small">
<span id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-account-text-code" class="d-none d-md-inline">{{ form.account_code.data|accounting_default }}</span>
@@ -31,10 +31,10 @@ First written: 2023/2/25
<div class="modal-body">
<div id="accounting-line-item-editor-original-line-item-container" class="d-flex justify-content-between mb-3">
<div class="accounting-line-item-editor-original-line-item-content">
<div id="accounting-line-item-editor-original-line-item-control" class="form-control accounting-clickable accounting-material-text-field" data-bs-toggle="modal" data-bs-target="#accounting-original-line-item-selector-modal">
<label class="form-label" for="accounting-line-item-editor-original-line-item">{{ A_("Original Line Item") }}</label>
<div id="accounting-line-item-editor-original-line-item"></div>
</div>
<button id="accounting-line-item-editor-original-line-item-control" class="form-control text-start accounting-material-text-field" type="button" data-bs-toggle="modal" data-bs-target="#accounting-original-line-item-selector-modal">
<span class="form-label">{{ A_("Original Line Item") }}</span>
<span id="accounting-line-item-editor-original-line-item"></span>
</button>
<div id="accounting-line-item-editor-original-line-item-error" class="invalid-feedback"></div>
</div>
@@ -46,18 +46,18 @@ First written: 2023/2/25
</div>
<div class="mb-3">
<div id="accounting-line-item-editor-description-control" class="form-control accounting-clickable accounting-material-text-field" data-bs-toggle="modal" data-bs-target="">
<label class="form-label" for="accounting-line-item-editor-description">{{ A_("Description") }}</label>
<div id="accounting-line-item-editor-description"></div>
</div>
<button id="accounting-line-item-editor-description-control" class="form-control text-start accounting-material-text-field" type="button" data-bs-toggle="modal" data-bs-target="">
<span class="form-label">{{ A_("Description") }}</span>
<span id="accounting-line-item-editor-description"></span>
</button>
<div id="accounting-line-item-editor-description-error" class="invalid-feedback"></div>
</div>
<div class="mb-3">
<div id="accounting-line-item-editor-account-control" class="form-control accounting-clickable accounting-material-text-field" data-bs-toggle="modal" data-bs-target="">
<label class="form-label" for="accounting-line-item-editor-account">{{ A_("Account") }}</label>
<div id="accounting-line-item-editor-account"></div>
</div>
<button id="accounting-line-item-editor-account-control" class="form-control text-start accounting-material-text-field" type="button" data-bs-toggle="modal" data-bs-target="">
<span class="form-label">{{ A_("Account") }}</span>
<span id="accounting-line-item-editor-account"></span>
</button>
<div id="accounting-line-item-editor-account-error" class="invalid-feedback"></div>
</div>
@@ -19,8 +19,8 @@ form-recurring-expense-income.html: The recurring expense or income sub-form in
Author: imacat@mail.imacat.idv.tw (imacat)
First written: 2023/3/22
#}
<div id="accounting-recurring-{{ expense_income }}" class="form-control mb-3 accounting-material-text-field {% if recurring_items %} accounting-not-empty {% else %} accounting-clickable {% endif %}">
<label class="form-label" for="accounting-recurring-{{ expense_income }}">{{ label }}</label>
<div id="accounting-recurring-{{ expense_income }}" class="form-control mb-3 accounting-material-text-field {% if recurring_items %} accounting-not-empty {% else %} accounting-clickable {% endif %}" {% if recurring_items %} tabindex="-1" {% else %} role="button" tabindex="0" {% endif %}>
<span class="form-label">{{ label }}</span>
<div id="accounting-recurring-{{ expense_income }}-content" class="{% if not recurring_items %} d-none {% endif %}">
<ul id="accounting-recurring-{{ expense_income }}-list" class="list-group mb-2 mt-2">
{% for recurring_item in recurring_items %}
@@ -27,11 +27,11 @@ First written: 2023/3/22
<input id="accounting-recurring-{{ expense_income }}-{{ item_index }}-description-template" type="hidden" name="recurring-{{ expense_income }}-{{ item_index }}-description_template" value="{{ form.description_template.data|accounting_default }}">
<div class="d-flex justify-content-between">
<div class="w-100">
<div id="accounting-recurring-{{ expense_income }}-{{ item_index }}-control" class="form-control accounting-clickable {% if form.all_errors %} is-invalid {% endif %}" data-bs-toggle="modal" data-bs-target="#accounting-recurring-item-editor-{{ expense_income }}-modal">
<div id="accounting-recurring-{{ expense_income }}-{{ item_index }}-account-text" class="small">{{ form.account_text|accounting_default }}</div>
<div id="accounting-recurring-{{ expense_income }}-{{ item_index }}-name-text">{{ form.name.data|accounting_default }}</div>
<div id="accounting-recurring-{{ expense_income }}-{{ item_index }}-description-template-text" class="small">{{ form.description_template.data|accounting_default }}</div>
</div>
<button id="accounting-recurring-{{ expense_income }}-{{ item_index }}-control" class="form-control text-start {% if form.all_errors %} is-invalid {% endif %}" type="button" data-bs-toggle="modal" data-bs-target="#accounting-recurring-item-editor-{{ expense_income }}-modal">
<span id="accounting-recurring-{{ expense_income }}-{{ item_index }}-account-text" class="d-block small">{{ form.account_text|accounting_default }}</span>
<span id="accounting-recurring-{{ expense_income }}-{{ item_index }}-name-text" class="d-block">{{ form.name.data|accounting_default }}</span>
<span id="accounting-recurring-{{ expense_income }}-{{ item_index }}-description-template-text" class="d-block small">{{ form.description_template.data|accounting_default }}</span>
</button>
<div id="accounting-recurring-{{ expense_income }}-{{ item_index }}-error" class="invalid-feedback">{% if form.all_errors %}{{ form.all_errors[0] }}{% endif %}</div>
</div>
@@ -36,10 +36,10 @@ First written: 2023/3/22
</div>
<div class="mb-3">
<div id="accounting-recurring-item-editor-{{ expense_income }}-account-control" class="form-control accounting-clickable accounting-material-text-field" data-bs-toggle="modal" data-bs-target="#accounting-recurring-accounting-selector-{{ expense_income }}-modal">
<label class="form-label" for="accounting-recurring-item-editor-{{ expense_income }}-account">{{ A_("Account") }}</label>
<div id="accounting-recurring-item-editor-{{ expense_income }}-account"></div>
</div>
<button id="accounting-recurring-item-editor-{{ expense_income }}-account-control" class="form-control text-start accounting-material-text-field" type="button" data-bs-toggle="modal" data-bs-target="#accounting-recurring-accounting-selector-{{ expense_income }}-modal">
<span class="form-label">{{ A_("Account") }}</span>
<span id="accounting-recurring-item-editor-{{ expense_income }}-account"></span>
</button>
<div id="accounting-recurring-item-editor-{{ expense_income }}-account-error" class="invalid-feedback"></div>
</div>
@@ -59,10 +59,10 @@ First written: 2023/3/8
</li>
{% endfor %}
<li>
<span class="dropdown-item {% if report.report_chooser.is_search %} active {% endif %} accounting-clickable" data-bs-toggle="modal" data-bs-target="#accounting-search-modal">
<button class="dropdown-item {% if report.report_chooser.is_search %} active {% endif %}" type="button" data-bs-toggle="modal" data-bs-target="#accounting-search-modal">
<i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i>
{{ A_("Search") }}
</span>
</button>
</li>
</ul>
</div>