From: Christian Heller Date: Tue, 28 Jan 2025 14:29:36 +0000 (+0100) Subject: Improve structured-editing view. X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/%7B%7B%20web_path%20%7D%7D/static/do_todos?a=commitdiff_plain;h=454445ee9fd03c96e8b43074434cf5422ecd09e9;p=plomledger Improve structured-editing view. --- diff --git a/templates/_base.tmpl b/templates/_base.tmpl index af5070c..bc15e6b 100644 --- a/templates/_base.tmpl +++ b/templates/_base.tmpl @@ -10,7 +10,8 @@ body { background-color: white; font-family: sans-serif; } tr.alternating:nth-child(odd) { background-color: #dcdcdc; } tr.alternating:nth-child(even) { background-color: #ffffff; } -td { text-align: left; vertical-align: top; } +td { margin: 0; padding: 0; text-align: left; vertical-align: top; } +input { background-color: transparent; } span.warning, table.warning tbody tr td, tr.warning td { background-color: #ff8888; } {% block css %}{% endblock %} diff --git a/templates/edit_structured.tmpl b/templates/edit_structured.tmpl index 0e510ae..f85a59d 100644 --- a/templates/edit_structured.tmpl +++ b/templates/edit_structured.tmpl @@ -4,6 +4,9 @@ {% block css %} {{ macros.css_td_money() }} {{ macros.css_errors() }} +input.date_input, input.number_input { font-family: monospace; } +input.number_input { text-align: right; } +input.date_input { margin-right: 0.1em; } {% endblock %} @@ -33,59 +36,78 @@ function update_form() { const dat_line = dat_lines[i]; const tr = document.createElement("tr"); table.appendChild(tr); - function add_input(name, value, colspan=1, placeholder='') { + function setup_input_td(tr, colspan) { const td = add_td(tr, colspan); + if (dat_line.error) { td.classList.add("invalid"); }; + return td; + } + function add_input(td, name, value, size) { const input = document.createElement("input"); td.appendChild(input); input.name = `line_${i}_${name}` input.value = value.trim(); - input.placeholder = placeholder; + input.size = size; input.oninput = taint; - if (dat_line.error) { - td.classList.add("invalid"); - } + return input; + } + function add_td_input(name, value, size=20, colspan=1) { + return add_input(setup_input_td(tr, colspan), name, value, size); } if (dat_line.is_intro) { - add_input('date', dat_line.booking_line.date) - add_input('target', dat_line.booking_line.target, 2) - } else if (!dat_line.error) { - add_input('account', dat_line.booking_line.account); - add_input('amount', dat_line.booking_line.amount == 'None' ? '' : dat_line.booking_line.amount); - add_input('currency', dat_line.booking_line.currency, 1, '€'); + const td = setup_input_td(tr, 3); + const date_input = add_input(td, 'date', dat_line.booking_line.date, 10) + date_input.classList.add('date_input'); + add_input(td, 'target', dat_line.booking_line.target, 35) + } else if (!dat_line.error) { // i.e. valid TransferLine + add_td_input('account', dat_line.booking_line.account, 30); + // not using input[type=number] cuz no minimal step size, therefore regex test instead + const amt_input = add_td_input('amount', dat_line.booking_line.amount == 'None' ? '' : dat_line.booking_line.amount, 12); + amt_input.pattern = '^[0-9]+(\.[0-9]+)?$'; + amt_input.classList.add("number_input"); + // ensure integer amounts at least line up with double-digit decimals + if (amt_input.value.match(/^[0-9]+$/)) { amt_input.value += '.00'; } + // imply that POST handler will set '€' currency if unset, but amount set + const curr_input = add_td_input('currency', dat_line.booking_line.currency, 3); + curr_input.placeholder = '€'; } else { - add_input('error', dat_line.code, 3) + add_td_input('error', dat_line.code, 20, 3) } - add_input('comment', dat_line.comment); + add_td_input('comment', dat_line.comment, 40); + // add action buttons, with "delete" after some safety distance const td_btns = add_td(tr); - add_button(td_btns, 'delete', false, function() { - dat_lines.splice(i, 1); - }); - add_button(td_btns, 'move up', i > 1 ? false : true, function() { + add_button(td_btns, '^', i > 1 ? false : true, function() { const prev_line = dat_lines[i-1]; dat_lines.splice(i-1, 1); dat_lines.splice(i, 0, prev_line); }); - add_button(td_btns, 'move down', i+1 < dat_lines.length ? false : true, function() { + add_button(td_btns, 'v', i+1 < dat_lines.length ? false : true, function() { const next_line = dat_lines[i]; dat_lines.splice(i, 1); dat_lines.splice(i+1, 0, next_line); }); + td_btns.appendChild(document.createTextNode(' · · · ')) + add_button(td_btns, 'delete', false, function() { dat_lines.splice(i, 1); }); + // add error explanation row if necessary if (dat_line.error) { const tr = document.createElement("tr"); table.appendChild(tr); const td = add_td(tr, 3); tr.appendChild(document.createElement("td")); td.textContent = dat_line.error; - td.classList.add("invalid"); tr.classList.add("warning"); } } + // add "add line" row const tr = document.createElement("tr"); table.appendChild(tr); const td = add_td(tr, 5); add_button(td, 'add line', false, function() { - new_line = {error: '', comment: '', booking_line: {account: '', amount: '', currency: ''}}; - dat_lines.push(new_line); + new_line = {error: '', comment: '', booking_line: {account: '', amount: '', currency: ''}}; + dat_lines.push(new_line); + }); + // make all rows alternate background color for better readability + Array.from(table.rows).forEach((tr) => { + tr.classList.add('alternating'); }); }