diff --git a/src/accounting/option/forms.py b/src/accounting/option/forms.py
index 84bd70f..04531b1 100644
--- a/src/accounting/option/forms.py
+++ b/src/accounting/option/forms.py
@@ -209,8 +209,26 @@ class RecurringForm(RecurringItemForm):
return (item.name.data, item.account_code.data,
item.description_template.data)
- return {"expense": [as_tuple(x.form) for x in self.expenses],
- "income": [as_tuple(x.form) for x in self.incomes]}
+ expenses: list[RecurringItemForm] = [x.form for x in self.expenses]
+ self.__sort_item_forms(expenses)
+ incomes: list[RecurringItemForm] = [x.form for x in self.incomes]
+ self.__sort_item_forms(incomes)
+ return {"expense": [as_tuple(x) for x in expenses],
+ "income": [as_tuple(x) for x in incomes]}
+
+ @staticmethod
+ def __sort_item_forms(forms: list[RecurringItemForm]) -> None:
+ """Sorts the recurring item sub-forms.
+
+ :param forms: The recurring item sub-forms.
+ :return: None.
+ """
+ ord_by_form: dict[RecurringItemForm, int] \
+ = {forms[i]: i for i in range(len(forms))}
+ recv_no: set[int] = {x.no.data for x in forms if x.no.data is not None}
+ missing_recv_no: int = 100 if len(recv_no) == 0 else max(recv_no) + 100
+ forms.sort(key=lambda x: (x.no.data or missing_recv_no,
+ ord_by_form.get(x)))
class OptionForm(FlaskForm):
diff --git a/src/accounting/static/js/option-form.js b/src/accounting/static/js/option-form.js
index 8ed397f..1397568 100644
--- a/src/accounting/static/js/option-form.js
+++ b/src/accounting/static/js/option-form.js
@@ -236,6 +236,7 @@ class RecurringExpenseIncomeSubForm {
this.#addButton = document.getElementById(this.#prefix + "-add");
this.#addButton.onclick = () => this.editor.onAddNew();
+ this.#initializeDragAndDropReordering();
}
/**
@@ -252,6 +253,8 @@ class RecurringExpenseIncomeSubForm {
const element = document.getElementById(this.#prefix + "-" + String(newIndex))
const item = new RecurringItemSubForm(this, element);
this.#items.push(item);
+ this.#initializeDragAndDropReordering();
+ this.validate();
return item;
}
@@ -265,6 +268,20 @@ class RecurringExpenseIncomeSubForm {
this.#items.splice(index, 1);
}
+ /**
+ * Initializes the drag and drop reordering on the recurring item sub-forms.
+ *
+ */
+ #initializeDragAndDropReordering() {
+ initializeDragAndDropReordering(this.#itemList, () => {
+ const itemId = Array.from(this.#itemList.children).map((item) => item.id);
+ this.#items.sort((a, b) => itemId.indexOf(a.element.id) - itemId.indexOf(b.element.id));
+ for (let i = 0; i < this.#items.length; i++) {
+ this.#items[i].no.value = String(i + 1);
+ }
+ });
+ }
+
/**
* Validates the form.
*
@@ -309,7 +326,7 @@ class RecurringItemSubForm {
* The element
* @type {HTMLLIElement}
*/
- #element;
+ element;
/**
* The item index
@@ -329,6 +346,12 @@ class RecurringItemSubForm {
*/
#error;
+ /**
+ * The number
+ * @type {HTMLInputElement}
+ */
+ no;
+
/**
* The name input
* @type {HTMLInputElement}
@@ -379,11 +402,12 @@ class RecurringItemSubForm {
*/
constructor(expenseIncomeSubForm, element) {
this.#expenseIncomeSubForm = expenseIncomeSubForm
- this.#element = element;
+ this.element = element;
this.itemIndex = parseInt(element.dataset.itemIndex);
const prefix = "accounting-recurring-" + expenseIncomeSubForm.expenseIncome + "-" + element.dataset.itemIndex;
this.#control = document.getElementById(prefix + "-control");
this.#error = document.getElementById(prefix + "-error");
+ this.no = document.getElementById(prefix + "-no");
this.#name = document.getElementById(prefix + "-name");
this.#nameText = document.getElementById(prefix + "-name-text");
this.#accountCode = document.getElementById(prefix + "-account-code");
@@ -394,7 +418,7 @@ class RecurringItemSubForm {
this.#control.onclick = () => this.#expenseIncomeSubForm.editor.onEdit(this);
this.deleteButton.onclick = () => {
- this.#element.parentElement.removeChild(this.#element);
+ this.element.parentElement.removeChild(this.element);
this.#expenseIncomeSubForm.deleteItem(this);
};
}
diff --git a/src/accounting/templates/accounting/option/form.html b/src/accounting/templates/accounting/option/form.html
index 7ae26a9..d3ca1d5 100644
--- a/src/accounting/templates/accounting/option/form.html
+++ b/src/accounting/templates/accounting/option/form.html
@@ -22,6 +22,7 @@ First written: 2023/3/22
{% extends "accounting/base.html" %}
{% block accounting_scripts %}
+
{% endblock %}