all repos — piggy @ c2a637dc976e428beb8360bd0f74f777ea984b36

Dead simple finance manager in Go, HTML and JS.

static/js/records-edit.js (view raw)

  1document.addEventListener('DOMContentLoaded', function () {
  2    handleID();
  3
  4    document.getElementById('save').addEventListener('click', submit);
  5    
  6    if (id === 0) {
  7        document.getElementById('delete').style.display = "none";
  8    } else {
  9        document.getElementById('delete').addEventListener('click', remove);
 10    }
 11});
 12
 13let id;
 14
 15async function handleID() {
 16    id = getQueryStringID();
 17    const record = id === 0 ? null : await getRecord(id);
 18    document.getElementById("main-container").appendChild(loadRecord(record));
 19}
 20
 21function loadRecord(record) {
 22    const div = document.createElement("div");
 23    div.setAttribute("data-type", "record");
 24    div.setAttribute("data-id", id);
 25    div.classList.add("record");
 26
 27    // record.type
 28    div.appendChild(newInputText("Type", record?.type, "record-type"));
 29
 30    // record.description
 31    div.appendChild(newInputText("Description", record?.description, "record-description"));
 32
 33    // record.done
 34    div.appendChild(newInputCheckbox("Done", record?.done, "record-done"));
 35
 36    // record.entries
 37    div.appendChild(loadEntries(record?.entries ?? [null, null], "record-entries"));
 38
 39    return div;
 40}
 41
 42function loadEntries(entries, name) {
 43    const div = document.createElement("div")
 44    div.className = name;
 45
 46    const newEntry = document.createElement("button");
 47    newEntry.innerText = "Add entry";
 48    newEntry.onclick = () => div.appendChild(loadEntry(null));
 49    div.appendChild(newEntry);
 50
 51    for (const entry of entries) {
 52        div.appendChild(loadEntry(entry));
 53    }
 54    return div;
 55}
 56
 57function loadEntry(entry) {
 58    const div = document.createElement("div");
 59    div.setAttribute("data-type", "entry");
 60    div.setAttribute("data-id", entry?.id ?? 0);
 61    div.classList.add("entry");
 62
 63    const deleteEntry = document.createElement("button");
 64    deleteEntry.innerText = "Delete entry";
 65    deleteEntry.onclick = () => div.remove();
 66    div.appendChild(deleteEntry);
 67
 68    // entry.bookmaker_id
 69    div.appendChild(newInputText("Bookmaker ID", entry?.bookmaker_id, "entry-bookmaker_id"))
 70
 71    // entry.account_id
 72    div.appendChild(newInputText("Account ID", entry?.account_id, "entry-account_id"))
 73
 74    // entry.amount
 75    div.appendChild(newInputText("Amount", entry?.amount, "entry-amount"))
 76
 77    // entry.refund
 78    div.appendChild(newInputText("Refund", entry?.refund, "entry-refund"))
 79
 80    // entry.bonus
 81    div.appendChild(newInputText("Bonus", entry?.bonus, "entry-bonus"))
 82
 83    // entry.commission
 84    div.appendChild(newInputText("Commission", entry?.commission, "entry-commission"))
 85
 86    // entry.sub_entries
 87    div.appendChild(loadSubEntries(entry?.sub_entries ?? [null], "entry-subentries"));
 88
 89    return div;
 90}
 91
 92function loadSubEntries(subEntries, name) {
 93    const div = document.createElement("div")
 94    div.className = name;
 95
 96    const newSubEntry = document.createElement("button");
 97    newSubEntry.innerText = "Add subentry";
 98    newSubEntry.onclick = () => div.appendChild(loadSubEntry(null));
 99    div.appendChild(newSubEntry);
100
101    for (const subEntry of subEntries) {
102        div.appendChild(loadSubEntry(subEntry));
103    }
104    return div;
105}
106
107function loadSubEntry(subEntry) {
108    const div = document.createElement("div");
109    div.setAttribute("data-type", "subentry");
110    div.setAttribute("data-id", subEntry?.id ?? 0);
111    div.classList.add("subentry");
112
113    const deleteSubEntry = document.createElement("button");
114    deleteSubEntry.innerText = "Delete subentry";
115    deleteSubEntry.onclick = () => div.remove();
116    div.appendChild(deleteSubEntry);
117
118    // subentry.description
119    div.appendChild(newInputText("Description", subEntry?.description, "subentry-description"));
120    
121    // subentry.odds
122    div.appendChild(newInputText("Odds", subEntry?.odds, "subentry-odds"))
123    
124    // subentry.won
125    div.appendChild(newInputCheckbox("Won", subEntry?.won, "subentry-won"));
126    
127    // subentry.date
128    div.appendChild(newInputText("Date", subEntry?.date, "subentry-date"));
129
130    return div;
131}
132
133function getInputValueFromNode(node, name) {
134    const element = node.getElementsByClassName(name)[0];
135    return element.type === "checkbox" ? element.checked : element.value;
136}
137
138function buildRecordObject() {
139    const node = document.getElementsByClassName("record")[0];
140    return {
141        id: +node.getAttribute("data-id"),
142        type: getInputValueFromNode(node, "record-type"),
143        description: getInputValueFromNode(node, "record-description"),
144        done: getInputValueFromNode(node, "record-done"),
145        entries: buildEntriesObject(node.getElementsByClassName("record-entries")[0]),
146    }
147}
148
149function buildEntriesObject(entriesNode) {
150    const entriesNodes = entriesNode.getElementsByClassName("entry");
151    
152    const result = [];
153    for (const node of entriesNodes) {
154        result.push({
155            id: +node.getAttribute("data-id"),
156            bookmaker_id: +getInputValueFromNode(node, "entry-bookmaker_id"),
157            account_id: +getInputValueFromNode(node, "entry-account_id"),
158            amount: +getInputValueFromNode(node, "entry-amount"),
159            refund: +getInputValueFromNode(node, "entry-refund"),
160            bonus: +getInputValueFromNode(node, "entry-bonus"),
161            commission: +getInputValueFromNode(node, "entry-commission"),
162            sub_entries: buildSubEntriesObject(node.getElementsByClassName("entry-subentries")[0]),
163        });
164    }
165    return result;
166}
167
168function buildSubEntriesObject(subEntriesNode) {
169    const subEntriesNodes = subEntriesNode.getElementsByClassName("subentry");
170    
171    const result = [];
172    for (const node of subEntriesNodes) {
173        result.push({
174            id: +node.getAttribute("data-id"),
175            description: getInputValueFromNode(node, "subentry-description"),
176            odds: +getInputValueFromNode(node, "subentry-odds"),
177            won: getInputValueFromNode(node, "subentry-won"),
178            date: getInputValueFromNode(node, "subentry-date"),
179        });
180    }
181    return result;
182}
183
184async function submit() {
185    if (await saveRecord(buildRecordObject())) {
186        location.href = "/records"
187    }
188}
189
190async function remove() {
191    if (await myConfirm(deleteRecord, id)) {
192        location.href = "/records"
193    }
194}