Tuesday, October 8, 2024
HomeRuby On RailsDependent Fields with Hotwire | Drifting Ruby

Dependent Fields with Hotwire | Drifting Ruby


# Terminal
rails g scaffold customers identify age:integer driver_license:boolean extend_profile:boolean twitter linkedin perferred_method_of_contact e mail telephone
rails g stimulus toggle-fields
# settings.json
"inlineFold.regex": "(class=|className=|class:s*)(((4))",
# app/fashions/person.rb
class Consumer < ApplicationRecord
  enum :perferred_method_of_contact, { e mail: 0, telephone: 1 }
finish
# app/views/customers/_form.html.erb
<%= form_with(mannequin: person) do |kind| %>
  <% if person.errors.any? %>
    <div fashion="shade: pink">
      <h2><%= pluralize(person.errors.depend, "error") %> prohibited this person from being saved:</h2>

      <ul>
        <% person.errors.every do |error| %>
          <li><%= error.full_message %></li>
        <% finish %>
      </ul>
    </div>
  <% finish %>

  <div class="mb-3">
    <%= kind.label :identify, class: 'form-label' %>
    <%= kind.text_field :identify, class: 'form-control' %>
  </div>

  <div data-controller="toggle-fields">
    <div class="mb-3">
      <%= kind.label :age, class: 'form-label' %>
      <%= kind.number_field :age, "data-toggle-fields-target": :enter, class: 'form-control' %>
    </div>

    <div data-toggle-fields-target="hidden" data-greater-than=16 class="mb-3 form-check">
      <%= kind.label :driver_license, class: 'form-check-label' %>
      <%= kind.check_box :driver_license, class: 'form-check-input' %>
    </div>
  </div>

  <div data-controller="toggle-fields">
    <div class="mb-3 form-check">
      <%= kind.label :extend_profile, class: 'form-check-label' %>
      <%= kind.check_box :extend_profile, "data-toggle-fields-target": :enter, class: 'form-check-input' %>
    </div>

    <div data-toggle-fields-target="hidden" data-value=true class="mb-3">
      <%= kind.label :twitter, class: 'form-label' %>
      <%= kind.text_field :twitter, class: 'form-control' %>
    </div>

    <div data-toggle-fields-target="hidden" data-value=true class="mb-3">
      <%= kind.label :linkedin, class: 'form-label' %>
      <%= kind.text_field :linkedin, class: 'form-control' %>
    </div>
  </div>

  <div data-controller="toggle-fields">
    <div class="mb-3">
      <%= kind.label :perferred_method_of_contact, class: 'form-label' %>
      <%= kind.choose :perferred_method_of_contact,
        Consumer.perferred_method_of_contacts.keys,
        { include_blank: true },
        "data-toggle-fields-target": :enter,
        class: 'form-control' %>
    </div>

    <div data-toggle-fields-target="hidden" data-value="e mail" class="mb-3">
      <%= kind.label :e mail, class: 'form-label' %>
      <%= kind.text_field :e mail, class: 'form-control' %>
    </div>

    <div data-toggle-fields-target="hidden" data-value="telephone" class="mb-3">
      <%= kind.label :telephone, class: 'form-label' %>
      <%= kind.text_field :telephone, class: 'form-control' %>
    </div>
  </div>

  <div class="actions">
    <%= kind.submit class: 'btn btn-primary' %>
  </div>
<% finish %>
# app/javascript/controllers/toggle_fields_controller.js
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="toggle-fields"
export default class extends Controller {
  static targets = ["hidden", "input"]

  join() {
    this.inputTarget.addEventListener("change", this.toggle.bind(this))
    this.inputTarget.addEventListener("keyup", this.toggle.bind(this))
    this.toggle()
  }

  disconnect() {
    this.inputTarget.removeEventListener("change", this.toggle.bind(this))
    this.inputTarget.removeEventListener("keyup", this.toggle.bind(this))
  }

  toggle() {
    this.hiddenTargets.forEach((goal) => {
      const targetValue = goal.dataset.worth ? goal.dataset.worth : null
      const greaterThanValue = goal.dataset.greaterThan ? parseFloat(goal.dataset.greaterThan) : null
      const lessThanValue = goal.dataset.lessThan ? parseFloat(goal.dataset.lessThan) : null
      console.log(this.worth, targetValue, greaterThanValue, lessThanValue);

      let shouldShow = true

      if (targetValue !== null && this.worth !== targetValue) { shouldShow = false }
      if (greaterThanValue !== null && this.worth < greaterThanValue) { shouldShow = false }
      if (lessThanValue !== null && this.worth > lessThanValue) { shouldShow = false }

      if (shouldShow) {
        goal.classList.take away("d-none")
        // goal.classList.take away("hidden", "sm:hidden", "md:hidden", "lg:hidden")
      } else {
        goal.classList.add("d-none")
        // goal.classList.add("hidden", "sm:hidden", "md:hidden", "lg:hidden")
      }
    })
  }

  get worth() {
    change (this.inputTarget.kind) {
      case "checkbox":
        return this.inputTarget.checked ? "true" : "false"
      case "quantity":
        return this.inputTarget.worth ? parseFloat(this.inputTarget.worth) : null
      default:
        return this.inputTarget.worth
    }
  }
}
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments