Update web/templates/entry_edit.html

This commit is contained in:
Joshua Laymon 2025-08-14 22:35:36 +00:00
parent ec0f92ae1b
commit e621670335

View File

@ -1,95 +1,113 @@
Absolutely—heres a complete entry_edit.html that matches your current edit layout and adds the same “autofill Talk Title from Talk Number” behavior you have on the newentry form. I also added a tiny convenience so if the title field contains just - or —, its treated as empty and will autofill.
{% extends "base.html" %} {% extends "base.html" %}
{% load static %}
{% block title %}Edit Entry #{{ entry.id }} - Illustrations DB{% endblock %}
{% block body_class %}themed-bg{% endblock %} {% block body_class %}themed-bg{% endblock %}
{% load static %}
{% block content %} {% block content %}
<div class="container"> <div class="page">
<h1 class="page-title">Edit Illustration</h1> <!-- Top bar -->
<p class="page-subtitle"> <div class="result-toolbar">
Update the details below. Subjects should be commaseparated; keep scriptures in standard abbreviations.
</p>
<form id="entry-edit-form" method="post" class="search-form card">
{% csrf_token %}
<div class="form-grid">
<div class="form-row">
<label>Subject</label>
{{ form.subject }}
{% if form.subject.errors %}<div class="err">{{ form.subject.errors|striptags }}</div>{% endif %}
</div>
<div class="form-row">
<label>Illustration</label>
{{ form.illustration }}
{% if form.illustration.errors %}<div class="err">{{ form.illustration.errors|striptags }}</div>{% endif %}
</div>
<div class="form-row">
<label>Application</label>
{{ form.application }}
{% if form.application.errors %}<div class="err">{{ form.application.errors|striptags }}</div>{% endif %}
</div>
<div class="form-row two">
<div>
<label>Scripture</label>
{{ form.scripture_raw }}
{% if form.scripture_raw.errors %}<div class="err">{{ form.scripture_raw.errors|striptags }}</div>{% endif %}
</div>
<div>
<label>Source</label>
{{ form.source }}
{% if form.source.errors %}<div class="err">{{ form.source.errors|striptags }}</div>{% endif %}
</div>
</div>
<div class="form-row two">
<div>
<label>Talk Title</label>
{{ form.talk_title }}
{% if form.talk_title.errors %}<div class="err">{{ form.talk_title.errors|striptags }}</div>{% endif %}
</div>
<div>
<label>Talk Number</label>
{{ form.talk_number }}
{% if form.talk_number.errors %}<div class="err">{{ form.talk_number.errors|striptags }}</div>{% endif %}
</div>
</div>
<div class="form-row two">
<div>
<label>Code</label>
{{ form.entry_code }}
{% if form.entry_code.errors %}<div class="err">{{ form.entry_code.errors|striptags }}</div>{% endif %}
</div>
<div>
<label>Dates</label>
<div class="two">
{{ form.date_added }} {{ form.date_edited }}
</div>
{% if form.date_added.errors %}<div class="err">{{ form.date_added.errors|striptags }}</div>{% endif %}
{% if form.date_edited.errors %}<div class="err">{{ form.date_edited.errors|striptags }}</div>{% endif %}
</div>
</div>
</div>
<div class="result-toolbar" style="margin-top:18px;">
<div class="rt-left"> <div class="rt-left">
<a class="btn" href="{% url 'entry_view' entry.id %}">← Back to Entry</a> <a class="btn btn-secondary" href="{% url 'entry_view' entry.id %}">← Back to Entry</a>
<span class="rt-count">Editing: #{{ entry.id }}</span>
</div> </div>
<div class="rt-right"> <div class="rt-right">
<a class="btn btn-secondary" href="{% url 'entry_view' entry.id %}">Cancel</a> <a class="btn" href="{% url 'entry_view' entry.id %}">Cancel</a>
<button class="btn btn-primary" type="submit">Save</button> <button form="entry-edit-form" class="btn btn-primary">Save</button>
</div> </div>
</div> </div>
<!-- Card -->
<div class="card entry-form modern-form">
<form id="entry-edit-form" method="post">
{% csrf_token %}
<div class="f-grid">
<div class="f-row">
<div class="f-label">Subject</div>
<div class="f-control">
{{ form.subject }}
</div>
</div>
<div class="f-row tall">
<div class="f-label">Illustration</div>
<div class="f-control">
{{ form.illustration }}
</div>
</div>
<div class="f-row tall">
<div class="f-label">Application</div>
<div class="f-control">
{{ form.application }}
</div>
</div>
<div class="f-row">
<div class="f-label">Scripture</div>
<div class="f-control">
{{ form.scripture_raw }}
</div>
</div>
<div class="f-row">
<div class="f-label">Source</div>
<div class="f-control">
{{ form.source }}
</div>
</div>
<div class="f-row">
<div class="f-label">Talk Title</div>
<div class="f-control">
{{ form.talk_title }}
</div>
</div>
<div class="f-row">
<div class="f-label">Talk Number</div>
<div class="f-control">
{{ form.talk_number }}
</div>
</div>
<div class="f-row">
<div class="f-label">Entry Code</div>
<div class="f-control">
{{ form.entry_code }}
</div>
</div>
<div class="f-row">
<div class="f-label">Date Added</div>
<div class="f-control">
{{ form.date_added }}
</div>
</div>
<div class="f-row">
<div class="f-label">Date Edited</div>
<div class="f-control">
{{ form.date_edited }}
</div>
</div>
</div>
<!-- bottom actions (hidden by CSS if you prefer only the top bar) -->
<div class="form-actions bottom-actions">
<a class="btn btn-secondary" href="{% url 'entry_view' entry.id %}">Cancel</a>
<button class="btn btn-primary">Save</button>
</div>
</form> </form>
</div> </div>
</div>
<!-- Same talk-title autofill behavior as entry_add --> <!-- Talk title auto-fill (same behavior as entry_add) -->
<script> <script>
(function () { (function () {
// Location of your mapping file
const talksUrl = "{% static 'talks.json' %}"; const talksUrl = "{% static 'talks.json' %}";
function wireAutofill(talkMap) { function wireAutofill(talkMap) {
@ -97,30 +115,42 @@
const titleEl = document.getElementById("id_talk_title"); const titleEl = document.getElementById("id_talk_title");
if (!numberEl || !titleEl) return; if (!numberEl || !titleEl) return;
// Consider "-" or "—" as empty (lets autofill replace them)
const isEffectivelyEmpty = (s) => {
const t = (s || "").trim();
return t === "" || t === "-" || t === "—";
};
// Track if user has typed something custom
let userTyped = false; let userTyped = false;
titleEl.addEventListener("input", () => { titleEl.addEventListener("input", () => {
userTyped = titleEl.value.trim().length > 0; userTyped = !isEffectivelyEmpty(titleEl.value);
if (!userTyped) titleEl.dataset.autofilled = "0"; if (!userTyped) titleEl.dataset.autofilled = "0";
}); });
function maybeAutofill() { function maybeAutofill() {
const n = numberEl.value; const n = numberEl.value;
const mapped = talkMap && talkMap[n] ? talkMap[n] : ""; const mapped = talkMap && talkMap[n] ? talkMap[n] : "";
if (!userTyped) { if (!userTyped) {
if (mapped) { if (mapped) {
titleEl.value = mapped; titleEl.value = mapped;
titleEl.dataset.autofilled = "1"; titleEl.dataset.autofilled = "1";
} else if (titleEl.dataset.autofilled === "1") { } else if (titleEl.dataset.autofilled === "1") {
// Previously autofilled but new number has no title: clear it
titleEl.value = ""; titleEl.value = "";
titleEl.dataset.autofilled = "0"; titleEl.dataset.autofilled = "0";
} }
} }
} }
// Change -> try to fill
numberEl.addEventListener("change", maybeAutofill); numberEl.addEventListener("change", maybeAutofill);
// Initial fill: if empty, we allow autofill; if not, respect user content. // Initial fill on page load:
if (titleEl.value.trim() === "") { // If current title is empty/hyphen, allow autofill; otherwise respect user text
if (isEffectivelyEmpty(titleEl.value)) {
userTyped = false; userTyped = false;
maybeAutofill(); maybeAutofill();
} else { } else {
@ -128,6 +158,7 @@
} }
} }
// Fetch the mapping; if it fails, no worries—form still works
fetch(talksUrl, {cache: "no-store"}) fetch(talksUrl, {cache: "no-store"})
.then(r => r.ok ? r.json() : {}) .then(r => r.ok ? r.json() : {})
.then(map => wireAutofill(map)) .then(map => wireAutofill(map))