home · contact · privacy
Force user to apply or revert changes in edit view before switching its display mode.
authorChristian Heller <c.heller@plomlompom.de>
Mon, 27 Jan 2025 00:06:34 +0000 (01:06 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Mon, 27 Jan 2025 00:06:34 +0000 (01:06 +0100)
ledger.py
templates/_macros.tmpl
templates/edit_raw.tmpl
templates/edit_structured.tmpl

index a3bc7af58b35f431007bcf5407a15ec2e87090ee..a998b974bd4f3a4a3db41b7b1cc96245efe36468 100755 (executable)
--- a/ledger.py
+++ b/ledger.py
@@ -245,45 +245,48 @@ class Handler(PlomHttpHandler):
         redir_path = Path('/')
         if self.pagename.startswith('edit_'):
             id_ = int(self.path_toks[2])
-            redir_path = Path('/').joinpath('booking').joinpath(str(id_))
+            redir_path = Path('/').joinpath(self.pagename).joinpath(str(id_))
         if self.pagename == 'file':
             if 'reload' in self.postvars.as_dict:
                 self.server.load()
             elif 'save' in self.postvars.as_dict:
                 self.server.save()
         elif self.pagename == 'edit_structured':
-            line_keys = self.postvars.keys_prefixed('line_')
-            lineno_to_inputs: dict[int, list[str]] = {}
-            for key in line_keys:
-                toks = key.split('_', maxsplit=2)
-                lineno = int(toks[1])
-                if lineno not in lineno_to_inputs:
-                    lineno_to_inputs[lineno] = []
-                lineno_to_inputs[lineno] += [toks[2]]
-            new_dat_lines = []
-            indent = '  '
-            for lineno, input_names in lineno_to_inputs.items():
-                data = ''
-                comment = self.postvars.first(f'line_{lineno}_comment')
-                for name in input_names:
-                    input_ = self.postvars.first(f'line_{lineno}_{name}')
-                    if name == 'date':
-                        data = input_
-                    elif name == 'target':
-                        data += f'  {input_}'
-                    elif name == 'error':
-                        data = f'{indent}{input_}'
-                    elif name == 'account':
-                        data = f'{indent}{input_}'
-                    elif name in {'amount', 'currency'}:
-                        data += f'  {input_}'
-                new_dat_lines += [
+            if self.postvars.first('apply'):
+                line_keys = self.postvars.keys_prefixed('line_')
+                lineno_to_inputs: dict[int, list[str]] = {}
+                for key in line_keys:
+                    toks = key.split('_', maxsplit=2)
+                    lineno = int(toks[1])
+                    if lineno not in lineno_to_inputs:
+                        lineno_to_inputs[lineno] = []
+                    lineno_to_inputs[lineno] += [toks[2]]
+                new_dat_lines = []
+                indent = '  '
+                for lineno, input_names in lineno_to_inputs.items():
+                    data = ''
+                    comment = self.postvars.first(f'line_{lineno}_comment')
+                    for name in input_names:
+                        input_ = self.postvars.first(f'line_{lineno}_{name}')
+                        if name == 'date':
+                            data = input_
+                        elif name == 'target':
+                            data += f'  {input_}'
+                        elif name == 'error':
+                            data = f'{indent}{input_}'
+                        elif name == 'account':
+                            data = f'{indent}{input_}'
+                        elif name in {'amount', 'currency'}:
+                            data += f'  {input_}'
+                    new_dat_lines += [
                         DatLine(f'{data} ; {comment}' if comment else data)]
-            self.server.rewrite_booking(id_, new_dat_lines)
+                self.server.rewrite_booking(id_, new_dat_lines)
         elif self.pagename == 'edit_raw':
-            new_dat_lines = [DatLine(line) for line
-                             in self.postvars.first('booking').splitlines()]
-            self.server.rewrite_booking(id_, new_dat_lines)
+            if self.postvars.first('apply'):
+                new_dat_lines = [
+                        DatLine(line) for line
+                        in self.postvars.first('booking').splitlines()]
+                self.server.rewrite_booking(id_, new_dat_lines)
         self.redirect(redir_path)
 
     def do_GET(self) -> None:
index dd45db6e8231d2f459f00b8735b5dee412059316..d09643bb1d510e5dc4a35bd1f10d053a0ed3eb24 100644 (file)
@@ -51,3 +51,26 @@ td.invalid, tr.warning td.invalid { background-color: #ff0000; }
 {% endfor %}
 </table>
 {% endmacro %}
+
+{% macro taint_js() %}
+function taint() {
+  const els = document.getElementsByClassName("enable_on_change");
+  for (let i = 0; i < els.length; i++) {
+    els[i].disabled = false;
+  }
+  const a = document.getElementById("switch_link");
+  const link_text = a.textContent;
+  const span = a.parentNode;
+  span.innerHTML = "";
+  const del = document.createElement("del");
+  span.appendChild(del);
+  del.textContent = link_text;
+}
+{% endmacro %}
+
+{% macro edit_bar(target, id) %}
+<input class="enable_on_change" type="submit" name="apply" value="apply" disabled />
+<input class="enable_on_change" type="submit" name="revert" value="revert" disabled />
+<span><a id="switch_link" href="/edit_{{target}}/{{id}}">switch to {{target}}</a></span>
+<hr />
+{% endmacro %}
index ad344a891411eb76a6983d92073e2a97a90836ba..6e3702ded7ef642d8c417bcaf8f224a693f71e94 100644 (file)
@@ -6,13 +6,17 @@
 {{ macros.css_errors() }}
 {% endblock %}
 
+
+{% block script %}
+{{ macros.taint_js() }}
+{% endblock %}
+
+
 {% block content %}
-<a href="/edit_structured/{{id}}">edit structured</a>
-<hr />
 <form action="/edit_raw/{{id}}" method="POST">
-<textarea name="booking" cols=100 rows=100>
+{{ macros.edit_bar("structured", id) }}
+<textarea name="booking" cols=100 rows=100 onchange="taint()">
 {% for dat_line in dat_lines %}{{ dat_line.raw }}
 {% endfor %}</textarea>
-<input type="submit" value="update" />
 </form>
 {% endblock %}
index af0c6348d499d6407a6560cb6b28b38eb9b44d6a..a3200886d43ceba14cb35c09ff0c114e555a32fd 100644 (file)
@@ -10,6 +10,8 @@
 {% block script %}
 var dat_lines = {{dat_lines|tojson|safe}};
 
+{{ macros.taint_js() }}
+
 function update_form() {
   const table = document.getElementById("dat_lines");
   table.innerHTML = "";
@@ -19,7 +21,7 @@ function update_form() {
     btn.textContent = text;
     btn.type = "button";  // otherwise will act as form submit
     btn.disabled = disable;
-    btn.onclick = function() {f(); update_form();};
+    btn.onclick = function() {f(); update_form(); taint(); };
   }
   function add_td(tr, colspan=1) {
     const td = document.createElement("td");
@@ -37,6 +39,7 @@ function update_form() {
       td.appendChild(input);
       input.name = `line_${i}_${name}`
       input.value = value.trim();
+      input.onchange = taint;
       if (dat_line.error) {
         td.classList.add("invalid");
       }
@@ -90,11 +93,9 @@ window.onload = update_form;
 
 
 {% block content %}
-<a href="/edit_raw/{{id}}">edit raw</a>
-<hr />
 <form action="/edit_structured/{{id}}" method="POST">
+{{ macros.edit_bar("raw", id) }}
 <table id="dat_lines">
 </table>
-<input type="submit" value="update" />
 </form>
 {% endblock %}