Rewrote the JavaScript AccountSelector to store the page elements in the object.

This commit is contained in:
依瑪貓 2023-03-10 12:51:37 +08:00
parent b45986ecfc
commit f2c184f769

View File

@ -45,6 +45,42 @@ class AccountSelector {
*/ */
#prefix; #prefix;
/**
* The button to clear the account
* @type {HTMLButtonElement}
*/
#clearButton
/**
* The query input
* @type {HTMLInputElement}
*/
#query;
/**
* The error message when the query has no result
* @type {HTMLParagraphElement}
*/
#queryNoResult;
/**
* The option list
* @type {HTMLUListElement}
*/
#optionList;
/**
* The options
* @type {HTMLLIElement[]}
*/
#options;
/**
* The more item to show all accounts
* @type {HTMLLIElement}
*/
#more;
/** /**
* Constructs an account selector. * Constructs an account selector.
* *
@ -53,41 +89,34 @@ class AccountSelector {
constructor(modal) { constructor(modal) {
this.#entryType = modal.dataset.entryType; this.#entryType = modal.dataset.entryType;
this.#prefix = "accounting-account-selector-" + modal.dataset.entryType; this.#prefix = "accounting-account-selector-" + modal.dataset.entryType;
const formAccountControl = document.getElementById("accounting-entry-form-account-control"); this.#query = document.getElementById(this.#prefix + "-query");
const formAccount = document.getElementById("accounting-entry-form-account"); this.#queryNoResult = document.getElementById(this.#prefix + "-option-no-result");
const more = document.getElementById(this.#prefix + "-more"); this.#optionList = document.getElementById(this.#prefix + "-option-list");
const btnClear = document.getElementById(this.#prefix + "-btn-clear"); // noinspection JSValidateTypes
const options = Array.from(document.getElementsByClassName(this.#prefix + "-option")); this.#options = Array.from(document.getElementsByClassName(this.#prefix + "-option"));
more.onclick = () => { this.#more = document.getElementById(this.#prefix + "-more");
more.classList.add("d-none"); this.#clearButton = document.getElementById(this.#prefix + "-btn-clear");
this.#more.onclick = () => {
this.#more.classList.add("d-none");
this.#filterAccountOptions(); this.#filterAccountOptions();
}; };
this.#initializeAccountQuery(); this.#clearButton.onclick = () => {
btnClear.onclick = () => { AccountSelector.#formAccountControl.classList.remove("accounting-not-empty");
formAccountControl.classList.remove("accounting-not-empty"); AccountSelector.#formAccount.innerText = "";
formAccount.innerText = ""; AccountSelector.#formAccount.dataset.code = "";
formAccount.dataset.code = ""; AccountSelector.#formAccount.dataset.text = "";
formAccount.dataset.text = "";
validateJournalEntryAccount(); validateJournalEntryAccount();
}; };
for (const option of options) { for (const option of this.#options) {
option.onclick = () => { option.onclick = () => {
formAccountControl.classList.add("accounting-not-empty"); AccountSelector.#formAccountControl.classList.add("accounting-not-empty");
formAccount.innerText = option.dataset.content; AccountSelector.#formAccount.innerText = option.dataset.content;
formAccount.dataset.code = option.dataset.code; AccountSelector.#formAccount.dataset.code = option.dataset.code;
formAccount.dataset.text = option.dataset.content; AccountSelector.#formAccount.dataset.text = option.dataset.content;
validateJournalEntryAccount(); validateJournalEntryAccount();
}; };
} }
} this.#query.addEventListener("input", () => {
/**
* Initializes the query on the account options.
*
*/
#initializeAccountQuery() {
const query = document.getElementById(this.#prefix + "-query");
query.addEventListener("input", () => {
this.#filterAccountOptions(); this.#filterAccountOptions();
}); });
} }
@ -97,18 +126,13 @@ class AccountSelector {
* *
*/ */
#filterAccountOptions() { #filterAccountOptions() {
const query = document.getElementById(this.#prefix + "-query"); if (this.#optionList === null) {
const optionList = document.getElementById(this.#prefix + "-option-list");
if (optionList === null) {
console.log(this.#prefix + "-option-list"); console.log(this.#prefix + "-option-list");
} }
const options = Array.from(document.getElementsByClassName(this.#prefix + "-option"));
const more = document.getElementById(this.#prefix + "-more");
const queryNoResult = document.getElementById(this.#prefix + "-option-no-result");
const codesInUse = this.#getAccountCodeUsedInForm(); const codesInUse = this.#getAccountCodeUsedInForm();
let shouldAnyShow = false; let shouldAnyShow = false;
for (const option of options) { for (const option of this.#options) {
const shouldShow = this.#shouldAccountOptionShow(option, more, codesInUse, query); const shouldShow = this.#shouldAccountOptionShow(option, this.#more, codesInUse, this.#query);
if (shouldShow) { if (shouldShow) {
option.classList.remove("d-none"); option.classList.remove("d-none");
shouldAnyShow = true; shouldAnyShow = true;
@ -116,12 +140,12 @@ class AccountSelector {
option.classList.add("d-none"); option.classList.add("d-none");
} }
} }
if (!shouldAnyShow && more.classList.contains("d-none")) { if (!shouldAnyShow && this.#more.classList.contains("d-none")) {
optionList.classList.add("d-none"); this.#optionList.classList.add("d-none");
queryNoResult.classList.remove("d-none"); this.#queryNoResult.classList.remove("d-none");
} else { } else {
optionList.classList.remove("d-none"); this.#optionList.classList.remove("d-none");
queryNoResult.classList.add("d-none"); this.#queryNoResult.classList.add("d-none");
} }
} }
@ -132,8 +156,7 @@ class AccountSelector {
*/ */
#getAccountCodeUsedInForm() { #getAccountCodeUsedInForm() {
const accountCodes = Array.from(document.getElementsByClassName("accounting-" + this.#prefix + "-account-code")); const accountCodes = Array.from(document.getElementsByClassName("accounting-" + this.#prefix + "-account-code"));
const formAccount = document.getElementById("accounting-entry-form-account"); const inUse = [AccountSelector.#formAccount.dataset.code];
const inUse = [formAccount.dataset.code];
for (const accountCode of accountCodes) { for (const accountCode of accountCodes) {
inUse.push(accountCode.value); inUse.push(accountCode.value);
} }
@ -172,33 +195,28 @@ class AccountSelector {
} }
/** /**
* Initializes the account selector when it is shown. * The callback when the account selector is shown.
* *
*/ */
initShow() { #onOpen() {
const formAccount = document.getElementById("accounting-entry-form-account"); this.#query.value = "";
const query = document.getElementById(this.#prefix + "-query") this.#more.classList.remove("d-none");
const more = document.getElementById(this.#prefix + "-more");
const options = Array.from(document.getElementsByClassName(this.#prefix + "-option"));
const btnClear = document.getElementById(this.#prefix + "-btn-clear");
query.value = "";
more.classList.remove("d-none");
this.#filterAccountOptions(); this.#filterAccountOptions();
for (const option of options) { for (const option of this.#options) {
if (option.dataset.code === formAccount.dataset.code) { if (option.dataset.code === AccountSelector.#formAccount.dataset.code) {
option.classList.add("active"); option.classList.add("active");
} else { } else {
option.classList.remove("active"); option.classList.remove("active");
} }
} }
if (formAccount.dataset.code === "") { if (AccountSelector.#formAccount.dataset.code === "") {
btnClear.classList.add("btn-secondary"); this.#clearButton.classList.add("btn-secondary");
btnClear.classList.remove("btn-danger"); this.#clearButton.classList.remove("btn-danger");
btnClear.disabled = true; this.#clearButton.disabled = true;
} else { } else {
btnClear.classList.add("btn-danger"); this.#clearButton.classList.add("btn-danger");
btnClear.classList.remove("btn-secondary"); this.#clearButton.classList.remove("btn-secondary");
btnClear.disabled = false; this.#clearButton.disabled = false;
} }
} }
@ -208,11 +226,32 @@ class AccountSelector {
*/ */
static #selectors = {} static #selectors = {}
/**
* The journal entry form.
* @type {HTMLFormElement}
*/
static #entryForm;
/**
* The control of the account on the journal entry form
* @type {HTMLDivElement}
*/
static #formAccountControl;
/**
* The account on the journal entry form
* @type {HTMLDivElement}
*/
static #formAccount;
/** /**
* Initializes the account selectors. * Initializes the account selectors.
* *
*/ */
static initialize() { static initialize() {
this.#entryForm = document.getElementById("accounting-entry-form");
this.#formAccountControl = document.getElementById("accounting-entry-form-account-control");
this.#formAccount = document.getElementById("accounting-entry-form-account");
const modals = Array.from(document.getElementsByClassName("accounting-account-selector-modal")); const modals = Array.from(document.getElementsByClassName("accounting-account-selector-modal"));
for (const modal of modals) { for (const modal of modals) {
const selector = new AccountSelector(modal); const selector = new AccountSelector(modal);
@ -226,9 +265,7 @@ class AccountSelector {
* *
*/ */
static #initializeTransactionForm() { static #initializeTransactionForm() {
const entryForm = document.getElementById("accounting-entry-form"); this.#formAccountControl.onclick = () => this.#selectors[this.#entryForm.dataset.entryType].#onOpen();
const formAccountControl = document.getElementById("accounting-entry-form-account-control");
formAccountControl.onclick = () => this.#selectors[entryForm.dataset.entryType].initShow();
} }
/** /**
@ -236,8 +273,6 @@ class AccountSelector {
*x *x
*/ */
static initializeJournalEntryForm() { static initializeJournalEntryForm() {
const entryForm = document.getElementById("accounting-entry-form"); this.#formAccountControl.dataset.bsTarget = "#accounting-account-selector-" + this.#entryForm.dataset.entryType + "-modal";
const formAccountControl = document.getElementById("accounting-entry-form-account-control");
formAccountControl.dataset.bsTarget = "#accounting-account-selector-" + entryForm.dataset.entryType + "-modal";
} }
} }