Update web/templates/entry_add.html
This commit is contained in:
parent
908e8bd03e
commit
e2a2b7239d
@ -112,6 +112,10 @@
|
||||
@media (max-width: 860px) {
|
||||
.form-row.two, .form-row.three { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
/* --- Subtle validation colors for Scripture field --- */
|
||||
.scripture-valid { background-color: hsl(140 80% 92% / 0.8); transition: background-color .15s ease; }
|
||||
.scripture-invalid { background-color: hsl(0 80% 94% / 0.8); transition: background-color .15s ease; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@ -169,11 +173,105 @@
|
||||
dateAddedEl.value = `${yyyy}-${mm}-${dd}`;
|
||||
}
|
||||
})();
|
||||
|
||||
// ----- Prefill Entry Code with current username -----
|
||||
const entryCodeEl = document.getElementById("id_entry_code");
|
||||
if (entryCodeEl && !entryCodeEl.value) {
|
||||
entryCodeEl.value = "{{ request.user.username }}";
|
||||
}
|
||||
|
||||
/* ===========================
|
||||
Live Scripture Validation
|
||||
=========================== */
|
||||
(function () {
|
||||
const el = document.getElementById("id_scripture_raw");
|
||||
if (!el) return;
|
||||
|
||||
// Exact WOL abbreviations (case-sensitive)
|
||||
const WOL = new Set([
|
||||
// OT
|
||||
"Ge","Ex","Le","Nu","De","Jos","Jg","Ru","1Sa","2Sa","1Ki","2Ki","1Ch","2Ch","Ezr","Ne","Es","Job","Ps","Pr","Ec","Ca","Isa","Jer","La","Eze","Da","Ho","Joe","Am","Ob","Jon","Mic","Na","Hab","Zep","Hag","Zec","Mal",
|
||||
// NT
|
||||
"Mt","Mr","Lu","Joh","Ac","Ro","1Co","2Co","Ga","Eph","Php","Col","1Th","2Th","1Ti","2Ti","Tit","Phm","Heb","Jas","1Pe","2Pe","1Jo","2Jo","3Jo","Jude","Re"
|
||||
]);
|
||||
|
||||
// Normalize some gentle user quirks:
|
||||
// - Allow trailing dot after the book token: "Ps." -> "Ps"
|
||||
// - Allow a space after the number in numbered books: "1 Pe" -> "1Pe"
|
||||
function normalizeBookToken(raw) {
|
||||
let t = raw.trim();
|
||||
// collapse internal multiple spaces
|
||||
t = t.replace(/\s+/g, " ");
|
||||
// remove trailing period on the book token
|
||||
t = t.replace(/\.$/, "");
|
||||
// join patterns like "1 Pe" or "2 Co" -> "1Pe" / "2Co"
|
||||
t = t.replace(/^([1-3])\s+([A-Za-z]+)/, (_, n, b) => n + b);
|
||||
return t;
|
||||
}
|
||||
|
||||
// Validate one reference like:
|
||||
// "Ro 12" (chapter only)
|
||||
// "Ro 12:1" (single verse)
|
||||
// "Ro 12:1, 3, 5-7" (lists and ranges)
|
||||
// "Joh 3:16-4:2" (cross-chapter range)
|
||||
// "Ps. 23" (trailing dot on book handled by normalization)
|
||||
function isValidSingleRef(ref) {
|
||||
const s = ref.trim();
|
||||
if (!s) return false;
|
||||
|
||||
// Split book token from the rest (book is everything before first space)
|
||||
const firstSpace = s.indexOf(" ");
|
||||
if (firstSpace < 0) return false;
|
||||
|
||||
const rawBook = s.slice(0, firstSpace);
|
||||
const book = normalizeBookToken(rawBook);
|
||||
|
||||
if (!WOL.has(book)) return false;
|
||||
|
||||
const rest = s.slice(firstSpace + 1).trim();
|
||||
if (!rest) return false;
|
||||
|
||||
// Accept "chapter" only (e.g., "Ps 23")
|
||||
if (/^\d{1,3}$/.test(rest)) return true;
|
||||
|
||||
// Accept "chapter:verses" where verses can be:
|
||||
// - n
|
||||
// - n-m
|
||||
// - n, m, p-q
|
||||
// and allow a cross-chapter range like 3:16-4:2
|
||||
// Pattern:
|
||||
// chap: ( part(, part)* )
|
||||
// where part is either:
|
||||
// v -> \d{1,3}
|
||||
// v-v -> \d{1,3}\s*-\s*\d{1,3}
|
||||
// v-ch:v2 -> \d{1,3}\s*-\s*\d{1,3}:\d{1,3}
|
||||
const re = /^(\d{1,3}):\s*(\d{1,3}(?:\s*-\s*(?:\d{1,3}|\d{1,3}:\d{1,3}))?(?:\s*,\s*\d{1,3}(?:\s*-\s*(?:\d{1,3}|\d{1,3}:\d{1,3}))?)*)$/;
|
||||
if (re.test(rest)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function validateAll() {
|
||||
const raw = el.value || "";
|
||||
// split by ';' as multiple references
|
||||
const parts = raw.split(";").map(t => t.trim()).filter(Boolean);
|
||||
if (parts.length === 0) {
|
||||
el.classList.remove("scripture-valid","scripture-invalid");
|
||||
return;
|
||||
}
|
||||
const allValid = parts.every(isValidSingleRef);
|
||||
el.classList.toggle("scripture-valid", allValid);
|
||||
el.classList.toggle("scripture-invalid", !allValid);
|
||||
}
|
||||
|
||||
// Wire events
|
||||
el.addEventListener("input", validateAll);
|
||||
el.addEventListener("change", validateAll);
|
||||
// Run once on load (in case form is prefilled)
|
||||
validateAll();
|
||||
})();
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
Loading…
Reference in New Issue
Block a user