Module: TurboStreamActionsHelper

Defined in:
app/helpers/turbo_stream_actions_helper.rb

Instance Method Summary collapse

Instance Method Details

#analytics_event(event_name, properties = {}) ⇒ Object

Fire an analytics event
Usage: <%= turbo_stream.analytics_event("add_to_cart", { sku: "ABC123", price: 29.99 }) %>



164
165
166
167
168
# File 'app/helpers/turbo_stream_actions_helper.rb', line 164

def analytics_event(event_name, properties = {})
  turbo_stream_action_tag :analytics_event,
    'event-name': event_name,
    properties: properties.to_json
end

#bs_modal_hideObject



50
51
52
# File 'app/helpers/turbo_stream_actions_helper.rb', line 50

def bs_modal_hide
  turbo_stream_action_tag :bs_modal_hide
end

#bs_modal_show(modal_id) ⇒ Object

Show a Bootstrap modal by ID
Usage: <%= turbo_stream.bs_modal_show("myModalId") %>



46
47
48
# File 'app/helpers/turbo_stream_actions_helper.rb', line 46

def bs_modal_show(modal_id)
  turbo_stream_action_tag :bs_modal_show, 'modal-id': modal_id
end

#bs_offcanvas_hide(offcanvas_id) ⇒ Object

Hide a Bootstrap offcanvas by ID
Usage: <%= turbo_stream.bs_offcanvas_hide("offcanvas-id") %>



56
57
58
# File 'app/helpers/turbo_stream_actions_helper.rb', line 56

def bs_offcanvas_hide(offcanvas_id)
  turbo_stream_action_tag :bs_offcanvas_hide, target: offcanvas_id
end

#bulk_sync_fullcalendar_events(calendar_id: 'calendar', clear_all: false, events_data: []) ⇒ Object

Bulk-sync multiple FullCalendar events in a single Turbo Stream action.
Optionally clears all existing events first (for full calendar reloads).
Usage: <%= turbo_stream.bulk_sync_fullcalendar_events(calendar_id: "calendar", clear_all: true, events_data: @calendar_events) %>



122
123
124
125
126
127
# File 'app/helpers/turbo_stream_actions_helper.rb', line 122

def bulk_sync_fullcalendar_events(calendar_id: 'calendar', clear_all: false, events_data: [])
  turbo_stream_action_tag :bulk_sync_fullcalendar_events,
    'calendar-id': calendar_id,
    'clear-all': clear_all,
    'events-data': events_data.to_json
end

#clear_elements_id_prefix_except(id_prefix, except_id) ⇒ Object



100
101
102
# File 'app/helpers/turbo_stream_actions_helper.rb', line 100

def clear_elements_id_prefix_except(id_prefix, except_id)
  turbo_stream_action_tag :clear_elements_id_prefix_except, 'id-prefix': id_prefix, 'except-id': except_id
end

#clear_elements_matching(*selectors) ⇒ Object



96
97
98
# File 'app/helpers/turbo_stream_actions_helper.rb', line 96

def clear_elements_matching(*selectors)
  turbo_stream_action_tag :clear_elements_matching, selectors: selectors.flatten.compact.to_json
end

#clear_modalObject



144
145
146
# File 'app/helpers/turbo_stream_actions_helper.rb', line 144

def clear_modal
  turbo_stream_action_tag :clear_modal
end

#dispatch_event(selector, event_name, detail: nil) ⇒ Object

Dispatch a custom DOM event on an element matching a CSS selector
Usage:
<%= turbo_stream.dispatch_event("body", "room:options-updated") %>
<%= turbo_stream.dispatch_event("body", "cart:updated", detail: { count: 3 }) %>



133
134
135
136
137
138
# File 'app/helpers/turbo_stream_actions_helper.rb', line 133

def dispatch_event(selector, event_name, detail: nil)
  turbo_stream_action_tag :dispatch_event,
    selector: selector,
    'event-name': event_name,
    detail: (detail.to_json if detail)
end

#hide_element(element_id) ⇒ Object

Hide an element by ID (adds display:none)
Usage: <%= turbo_stream.hide_element("elementId") %>



68
69
70
# File 'app/helpers/turbo_stream_actions_helper.rb', line 68

def hide_element(element_id)
  turbo_stream_action_tag :hide_element, 'element-id': element_id
end

#init_bootstrap(target_id, component: nil) ⇒ Object

Initialize Bootstrap components after a Turbo Stream update
Usage: <%= turbo_stream.init_bootstrap("messages_list", component: "Tooltip") %>
Supported: Tooltip, Popover, Collapse, Dropdown (or nil for all)



82
83
84
# File 'app/helpers/turbo_stream_actions_helper.rb', line 82

def init_bootstrap(target_id, component: nil)
  turbo_stream_action_tag :init_bootstrap, target: target_id, component: component
end

#open_url(url) ⇒ Object

Open a URL in a new browser tab (for PDFs, downloads, etc.)
Usage: turbo_stream.open_url(upload_url(@pdf))



10
11
12
# File 'app/helpers/turbo_stream_actions_helper.rb', line 10

def open_url(url)
  turbo_stream_action_tag :open_url, url: url
end

#redirect(url) ⇒ Object

Full-page redirect via Turbo Drive (breaks out of Turbo Frame context)
Usage: turbo_stream.redirect("/my-account")



4
5
6
# File 'app/helpers/turbo_stream_actions_helper.rb', line 4

def redirect(url)
  turbo_stream_action_tag :redirect, url: url
end

#remove_hidden_inputs(name_contains:, value:) ⇒ Object

Remove hidden inputs whose value matches value and whose name attribute
contains name_contains. Used after destroying a nested-form record so the
leftover hidden inputs (rendered for the destroyed row) do not get
re-submitted with the parent form on its next save.
Usage:
<%= turbo_stream.remove_hidden_inputs(name_contains: 'contact_points_attributes',
value: @contact_point.id) %>

Raises:

  • (ArgumentError)


186
187
188
189
190
191
192
# File 'app/helpers/turbo_stream_actions_helper.rb', line 186

def remove_hidden_inputs(name_contains:, value:)
  raise ArgumentError, 'remove_hidden_inputs: value must not be blank' if value.blank?

  turbo_stream_action_tag :remove_hidden_inputs,
    'name-contains': name_contains,
    value: value.to_s
end

#replace_css_class(selector, pattern, replacement, traverse: 0) ⇒ Object

Replace CSS classes matching a regex pattern with a replacement class
Usage: <%= turbo_stream.replace_css_class(".my-selector", "status-\w+", "status-7") %>
Pass traverse: N to walk up N parent levels before replacing.



75
76
77
# File 'app/helpers/turbo_stream_actions_helper.rb', line 75

def replace_css_class(selector, pattern, replacement, traverse: 0)
  turbo_stream_action_tag :replace_css_class, selector: selector, pattern: pattern, replacement: replacement, traverse: traverse
end

#reset_activity_card_collapse(container_dom_id) ⇒ Object



140
141
142
# File 'app/helpers/turbo_stream_actions_helper.rb', line 140

def reset_activity_card_collapse(container_dom_id)
  turbo_stream_action_tag :reset_activity_card_collapse, 'container-id': container_dom_id
end

#set_input_value_by_selector(selector, value) ⇒ Object



92
93
94
# File 'app/helpers/turbo_stream_actions_helper.rb', line 92

def set_input_value_by_selector(selector, value)
  turbo_stream_action_tag :set_input_value_by_selector, selector: selector, value: value.to_s
end

#set_tab_param(tab_id) ⇒ Object

Update the ?tab=<id> query param in the browser URL via replaceState
without triggering a navigation. Used by the warehouse stream actions
when the originating tab disappears (count went to 0) so the URL keeps
reflecting the tab actually being shown.
Usage: turbo_stream.set_tab_param("picking")



175
176
177
# File 'app/helpers/turbo_stream_actions_helper.rb', line 175

def set_tab_param(tab_id)
  turbo_stream_action_tag :set_tab_param, tab: tab_id
