aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/templates/dashboard/post_form.html
diff options
context:
space:
mode:
authorgrm <grm@eyesin.space>2026-09-15 23:17:17 +0300
committergrm <grm@eyesin.space>2026-09-15 23:17:17 +0300
commit628dcb814ece6335667e2b719049728aa161d8c9 (patch)
tree8fa4654771bee0166286b32fc123beec892870bb /internal/web/templates/dashboard/post_form.html
parent2c85ca1a46ddf4652f8fffc53d6bcfbe32b2b4ff (diff)
downloadblogspace-628dcb814ece6335667e2b719049728aa161d8c9.tar.gz
blogspace-628dcb814ece6335667e2b719049728aa161d8c9.tar.bz2
blogspace-628dcb814ece6335667e2b719049728aa161d8c9.zip
Make the post form's tag input a box with a folded list of chips
A checkbox per existing tag stops working once a blog has dozens of them. The form is now one comma-separated box, prefilled with the post's tags, and the blog's tags sit folded under it as chips; a small script toggles a clicked chip in the box, and without it the chips are a plain list to copy from. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal/web/templates/dashboard/post_form.html')
-rw-r--r--internal/web/templates/dashboard/post_form.html26
1 files changed, 22 insertions, 4 deletions
diff --git a/internal/web/templates/dashboard/post_form.html b/internal/web/templates/dashboard/post_form.html
index fd47615..ab05b34 100644
--- a/internal/web/templates/dashboard/post_form.html
+++ b/internal/web/templates/dashboard/post_form.html
@@ -14,11 +14,29 @@
<label>{{t "Date"}}<br>
<input type="datetime-local" name="posted_at" value="{{.Data.post.CreatedAt.Format "2006-01-02T15:04"}}" placeholder="YYYY-MM-DD HH:MM"></label>
</div>
- {{if .Data.allTags}}<p class="lbl">{{t "Tags"}}</p>
- <div class="tagpick">{{range .Data.allTags}}<label class="check"><input type="checkbox" name="tag" value="{{.Name}}"{{if index $.Data.tagged .Slug}} checked{{end}}> {{.Name}}</label>{{end}}</div>{{end}}
- <label>{{if .Data.allTags}}{{t "New tags"}}{{else}}{{t "Tags"}}{{end}} <span class="muted">({{t "comma-separated"}})</span><br>
- <input name="new_tags" value="{{.Data.newTags}}" maxlength="900" placeholder="{{t "go, tomatoes, recipes"}}"></label>
+ <label for="post-tags">{{t "Tags"}} <span class="muted">({{t "comma-separated"}})</span><br>
+ <input id="post-tags" name="tags" value="{{.Data.tagsText}}" maxlength="900" placeholder="{{t "go, tomatoes, recipes"}}"></label>
+ {{if .Data.allTags}}<details class="tagref"><summary>{{tf "Your tags (%d)" (len .Data.allTags)}}</summary>
+ <p class="chips">{{range .Data.allTags}}<span class="chip" data-tag="{{.Name}}">{{.Name}}</span> {{end}}</p>
+ </details>{{end}}
<p class="muted small">{{t "Tags on hidden posts are not shown on the blog; a tag nobody uses disappears."}}</p>
+ <script>
+ // The chips add or remove their tag in the box; without JS they are a plain list to copy from.
+ (function () {
+ var box = document.getElementById('post-tags'), chips = document.querySelectorAll('.chip');
+ if (!box || !chips.length) return;
+ function list() { return box.value.split(',').map(function (s) { return s.trim(); }).filter(Boolean); }
+ function has(l, t) { t = t.toLowerCase(); return l.some(function (x) { return x.toLowerCase() === t; }); }
+ function mark() { var l = list(); for (var i = 0; i < chips.length; i++) chips[i].className = has(l, chips[i].getAttribute('data-tag')) ? 'chip on' : 'chip'; }
+ for (var i = 0; i < chips.length; i++) chips[i].onclick = function () {
+ var t = this.getAttribute('data-tag'), l = list();
+ l = has(l, t) ? l.filter(function (x) { return x.toLowerCase() !== t.toLowerCase(); }) : l.concat([t]);
+ box.value = l.join(', '); mark();
+ };
+ box.addEventListener('input', mark);
+ document.querySelector('.tagref').className += ' live'; mark();
+ })();
+ </script>
<label for="ed-body">{{t "Content"}} <span class="muted">(Markdown)</span></label>
{{template "editor" (dict "name" "body" "value" .Data.post.BodyMD "rows" 24 "tall" true "upload" (print "/b/" .Blog.Subdomain "/files/upload") "preview" (print "/b/" .Blog.Subdomain "/preview") "csrf" .CSRF)}}
<label class="check"><input type="checkbox" name="published"{{if .Data.post.Published}} checked{{end}}> {{t "Visible on the blog"}}</label>