TurboModal

TurboModal

TurboModal Stimulus Controller

Handles explicit Turbo Stream form submission while coordinating Bootstrap modal transitions, visible feedback, and focus restoration after page updates.

Features:

  • Modal closing before successful Turbo Stream rendering
  • Bootstrap modal integration
  • Turbo Form submission handling
  • Prevents modal from interfering with page updates

Usage:

Successful stream responses close the modal before updating the page. Failed requests leave it open so the user can review feedback and retry.

Constructor

new TurboModal()

Source:

Methods

announceFailure()

Description:
  • Announce a failed submission after any server-provided stream is rendered.

Source:

announceSuccess()

Description:
  • Announce successful completion after the modal starts closing.

Source:

captureModalTrigger()

Description:
  • Remember the control that opened the modal for focus restoration.

Source:

clearFailure()

Description:
  • Remove stale in-modal failure feedback before retrying a submission.

Source:

closeModal()

Description:
  • Hide the containing Bootstrap modal if one exists.

Source:

(async) closeModalAndWait()

Description:
  • Hide a visible modal and resolve only after Bootstrap finishes its transition.

Source:

closeModalBeforeSubmit(event)

Description:
  • Close the modal before form submission starts

Source:
Parameters:
Name Type Description
event Event

The turbo:submit-start event

connect()

Description:
  • Initialize - log when controller connects

Source:

connectedElement()

Description:
  • Return an element only while it remains connected to the current document.

Source:

createStreamFocusPlan(streamHtml) → {object|null}

Description:
  • Capture enough of a row-changing Turbo Stream to select a logical focus target afterward.

Source:
Parameters:
Name Type Description
streamHtml string

Turbo Stream response body.

Returns:

Focus restoration plan.

Type
object | null

dismissModalBackdrop()

Description:
  • Remove stray backdrops when Bootstrap did not fully tear down the modal.

Source:

failureContainer()

Description:
  • Resolve or create the visible feedback container inside the active modal.

Source:

failureMessage()

Description:
  • Return the configured failure copy for visible and announced feedback.

Source:

findFocusable()

Description:
  • Find the preferred actionable descendant of a potential focus target.

Source:

findModalElement()

Description:
  • Resolve the Bootstrap modal for this form.

    Officers (and similar) wrap the modal markup inside the form; others nest the form inside the modal. Support both DOM shapes.

Source:

modalInstance()

Description:
  • Return the Bootstrap instance for a modal, creating it when supported.

Source:

renderTurboStream(streamHtml)

Source:
Parameters:
Name Type Description
streamHtml string

Turbo stream HTML

(async) restoreFocusAfterStream()

Description:
  • Focus the replacement action or the nearest surviving grid context.

Source:

setSubmitting()

Description:
  • Prevent duplicate submits while the Turbo Stream request is in-flight.

Source:

showFallbackFailure()

Description:
  • Show a visible retryable error while keeping the modal and entered values open.

Source:

showFallbackSuccess()

Description:
  • Show visible feedback if Turbo cannot apply an otherwise successful stream.

Source:

streamIncludesLiveFeedback()

Description:
  • Return true when the stream already provides an accessible live-region message.

Source:

(async) submitAsTurboStream(event)

Description:
  • Submit a modal form as a Turbo Stream request.

    Turbo Drive is disabled globally, so modal forms that should update the current grid need an explicit stream fetch instead of browser navigation.

Source:
Parameters:
Name Type Description
event SubmitEvent

The submit event

successMessage()

Description:
  • Return the configured success copy for visible and announced feedback.

Source:

syncPageContext()

Description:
  • Sync hidden page context to the visible browser URL before posting.

Source:

(async) waitForRenderFrame()

Description:
  • Wait one bounded rendering step for Turbo custom elements to update the DOM.

Source: