Add global listener for HTMX save confirmations and trigger event
This commit is contained in:
@@ -245,4 +245,43 @@
|
|||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
// Global listener for server-triggered save confirmations.
|
||||||
|
// The view sets an `HX-Trigger` header named `saved` when an HTMX save occurs.
|
||||||
|
document.addEventListener('saved', function(evt){
|
||||||
|
try {
|
||||||
|
// Prefer toastr if available
|
||||||
|
if (typeof toastr !== 'undefined' && toastr && typeof toastr.success === 'function') {
|
||||||
|
toastr.success('Saved');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lightweight fallback toast
|
||||||
|
const id = 'htmx-save-toast';
|
||||||
|
let el = document.getElementById(id);
|
||||||
|
if (!el) {
|
||||||
|
el = document.createElement('div');
|
||||||
|
el.id = id;
|
||||||
|
el.style.position = 'fixed';
|
||||||
|
el.style.top = '1rem';
|
||||||
|
el.style.right = '1rem';
|
||||||
|
el.style.zIndex = 2000;
|
||||||
|
el.style.padding = '0.6rem 0.9rem';
|
||||||
|
el.style.background = 'rgba(40,167,69,0.95)';
|
||||||
|
el.style.color = '#fff';
|
||||||
|
el.style.borderRadius = '0.4rem';
|
||||||
|
el.style.boxShadow = '0 2px 8px rgba(0,0,0,0.2)';
|
||||||
|
el.style.fontWeight = '600';
|
||||||
|
el.style.opacity = '0';
|
||||||
|
el.style.transition = 'opacity 220ms ease-in-out';
|
||||||
|
document.body.appendChild(el);
|
||||||
|
}
|
||||||
|
el.textContent = 'Saved';
|
||||||
|
// show
|
||||||
|
requestAnimationFrame(function(){ el.style.opacity = '1'; });
|
||||||
|
// hide after 1.6s
|
||||||
|
setTimeout(function(){ el.style.opacity = '0'; }, 1600);
|
||||||
|
} catch (e) { console && console.error && console.error(e); }
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
+9
-1
@@ -287,7 +287,15 @@ def exam_take(request, pk: int, sk: int, cid: str | None = None, passcode: str |
|
|||||||
# Save action should not trigger a full-page load for HTMX clients.
|
# Save action should not trigger a full-page load for HTMX clients.
|
||||||
if is_htmx:
|
if is_htmx:
|
||||||
# Re-render the same fragment so the client can swap it in-place
|
# Re-render the same fragment so the client can swap it in-place
|
||||||
return exam_take_fragment(request, pk=pk, sk=pos, cid=cid, passcode=passcode)
|
# and set an HX-Trigger header so the client can show a confirmation
|
||||||
|
resp = exam_take_fragment(request, pk=pk, sk=pos, cid=cid, passcode=passcode)
|
||||||
|
try:
|
||||||
|
# Use a small JSON payload so client listeners can access details if needed
|
||||||
|
resp['HX-Trigger'] = json.dumps({'saved': True})
|
||||||
|
except Exception:
|
||||||
|
# Fallback to a simple event name
|
||||||
|
resp['HX-Trigger'] = 'saved'
|
||||||
|
return resp
|
||||||
# Non-HTMX clients get redirected back to the same question page
|
# Non-HTMX clients get redirected back to the same question page
|
||||||
return redirect(take_url, sk=pos, **kwargs)
|
return redirect(take_url, sk=pos, **kwargs)
|
||||||
elif "goto" in request.POST:
|
elif "goto" in request.POST:
|
||||||
|
|||||||
Reference in New Issue
Block a user