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 "main"}}
<div>
<style>
li:has(> input[type="checkbox"]) {
padding-top: 0.1em;
padding-bottom: 0.1em;
cursor: default;
}
</style>
<div id="noteContent">
{{.note.BodyRendered}}
</div>
<div class="d-flex justify-content-between">
@ -77,17 +84,27 @@
{{end}}
<script>
let checkBoxes = document.querySelectorAll('input[type=checkbox]')
for (const i in checkBoxes) {
let checkBoxes = document.querySelectorAll('input[type=checkbox]');
let noteContentWrapper = document.querySelector('#noteContent');
console.log(checkBoxes.keys())
for (const i of checkBoxes.keys()) {
let box = checkBoxes[i]
let parent = box.parentNode
box.disabled = false
box.onchange = function(event) {
let form = new FormData()
form.append("box", i)
box.onclick = function(event) {
return false;
}
parent.onclick = function(event) {
let form = new FormData();
form.append("box", i);
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)
}
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) {
boxesFound := 0
@ -358,6 +362,8 @@ func (t *toggleCheckboxTransformer) Transform(node *ast.Document, reader text.Re
}
box.IsChecked = !box.IsChecked
t.boxToggled = true
t.boxChecked = box.IsChecked
return ast.WalkStop, nil
})
}
@ -380,8 +386,8 @@ func renderTaskCheckBox(writer util.BufWriter, source []byte, node ast.Node, ent
return ast.WalkContinue, err
}
func (n *Note) ToggleBox(nthBox int) {
checkboxTransformer := toggleCheckboxTransformer{nthBox: nthBox}
func (n *Note) ToggleBox(nthBox int) (bool, bool) {
checkboxTransformer := toggleCheckboxTransformer{nthBox: nthBox, boxToggled: false}
transformer := util.Prioritized(&checkboxTransformer, 0)
renderer := markdown.NewRenderer()
@ -397,6 +403,8 @@ func (n *Note) ToggleBox(nthBox int) {
md.Convert(n.Body, &buf)
n.Body = buf.Bytes()
n.Save()
return checkboxTransformer.boxToggled, checkboxTransformer.boxChecked
}
func (n *Note) HasTag(tag string) bool {

View file

@ -1,6 +1,7 @@
package views
import (
"encoding/json"
"log"
"net/http"
"strconv"
@ -181,18 +182,25 @@ func togglebox(w http.ResponseWriter, r *http.Request) {
nthBox, err := strconv.Atoi(r.FormValue("box"))
if err != nil {
log.Fatal("You fucked up boy")
http.Error(w, "Box not provided as numeric value", 400)
return
}
note, ok := notes.Notes.GetOne(user, uid)
if !ok {
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": uid}), http.StatusFound)
http.Error(w, "Note not found", 404)
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 {