Skip to content

Commit 7626432

Browse files
committed
Re-initialize JavaScript elements on failed form submission
When the form is submitted but no redirect occurs (e.g., after a validation error), the page content is simply replaced. However, for this occasion Turbo misses to emit a new `turbo:load` event, which makes it more difficult to use custom JavaScript waiting on page initializations. Potentially, we could use `turbo:render` here to fix these occasions.
1 parent 3e487d3 commit 7626432

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

app/javascript/turbo-migration.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
let sprocketsLoaded = false;
1313
const sprocketsLoadQueue = [];
14+
const turboRenderQueue = [];
1415

1516
document.addEventListener('turbo:load', (event) => {
1617
sprocketsLoaded ? forwardTurboLoad(event) : sprocketsLoadQueue.push(event);
@@ -22,6 +23,25 @@ document.addEventListener('sprockets:load', () => {
2223
flushQueue(sprocketsLoadQueue);
2324
});
2425

26+
// Handle failed form submissions by waiting for `turbo:render` events
27+
document.addEventListener('turbo:submit-end', (event) => {
28+
if (!event.detail.success) {
29+
// If the form submission was _not_ successful, we need to re-initialize JavaScript elements.
30+
// This is necessary since Turbo does not dispatch a `turbo:load` event in this case.
31+
turboRenderQueue.push(event);
32+
}
33+
});
34+
35+
document.addEventListener('turbo:render', () => {
36+
if (sprocketsLoaded) {
37+
flushQueue(turboRenderQueue);
38+
} else {
39+
// In the unlikely case that Sprockets isn't ready yet, we queue the events.
40+
sprocketsLoadQueue.push(...turboRenderQueue);
41+
turboRenderQueue.length = 0;
42+
}
43+
});
44+
2545
function forwardTurboLoad(event) {
2646
requestAnimationFrame(() => {
2747
const delayedEvent = new CustomEvent('turbo-migration:load', { detail: { ...event.detail } });

0 commit comments

Comments
 (0)