Home > OS >  Hide blocks in form when choosing options
Hide blocks in form when choosing options

Time:06-13

I had a form for announcements. I need to hide some divs when user choose something. For example, when user choose 'Buy', i need to hide div with :services. User must to see only divs for 'Buy'. If user choose "chat", we don't need "city", "images", and others, only create. This is my form:

     = form_with(model: @room, local: true, html: {multipart: true}) do |f|
      - if @room && @room.errors.any?
#error_explanation
  %h2= "#{pluralize(@room.errors.count, "error")} prohibited this room from being saved:"
  %ul
    - @room.errors.full_messages.each do |message|
      %li= message
.form-group.mb-3
  = f.select :cat_route,[ "channel", "chat", "bot", "service"], class: 'form- 
 control'
 .form-group.mb-3
  = f.select :services,["option1", "option2", "option3"], class: 'form-control'
.form-group.mb-3
  = f.select :route,["Buy", "Sell"], class: 'form-control'
.form-group.mb-3
  = f.select :city,["City1", "City2", "City3"], class: 'form-control'
.form-group.mb-3
  = f.text_field :name, placeholder: "name", class: 'form-control'
.form-group.mb-3
  = f.text_field :link, placeholder: "link", class: 'form-control'
.form-group.mb-3
  = f.select :category,["SMM", "IT", "Gif Video"], class: 'form-control'
.form-group.mb-3
  = f.text_field :content, class: 'form-control'
.form-group.mb-3
  = f.text_field :price, class: 'form-control'
.form-group.mb-3
  = f.label 'Image'
  = f.file_field :image, class: 'form-control'
.form-group.mb-3
  = f.check_box :free, id: 'free', class: 'form-check-input'
 %b= f.label :option, 'Free', class: 'form-check-label', for: 'free'
.form-group.mb-3
  = f.check_box :hot, id: 'hot', class: 'form-check-input'
  = f.label 'hot', class: 'form-check-label small', for: 'hot'
%br
.actions
  = f.submit 'Create', class: 'btn btn-outline-primary btn-block'

CodePudding user response:

It's not very clear from your description what exactly you want to hide/show depending on selected options but you definitely need JS here to do this:

And you didn't mention what Rails version you use. Depending on this JS can be placed in Stimulus controller on in js file in assets pipeline

But I can provide you a raw snipper of js in your view file that does what you described in the question, rest you can implement according to the js template

= form_with(model: @room, local: true, html: {multipart: true}) do |f|
  - if @room && @room.errors.any?
    #error_explanation
      h2= "#{pluralize(@room.errors.count, "error")} prohibited this room from being saved:"
      ul
        - @room.errors.full_messages.each do |message|
          li= message
  .form-group.mb-3
    = f.select :cat_route,[ "channel", "chat", "bot", "service"], class: 'form-control'
  #other_blocks
    .form-group.mb-3
      = f.select :services,["option1", "option2", "option3"], class: 'form-control'
    .form-group.mb-3
      = f.select :route, ["Buy", "Sell"], class: 'form-control', include_blank: true
    .form-group.mb-3
      = f.select :city,["City1", "City2", "City3"], class: 'form-control'
    .form-group.mb-3
      = f.text_field :name, placeholder: "name", class: 'form-control'
    .form-group.mb-3
      = f.text_field :link, placeholder: "link", class: 'form-control'
    .form-group.mb-3
      = f.select :category,["SMM", "IT", "Gif Video"], class: 'form-control'
    .form-group.mb-3
      = f.text_field :content, class: 'form-control'
    .form-group.mb-3
      = f.text_field :price, class: 'form-control'
    .form-group.mb-3
      = f.label 'Image'
      = f.file_field :image, class: 'form-control'
    .form-group.mb-3
      = f.check_box :free, id: 'free', class: 'form-check-input'
    b= f.label :option, 'Free', class: 'form-check-label', for: 'free'
    .form-group.mb-3
      = f.check_box :hot, id: 'hot', class: 'form-check-input'
      = f.label 'hot', class: 'form-check-label small', for: 'hot'
  br
  .actions
    = f.submit 'Create', class: 'btn btn-outline-primary btn-block'


javascript:
  const roomRouteSelect = document.querySelector('#room_route')
  const roomCatRouteSelect = document.querySelector('#room_cat_route')
  const roomServicesSelect = document.querySelector('#room_services')
  const otherBlocks = document.querySelector('#other_blocks')
  roomRouteSelect.addEventListener('change', (e) => {
    if (e.target.value == 'Buy') {
      roomServicesSelect.classList.add('d-none')
    } else {
      roomServicesSelect.classList.remove('d-none')
    }
  })
  roomCatRouteSelect.addEventListener('change', (e) => {
    if (e.target.value == 'chat') {
      otherBlocks.classList.add('d-none')
    } else {
      otherBlocks.classList.remove('d-none')
    }
  })

Note: I wrapped some inputs in #other_blocks div, don't forget to add it to your form. Also I added include_blank: true to = f.select :route, ["Buy", "Sell"], class: 'form-control' so that you can see changes when you select this option

CodePudding user response:

I do not know Ruby. Assuming f.select :route means

<select id="route"

then I suggest the following - I guessed the HTML:

const form = document.querySelector("form");
const notChat = [...document.querySelectorAll(".form-control, .form-check-input, label")].slice(1); // all form-control except the first
form.addEventListener("change", e => {
  const tgt = e.target;
  if (tgt.id === "route") {
    document.getElementById("services").hidden = tgt.value === "Buy";
  } else if (tgt.id === "cat_route") {
    const hide = tgt.value === "chat"; console.log(hide)
    notChat.forEach(formControl => formControl.hidden = hide);
  }
})
<form>
  <div >
    <select name="cat_route" id="cat_route" >
      <option>channel</option>
      <option>chat</option>
      <option>bot</option>
      <option>service</option>
    </select>
  </div>
  <div >
    <select name="services" id="services" >
      <option>option1</option>
      <option>option2</option>
      <option>option3</option>
    </select>
  </div>
  <div >
    <select name="route" id="route" >
      <option>Buy</option>
      <option>Sell</option>
    </select>
  </div>
  <div >
    <select name="city" id="city" >
      <option>City1</option>
      <option>City2</option>
      <option>City3</option>
    </select>
  </div>
  <div >
    <input type="text" name="name" id="name" placeholder="name" >
  </div>
  <div >
    <input type="text" name="link" id="link" placeholder="link" >
  </div>
  <div >
    <select name="category" id="category" >
      <option>SMM</option>
      <option>IT</option>
      <option>Video</option>
    </select>
  </div>
  <div >
    <input type="text" id="content" >
  </div>
  <div >
    <input type="text" id="price" >
  </div>
  <div >
    <label>Image <input type="file" id="image" ></label>
  </div>
  <div >
    <label id="option"  for="free">Free</label> <input type="checkbox" id="free" >
  </div>
  <div >
    <label id="option"  for="hot">hot</label> <input type="checkbox" id="hot" >
  </div>
  <input type="submit" value="Create"  />
</form>

  • Related