LoginSignup
0
1

【備忘録】Rails7 Stimulus セレクトボックス 親子 複数 連動

Last updated at Posted at 2024-01-12

会社を選択すると、現場と品目の選択肢に、アソシエーションされているレコードをセットする
add_flow7.gif

config/routes.rb
  resources :companies do
    get 'sites', on: :member
    get 'waste_kinds', on: :member
  end
app/controllers/companies_controller.rb
  def sites
    company = Company.find(params[:id])
    sites = company.sites

    respond_to do |format|
      format.json { render json: sites }
    end
  end

  def waste_kinds
    company = Company.find(params[:id])
    waste_kinds = company.waste_kinds

    respond_to do |format|
      format.json { render json: waste_kinds }
    end
  end
app/views/industrial_wastes/_form.html.erb
<div data-controller="company-select">
  <div class="my-5">
    <%= form.label :company_id, "会社" %><span class="text-red-500">*</span>
    <%= form.collection_select(
      :company_id,
      Company.all,
      :id,
      :name,
      {prompt: true},
      class: "company-select shadow appearance-none border border-gray-200 rounded w-full py-2 px-3 mt-2 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
      data: {
        action: "change->company-select#onChange"
      }
    ) %>
  </div>

  <div class="my-5">
    <%= form.label :site_id, "現場" %><span class="text-red-500">*</span>
    <%= form.collection_select(
      :site_id,
      [],
      :id,
      :name,
      {prompt: "会社を先に選択してください"},
      class: "shadow appearance-none border border-gray-200 rounded w-full py-2 px-3 mt-2 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
      data: {
        "company-select-target": "site"
      }
    ) %>
  </div>

  <div class="my-5">
    <%= form.label :waste_kind_id, "品目" %><span class="text-red-500">*</span>
    <%= form.collection_select(
      :waste_kind_id,
      [],
      :id,
      :name,
      {prompt: "会社を先に選択してください"},
      class: "shadow appearance-none border border-gray-200 rounded w-full py-2 px-3 mt-2 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
      data: {
        "company-select-target": "wasteKind"
      }
    ) %>
  </div>
</div>
app/javascript/controllers/company_select_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
static targets = ["site", "wasteKind"]

onChange(event) {
  this.updateSiteOptions(event.target.value);
  this.updateWasteKindOptions(event.target.value);
}

updateSiteOptions(companyId) {
  fetch(`/companies/${companyId}/sites.json`)
    .then(response => response.json())
    .then(data => {
      let options = data.map(site => `<option value="${site.id}">${site.name}</option>`);
      this.siteTarget.innerHTML = options.join("");
    });
}

updateWasteKindOptions(companyId) {
  fetch(`/companies/${companyId}/waste_kinds.json`)
    .then(response => response.json())
    .then(data => {
      let options = data.map(wasteKind => `<option value="${wasteKind.id}">${wasteKind.name}</option>`);
      this.wasteKindTarget.innerHTML = options.join("");
    });
}
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1