Created
June 21, 2021 15:38
-
-
Save minimul/52b368eb78135729ff563fc136fbb8de to your computer and use it in GitHub Desktop.
Kicking off JavaScript on a turbo stream
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Needed to close an open modal after streaming in a new select box | |
# 1. Newly generated select box. Mark "from-stream" true. | |
# app/views/shipments/create_entity.turbo_stream.erb | |
<% | |
dropdown_html = "" | |
form_with(model: form, url: result.action_url) do |f| | |
dropdown_html = render partial: "shipments/entity_dropdown", | |
locals: { f: f, type: type, collection: collection, from_stream: true } | |
end | |
%> | |
# 2. shipments/entity_dropdown.html.erb | |
<div id="<%= shipment_entity_dropdown_id(type) %>"> | |
<%= f.select "#{type}_id".to_sym, collection, | |
{prompt: shipment_entity_prompt(type)}, | |
{ | |
data: { | |
"controller": "shipments--entity-dropdown", | |
"shipments--entity-dropdown-from-stream-value": defined?(from_stream) ? from_stream : false | |
} | |
} | |
%> | |
</div> | |
# 3. shipments/entity_dropdown_controller.js | |
# MutationObserver kicks off after the stream | |
# and fromStream value is now true | |
export default class extends Controller { | |
static values = { fromStream: Boolean } | |
connect () { | |
const limit = this.data.get('limit') | |
const placeholder = this.data.get('placeholder') | |
const searchText = this.data.get('no-results') | |
const closeOnSelect = this.single | |
const allowDeselect = !this.element.required | |
this.select = new SlimSelect({ | |
select: this.element, | |
closeOnSelect, | |
allowDeselect, | |
limit, | |
placeholder, | |
searchText, | |
onChange: (info) => { | |
this.markAsSelected(info) | |
} | |
}) | |
this.markAsSelected(this.element) | |
if (this.fromStreamValue) { | |
if (isVisible('#inner-modal-container')) { | |
Rails.fire(document, 'close-inner-modal') | |
} else { | |
Rails.fire(document, 'close-modal') | |
} | |
} | |
} | |
// ... more methods | |
} | |
# 4. When modal is opened create a custom event listener | |
# so modal can be closed. | |
export default class extends Modal { | |
static targets = ['container'] | |
open (e) { | |
this.adjustWidth(e) | |
// Expose the ability to close the modal | |
this.element.dispatchEvent(new CustomEvent('close-modal', { bubbles: true })) | |
document.addEventListener('close-modal', () => { this.close(e) }) | |
super.open(e) | |
} | |
close (e) { | |
document.removeEventListener('close-modal', this.close) | |
super.close(e) | |
} | |
disconnect () { | |
document.removeEventListener('close-modal', this.close) | |
super.disconnect() | |
} | |
// .. more methods | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment