diff options
| author | grm <grm@eyesin.space> | 2026-09-15 23:17:17 +0300 |
|---|---|---|
| committer | grm <grm@eyesin.space> | 2026-09-15 23:17:17 +0300 |
| commit | 628dcb814ece6335667e2b719049728aa161d8c9 (patch) | |
| tree | 8fa4654771bee0166286b32fc123beec892870bb /internal/web/templates/dashboard/post_form.html | |
| parent | 2c85ca1a46ddf4652f8fffc53d6bcfbe32b2b4ff (diff) | |
| download | blogspace-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.html | 26 |
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> |
