Enhance navigation after save by improving URL handling and fallback mechanisms for question transitions

This commit is contained in:
Ross
2026-01-05 14:04:30 +00:00
parent 3928df6d75
commit 20a06323d5
2 changed files with 82 additions and 75 deletions
+8 -8
View File
@@ -201,11 +201,11 @@
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<script> <script>
/* HTMX swap helpers: preserve scroll and container height to avoid page jumping /* HTMX swap helpers: preserve scroll and container height to avoid page jumping
Listens for htmx:beforeSwap and htmx:afterSwap on the question fragment container. Listens for htmx:beforeSwap and htmx:afterSwap on the question fragment container.
*/ */
(function(){ (function(){
function getTarget(evt){ function getTarget(evt){
return (evt.detail && (evt.detail.target || evt.detail.elt)) || evt.target; return (evt.detail && (evt.detail.target || evt.detail.elt)) || evt.target;
} }
@@ -233,12 +233,12 @@
target.dispatchEvent(new CustomEvent('fragment:loaded', { bubbles: true })); target.dispatchEvent(new CustomEvent('fragment:loaded', { bubbles: true }));
}catch(e){ console && console.error && console.error(e); } }catch(e){ console && console.error && console.error(e); }
}); });
})(); })();
</script> </script>
<script> <script>
// Global listener for server-triggered save confirmations. // Global listener for server-triggered save confirmations.
// The view sets an `HX-Trigger` header named `saved` when an HTMX save occurs. // The view sets an `HX-Trigger` header named `saved` when an HTMX save occurs.
document.addEventListener('saved', function(evt){ document.addEventListener('saved', function(evt){
try { try {
// Prefer toastr if available // Prefer toastr if available
if (typeof toastr !== 'undefined' && toastr && typeof toastr.success === 'function') { if (typeof toastr !== 'undefined' && toastr && typeof toastr.success === 'function') {
@@ -272,6 +272,6 @@ document.addEventListener('saved', function(evt){
// hide after 1.6s // hide after 1.6s
setTimeout(function(){ el.style.opacity = '0'; }, 1600); setTimeout(function(){ el.style.opacity = '0'; }, 1600);
} catch (e) { console && console.error && console.error(e); } } catch (e) { console && console.error && console.error(e); }
}); });
</script> </script>
{% endblock %} {% endblock %}
@@ -170,9 +170,16 @@
if(hxTrigger && hxTrigger.indexOf('saved') !== -1){ if(hxTrigger && hxTrigger.indexOf('saved') !== -1){
handled = true; handled = true;
if(window.htmx && typeof htmx.off === 'function') htmx.off('htmx:afterRequest', htmxHandler); if(window.htmx && typeof htmx.off === 'function') htmx.off('htmx:afterRequest', htmxHandler);
try{
const pageUrl = `{% if cid %}{% url 'physics:exam_take' pk=exam.pk sk=0 cid=cid passcode=passcode %}{% else %}{% url 'physics:exam_take_user' pk=exam.pk sk=0 %}{% endif %}`.replace('/0/', '/' + destIndex + '/');
window.location = pageUrl;
}catch(e){
if(document.getElementById('goto-button')){
document.getElementById('goto-button').value = destIndex; document.getElementById('goto-button').value = destIndex;
$('#goto-button').click(); $('#goto-button').click();
} }
}
}
}catch(e){/* ignore */} }catch(e){/* ignore */}
} }
@@ -181,13 +188,13 @@
} }
// As a fallback listen for the custom 'saved' event // As a fallback listen for the custom 'saved' event
const onSavedFallback = function(){ if(handled) return; handled = true; document.removeEventListener('saved', onSavedFallback); document.getElementById('goto-button').value = destIndex; $('#goto-button').click(); }; const onSavedFallback = function(){ if(handled) return; handled = true; document.removeEventListener('saved', onSavedFallback); try{ const pageUrl = `{% if cid %}{% url 'physics:exam_take' pk=exam.pk sk=0 cid=cid passcode=passcode %}{% else %}{% url 'physics:exam_take_user' pk=exam.pk sk=0 %}{% endif %}`.replace('/0/', '/' + destIndex + '/'); window.location = pageUrl; }catch(e){ if(document.getElementById('goto-button')){ document.getElementById('goto-button').value = destIndex; $('#goto-button').click(); } } };
document.addEventListener('saved', onSavedFallback); document.addEventListener('saved', onSavedFallback);
tmp.click(); tmp.click();
// final timeout fallback // final timeout fallback
setTimeout(function(){ if(!handled){ try{ document.removeEventListener('saved', onSavedFallback); if(window.htmx && typeof htmx.off === 'function') htmx.off('htmx:afterRequest', htmxHandler); document.getElementById('goto-button').value = destIndex; $('#goto-button').click(); }catch(e){} } }, 1500); setTimeout(function(){ if(!handled){ try{ document.removeEventListener('saved', onSavedFallback); if(window.htmx && typeof htmx.off === 'function') htmx.off('htmx:afterRequest', htmxHandler); const pageUrl = `{% if cid %}{% url 'physics:exam_take' pk=exam.pk sk=0 cid=cid passcode=passcode %}{% else %}{% url 'physics:exam_take_user' pk=exam.pk sk=0 %}{% endif %}`.replace('/0/', '/' + destIndex + '/'); window.location = pageUrl; }catch(e){ try{ if(document.getElementById('goto-button')){ document.getElementById('goto-button').value = destIndex; $('#goto-button').click(); } }catch(e){} } } }, 1500);
return; return;
} }
} }