-
-
Save tdegrunt/cf03568108e9ae9afd8ce83d5a10eb90 to your computer and use it in GitHub Desktop.
Hotwire Event-Driven Update Pattern
This file contains 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
<%= form_with model: citizen, class: "card flex flex-col gap", data: { controller: "form" } do |form| %> | |
<div class="flex flex-col gap mb-2"> | |
<div class="flex flex-col gap-half"> | |
<% countries = Country.order(:name) %> | |
<%= label_tag :country_id, "Country", class: "text-sm font-medium leading-none" %> | |
<%= select_tag :country_id, options_from_collection_for_select(countries, :id, :name, citizen.country_id), include_blank: "Select one", class: "input", data: { action: "form#submit", form_submitter_param: "on_country_change" } %> | |
</div> | |
<div class="flex flex-col gap-half"> | |
<% states = State.where(country_id: citizen.country_id).order(:name) %> | |
<%= label_tag :state_id, "State", class: "text-sm font-medium leading-none" %> | |
<%= select_tag :state_id, options_from_collection_for_select(states, :id, :name, citizen.state_id), include_blank: "Select one", class: "input", data: { action: "form#submit", form_submitter_param: "on_state_change" } %> | |
</div> | |
<div class="flex flex-col gap-half"> | |
<% cities = City.where(state_id: citizen.state_id).order(:name) %> | |
<%= form.label :city_id, "City", class: "text-sm font-medium leading-none" %> | |
<%= form.collection_select :city_id, cities, :id, :name, { include_blank: "Select one" }, { class: "input" } %> | |
</div> | |
</div> | |
<div class="flex items-center"> | |
<%= form.submit "Save changes", class: "btn btn--primary" %> | |
<%= form.submit id: "on_country_change", hidden: true, formaction: on_country_change_citizens_path, formmethod: :post, formnovalidate: true %> | |
<%= form.submit id: "on_state_change", hidden: true, formaction: on_state_change_citizens_path, formmethod: :post, formnovalidate: true %> | |
</div> | |
<% end %> |
This file contains 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
class Citizen < ApplicationRecord | |
belongs_to :city | |
delegate :state, :state_id, to: :city, allow_nil: true | |
delegate :country, :country_id, to: :state, allow_nil: true | |
end |
This file contains 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
class CitizensController < ApplicationController | |
def new | |
@citizen = Citizen.new | |
end | |
def edit | |
@citizen = Citizen.first | |
end | |
def create | |
head :created | |
end | |
def update | |
head :ok | |
end | |
def on_country_change | |
@states = State.where(country_id: params[:country_id]).order(:name) | |
end | |
def on_state_change | |
@cities = City.where(state_id: params[:state_id]).order(:name) | |
end | |
end |
This file contains 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
import { Controller } from "@hotwired/stimulus" | |
export default class extends Controller { | |
submit({ params }) { | |
if (params.submitter) { | |
this.element.requestSubmit(this.#find(params.submitter)) | |
} else { | |
this.element.requestSubmit() | |
} | |
} | |
#find(id) { | |
return document.getElementById(id) || this.#notFound(id) | |
} | |
#notFound(id) { | |
throw new Error(`Element with ID "${id}" not found`) | |
} | |
} |
This file contains 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
<%= turbo_stream.replace :state_id do %> | |
<%= select_tag :state_id, options_from_collection_for_select(@states, :id, :name), include_blank: "Select one", class: "input", data: { action: "form#submit", form_submitter_param: "on_state_change" } %> | |
<% end %> | |
<%= turbo_stream.replace :citizen_city_id do %> | |
<%= select_tag :citizen_city_id, nil, name: "citizen[city_id]", include_blank: "Select one", class: "input" %> | |
<% end %> |
This file contains 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
<%= turbo_stream.replace :citizen_city_id do %> | |
<%= select_tag :citizen_city_id, options_from_collection_for_select(@cities, :id, :name), name: "citizen[city_id]", include_blank: "Select one", class: "input" %> | |
<% end %> |
This file contains 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
Rails.application.routes.draw do | |
resources :citizens, only: %i(new edit create update) do | |
post "on_country_change", on: :collection | |
post "on_state_change", on: :collection | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment