Make checking boxes not require full page reload

This commit is contained in:
Maximilian Friedersdorff 2025-11-13 14:44:24 +00:00
parent cb24ab18c5
commit 1772e57ee8
3 changed files with 46 additions and 13 deletions

View file

@ -1,6 +1,13 @@
{{define "title"}}{{.note.Title}}{{end}} {{define "title"}}{{.note.Title}}{{end}}
{{define "main"}} {{define "main"}}
<div> <style>
li:has(> input[type="checkbox"]) {
padding-top: 0.1em;
padding-bottom: 0.1em;
cursor: default;
}
</style>
<div id="noteContent">
{{.note.BodyRendered}} {{.note.BodyRendered}}
</div> </div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -77,17 +84,27 @@
{{end}} {{end}}
<script> <script>
let checkBoxes = document.querySelectorAll('input[type=checkbox]') let checkBoxes = document.querySelectorAll('input[type=checkbox]');
for (const i in checkBoxes) { let noteContentWrapper = document.querySelector('#noteContent');
console.log(checkBoxes.keys())
for (const i of checkBoxes.keys()) {
let box = checkBoxes[i] let box = checkBoxes[i]
let parent = box.parentNode
box.disabled = false box.disabled = false
box.onchange = function(event) { box.onclick = function(event) {
let form = new FormData() return false;
form.append("box", i) }
parent.onclick = function(event) {
let form = new FormData();
form.append("box", i);
fetch("togglebox/", {method: "POST", body: form}).then((response) => { fetch("togglebox/", {method: "POST", body: form}).then((response) => {
location.reload(); return response.json();
}).then((json) => {
box.checked = json.checked;
}) })
} }
} }

View file

@ -336,7 +336,11 @@ func DeleteNote(uid string) error {
return os.Remove(filename) return os.Remove(filename)
} }
type toggleCheckboxTransformer struct{ nthBox int } type toggleCheckboxTransformer struct {
nthBox int
boxToggled bool
boxChecked bool
}
func (t *toggleCheckboxTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) { func (t *toggleCheckboxTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
boxesFound := 0 boxesFound := 0
@ -358,6 +362,8 @@ func (t *toggleCheckboxTransformer) Transform(node *ast.Document, reader text.Re
} }
box.IsChecked = !box.IsChecked box.IsChecked = !box.IsChecked
t.boxToggled = true
t.boxChecked = box.IsChecked
return ast.WalkStop, nil return ast.WalkStop, nil
}) })
} }
@ -380,8 +386,8 @@ func renderTaskCheckBox(writer util.BufWriter, source []byte, node ast.Node, ent
return ast.WalkContinue, err return ast.WalkContinue, err
} }
func (n *Note) ToggleBox(nthBox int) { func (n *Note) ToggleBox(nthBox int) (bool, bool) {
checkboxTransformer := toggleCheckboxTransformer{nthBox: nthBox} checkboxTransformer := toggleCheckboxTransformer{nthBox: nthBox, boxToggled: false}
transformer := util.Prioritized(&checkboxTransformer, 0) transformer := util.Prioritized(&checkboxTransformer, 0)
renderer := markdown.NewRenderer() renderer := markdown.NewRenderer()
@ -397,6 +403,8 @@ func (n *Note) ToggleBox(nthBox int) {
md.Convert(n.Body, &buf) md.Convert(n.Body, &buf)
n.Body = buf.Bytes() n.Body = buf.Bytes()
n.Save() n.Save()
return checkboxTransformer.boxToggled, checkboxTransformer.boxChecked
} }
func (n *Note) HasTag(tag string) bool { func (n *Note) HasTag(tag string) bool {

View file

@ -1,6 +1,7 @@
package views package views
import ( import (
"encoding/json"
"log" "log"
"net/http" "net/http"
"strconv" "strconv"
@ -181,18 +182,25 @@ func togglebox(w http.ResponseWriter, r *http.Request) {
nthBox, err := strconv.Atoi(r.FormValue("box")) nthBox, err := strconv.Atoi(r.FormValue("box"))
if err != nil { if err != nil {
log.Fatal("You fucked up boy") log.Fatal("You fucked up boy")
http.Error(w, "Box not provided as numeric value", 400)
return return
} }
note, ok := notes.Notes.GetOne(user, uid) note, ok := notes.Notes.GetOne(user, uid)
if !ok { if !ok {
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": uid}), http.StatusFound) http.Error(w, "Note not found", 404)
return return
} }
note.ToggleBox(nthBox) toggled, checked := note.ToggleBox(nthBox)
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": note.Uid}), http.StatusFound) if !toggled {
http.Error(w, "Failed to toggle box", 500)
} else {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]any{"checked": checked})
}
} }
type titleAndURL struct { type titleAndURL struct {