Entry creation!

This commit is contained in:
Yaro Kasear 2025-10-03 09:02:15 -05:00
parent 53efc8551d
commit 2502375d32
6 changed files with 252 additions and 178 deletions

View file

@ -6,8 +6,6 @@
function formToJson(form) {
const fd = new FormData(form);
const out = {};
// base values
fd.forEach((value, key) => {
if (key in out) {
if (!Array.isArray(out[key])) out[key] = [out[key]];
@ -16,31 +14,21 @@
out[key] = value;
}
});
// normalize radios and checkboxes
form.querySelectorAll('input[type="checkbox"], input[type="radio"]').forEach(el => {
if (!el.name) return;
if (el.type === 'radio') {
if (out[el.name] !== undefined) return; // already set for this group
if (out[el.name] !== undefined) return;
const checked = form.querySelector(`input[type="radio"][name="${CSS.escape(el.name)}"]:checked`);
if (checked) out[el.name] = checked.value ?? true;
return;
}
if (el.type === 'checkbox') {
const group = form.querySelectorAll(`input[type="checkbox"][name="${CSS.escape(el.name)}"]`);
if (group.length > 1) {
const checkedVals = Array.from(group).filter(i => i.checked).map(i => i.value ?? true);
out[el.name] = checkedVals;
} else {
out[el.name] = el.checked;
}
out[el.name] = group.length > 1
? Array.from(group).filter(i => i.checked).map(i => i.value ?? true)
: el.checked;
}
});
console.log(out);
return out;
}
@ -49,58 +37,61 @@
.map(el => Number(el.id.slice(3)))
.filter(Number.isFinite);
}
function collectEditedUpdates() {
const updates = [];
for (const id of collectExistingUpdateIds()) {
updates.push({ id, content: getMarkdown(id) }); // ensure getMarkdown exists
}
for (const md of (window.newDrafts || [])) {
if ((md ?? '').trim()) updates.push({ content: md });
}
for (const id of collectExistingUpdateIds()) updates.push({ id, content: getMarkdown(id) });
for (const md of (window.newDrafts || [])) if ((md ?? '').trim()) updates.push({ content: md });
return updates;
}
function collectDeletedIds() { return (window.deletedIds || []).filter(Number.isFinite); }
function collectDeletedIds() {
return (window.deletedIds || []).filter(Number.isFinite);
}
// much simpler, and correct
const formEl = document.getElementById({{ (field['attrs']['data-model'] ~ '_form') | tojson }});
const model = {{ field['attrs']['data-model'] | tojson }};
const idVal = {{ field['template_ctx']['values'].get('id') | tojson }};
const hasId = idVal !== null && idVal !== undefined;
document.getElementById("{{ field['attrs']['data-model'] }}_form").addEventListener("submit", async e => {
// Never call url_for for update on the "new" page.
// Create URL is fine to build server-side:
const createUrl = {{ url_for('entry.create_entry', model=field['attrs']['data-model']) | tojson }};
// Update URL is assembled on the client to avoid BuildError on "new":
const updateUrl = hasId ? `/entry/${model}/${idVal}` : null;
formEl.addEventListener("submit", async e => {
e.preventDefault();
const json = formToJson(e.target);
json.id = {{ field['template_ctx']['values']['id'] }};
const json = formToJson(formEl);
const model_name = {{ field['attrs']['data-model'] | tojson }};
if(model_name === 'inventory') {
if (model === 'inventory' && typeof getMarkdown === 'function') {
json.notes = getMarkdown().trim();
} else if (model_name === 'worklog') {
// child mutations
} else if (model === 'worklog') {
json.updates = collectEditedUpdates();
json.delete_update_ids = collectDeletedIds();
}
try {
const response = await fetch(
"{{ url_for('entry.update_entry', id=field['template_ctx']['values']['id'], model=field['attrs']['data-model']) }}",
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json),
}
);
if (hasId) json.id = idVal;
const reply = await response.json();
const url = hasId ? updateUrl : createUrl;
try {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json),
});
const reply = await res.json();
if (reply.status === 'success') {
toastMessage('This entry has been successfully saved!', 'success');
window.newDrafts = [];
window.deletedIds = [];
if (!hasId && reply.id) {
window.location.href = `/entry/${model}/${reply.id}?pretty=1`;
}
} else {
toastMessage(`Unable to save entry: ${reply.error}`, 'danger');
}
} catch (err) {
toastMessage(`Network error: ${String(err)}`, 'danger');
}
});
</script>
});
</script>