Implemented the incremental search (search-as-you-type) in the base account selector of the account form.
This commit is contained in:
		| @@ -64,6 +64,14 @@ class BaseAccount(db.Model): | ||||
|                 return l10n.title | ||||
|         return self.title_l10n | ||||
|  | ||||
|     @property | ||||
|     def query_values(self) -> list[str]: | ||||
|         """Returns the values to be queried. | ||||
|  | ||||
|         :return: The values to be queried. | ||||
|         """ | ||||
|         return [self.code, self.title_l10n] + [x.title for x in self.l10n] | ||||
|  | ||||
|  | ||||
| class BaseAccountL10n(db.Model): | ||||
|     """A localized base account title.""" | ||||
|   | ||||
| @@ -79,6 +79,54 @@ function initializeBaseAccountSelector() { | ||||
|         validateBase(); | ||||
|         bootstrap.Modal.getInstance(selector).hide(); | ||||
|     } | ||||
|     initializeBaseAccountQuery(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Initializes the query on the base account options. | ||||
|  * | ||||
|  * @private | ||||
|  */ | ||||
| function initializeBaseAccountQuery() { | ||||
|     const query = document.getElementById("accounting-base-selector-query"); | ||||
|     const optionList = document.getElementById("accounting-base-option-list"); | ||||
|     const options = Array.from(document.getElementsByClassName("accounting-base-option")); | ||||
|     const queryNoResult = document.getElementById("accounting-base-option-no-result"); | ||||
|     query.addEventListener("input", function () { | ||||
|         console.log(query.value); | ||||
|         if (query.value === "") { | ||||
|             options.forEach(function (option) { | ||||
|                 option.classList.remove("d-none"); | ||||
|             }); | ||||
|             optionList.classList.remove("d-none"); | ||||
|             queryNoResult.classList.add("d-none"); | ||||
|             return | ||||
|         } | ||||
|         let hasAnyMatched = false; | ||||
|         options.forEach(function (option) { | ||||
|             const queryValues = JSON.parse(option.dataset.queryValues); | ||||
|             let isMatched = false; | ||||
|             for (let i = 0; i < queryValues.length; i++) { | ||||
|                 if (queryValues[i].includes(query.value)) { | ||||
|                     isMatched = true; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if (isMatched) { | ||||
|                 option.classList.remove("d-none"); | ||||
|                 hasAnyMatched = true; | ||||
|             } else { | ||||
|                 option.classList.add("d-none"); | ||||
|             } | ||||
|         }); | ||||
|         if (!hasAnyMatched) { | ||||
|             optionList.classList.add("d-none"); | ||||
|             queryNoResult.classList.remove("d-none"); | ||||
|         } else { | ||||
|             optionList.classList.remove("d-none"); | ||||
|             queryNoResult.classList.add("d-none"); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -99,13 +99,14 @@ First written: 2023/2/1 | ||||
|           </label> | ||||
|         </div> | ||||
|  | ||||
|         <ul class="list-group accounting-selector-list"> | ||||
|         <ul id="accounting-base-option-list" class="list-group accounting-selector-list"> | ||||
|           {% for base in form.base_options %} | ||||
|           <li id="accounting-base-option-{{ base.code }}" class="list-group-item accounting-base-option accounting-clickable" data-code="{{ base.code }}" data-content="{{ base }}"> | ||||
|           <li id="accounting-base-option-{{ base.code }}" class="list-group-item accounting-base-option accounting-clickable" data-code="{{ base.code }}" data-content="{{ base }}" data-query-values="{{ base.query_values|tojson|forceescape }}"> | ||||
|             {{ base }} | ||||
|           </li> | ||||
|           {% endfor %} | ||||
|         </ul> | ||||
|         <p id="accounting-base-option-no-result" class="d-none">{{ A_("There is no data.") }}</p> | ||||
|       </div> | ||||
|       <div class="modal-footer"> | ||||
|         <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ A_("Cancel") }}</button> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user