end

#set_value(target_id, value) ⇒ Object

Set an input/textarea value by target ID
Avoids inline tags and .html_safe for passing data to form fields.
Usage: turbo_stream.set_value("room_name", @room_name)



158
159
160
# File 'app/helpers/turbo_stream_actions_helper.rb', line 158

def set_value(target_id, value)
  turbo_stream_action_tag :set_value, target: target_id, value: value.to_s
end

#show_element(element_id) ⇒ Object

Show an element by ID (removes display:none)
Usage: <%= turbo_stream.show_element("elementId") %>



62
63
64
# File 'app/helpers/turbo_stream_actions_helper.rb', line 62

def show_element(element_id)
  turbo_stream_action_tag :show_element, 'element-id': element_id
end

#sync_calendar_eventObject

Sync a CRM calendar event (legacy: uses data-attribute template on #event_calendar)
Used by crm/events/create.turbo_stream.erb



106
107
108
# File 'app/helpers/turbo_stream_actions_helper.rb', line 106

def sync_calendar_event
  turbo_stream_action_tag :sync_calendar_event
end

#sync_fullcalendar_event(calendar_id: 'calendar', remove_event_id: nil, event_data: {}) ⇒ Object

Sync a FullCalendar event (remove old + add new) via JSON attributes
Usage: <%= turbo_stream.sync_fullcalendar_event(calendar_id: "calendar", remove_event_id: old_id, event_data: { title: "...", start: "...", ... }) %>



112
113
114
115
116
117
# File 'app/helpers/turbo_stream_actions_helper.rb', line 112

def sync_fullcalendar_event(calendar_id: 'calendar', remove_event_id: nil, event_data: {})
  turbo_stream_action_tag :sync_fullcalendar_event,
    'calendar-id': calendar_id,
    'remove-event-id': remove_event_id,
    'event-data': event_data.to_json
end

#toast(content = nil, &block) ⇒ Object

Show a toast notification
Usage: <%= turbo_stream.toast do %>...<% end %>



150
151
152
153
# File 'app/helpers/turbo_stream_actions_helper.rb', line 150

def toast(content = nil, &block)
  template = content || (block ? @view_context.capture(&block) : nil)
  turbo_stream_action_tag :toast, template: template
end

#track_download(url, filename: nil, worker: nil, disposition: nil) ⇒ Object

Surface a downloadable file in the global Jobs offcanvas as a "Ready"
entry AND auto-trigger an immediate browser action. The offcanvas
entry is the always-visible fallback when the auto-trigger is
suppressed by the browser's pop-up blocker (common after multi-redirect
server flows like print_pick_slip → upload_url → redirect).

Disposition (default: :attachment) controls the auto-trigger:

  • :attachment → forces save-as via . Browser ignores the
    target attribute when download is set, so no tab opens.
  • :inline → opens in a new tab via . The
    server's Content-Disposition header decides whether the browser
    renders inline (PDFs in the in-browser viewer) or saves anyway.

Filename and worker label are optional; filename defaults to the
basename of the URL path on the client side; worker defaults to
"Download".

Usage:
turbo_stream.track_download(upload_url(@pdf))
turbo_stream.track_download(upload_url(@pdf), filename: 'invoice.pdf')
turbo_stream.track_download(upload_url(@pdf), worker: 'Print Pick Slip')
turbo_stream.track_download(upload_url(@pdf), disposition: :inline)



36
37
38
39
40
41
42
# File 'app/helpers/turbo_stream_actions_helper.rb', line 36

def track_download(url, filename: nil, worker: nil, disposition: nil)
  turbo_stream_action_tag :track_download,
    url: url,
    filename: filename,
    worker: worker,
    disposition: (disposition.to_s.presence)
end

#unblock_uiObject

Clear jquery-blockUI overlay after Turbo Stream updates
Usage: <%= turbo_stream.unblock_ui %>



88
89
90
# File 'app/helpers/turbo_stream_actions_helper.rb', line 88

def unblock_ui
  turbo_stream_action_tag :unblock_ui
end