简体   繁体   中英

How to show/hide fields on modal in Ruby on Rails?

I am writing an application using Rails 4.1 and Ruby 2.1.2. It has the following show.html.erb view for an Assignment Model:

<h1><%= "#{'Source URL'}"%> <div class="source-url"><%= @assignment.source.url %></div></h1>
<%= link_to new_assignment_contact_path(@assignment), id: 'display_modal', class: "add-btn btn-big" do %>
<i class="i15"></i> Add Contact
<% end %>
<br />
<br />
<table>
  <thead>
    <tr>
        <th>Contact Email Address</th>
        <th>Contact Name</th>
        <th>Title</th>
        <th>Phone</th>
  <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <% @contacts.each do |contact| %>
        <tr>
            <td><%= contact.contact_email %></td>
            <td><%= contact.contact_name %></td>
            <td><%= contact.contact_title %></td>
            <td><%= contact.contact_phone_number %></td>
    <td><%= contact.notes %></td>
        </tr>   
    <% end %>
  </tbody>      
</table>
<br />
<%= link_to "Completed", change_status_assignment_path(@assignment, status: "Completed"), method: :patch, class: "action-btn" %>

When a user clicks the New Contact button, a modal is displayed using the following form:

    <%= form_for(@contact, url: assignment_contacts_path(@assignment), remote: true) do |f| %>
    <div class="cols">
  <div class="col">
    <div class="field">
      <%= f.email_field :contact_email, autofocus: true, placeholder: "Contact email" %>
    </div>
    <div class="field">
      <%= f.text_field :contact_name, placeholder: "Contact Name" %>
    </div>
    <div class="field">
      <%= f.text_field :contact_title, placeholder: "Contact Title", class: "ico-doc" %>
    </div>
    <div class="field">
      <%= f.text_field :contact_phone_number, placeholder: "Contact Phone Number", class: "ico-phone" %>
    </div>
  </div>
  <div class="col">
    <div class="field">
      <%= f.text_field :contact_domain, placeholder: "Contact Domain", class: "ico-www" %>
    </div>
    <div class="field">
      <%= f.select :notes,  ["404 Not Found", "Page Not Loading", "Site Error", "Web Page Not Available", "Log In Required", "Privacy Error", "Blank Page",  "Redirect Url Change >>", "Contact Form Only >>", "Irrelevant >>"], { prompt: "Notes" }, { class: "ico-globe" }  %>
    </div>
    <div class = "field">
      <%= f.text_field :redirect_url_change, placeholder: "Enter Redirect URL" %>
    </div>
    <div class = "field">
      <%= f.text_field :contact_form_only, placeholder: "Enter Contact Form URL" %>
    </div>
    <div class = "field">
      <%= f.select :irrelevant, ["Foreign Site", "Lead Gen Site", "Job Listing", "Domain For Sale", "Forum", "FAQ", "Other >>"], { prompt: "Select Reason Irrelevant", style: 'display:none'} %>
    </div>
    <div class = "field">
      <%= f.text_field :other, placeholder: "Enter other reason" %>
    </div>
  </div>
    </div>

    <div class="actions">
        <%= f.submit "Submit", class: "action-btn" %>
    </div>          
<% end %>

The :redirect_url_change, :contact_form_only, :irrelevant, and :other fields on the modal are hidden by css using display:none. But, based on the option chosen in the :notes select element, the app needs to display one of these fields when a corresponding option with that value is selected.

The only way to do this in Rails that I know of is with jQuery or Coffeescript.

But, I'm not sure how to write the jQuery/Coffeescript to do this. And just as importantly, since this form is on a modal, where should this jQuery or Coffeescript be written? I've tried to just add a simple alert in the app/assets/javascript/contacts.js.coffee, but that doesn't get triggered to display. Am I putting this in the wrong place?

Please share some code you think would work for this and tell me where it should be placed.

EDIT: Thanks to Lanny I got the following jQuery working in the javascript console in the browser:

$("select[name='contact[notes]']").change(function () {
   if ($(this).val() == "Redirect Url Change >>") {
    $("input[name='contact[redirect_url_change]']").show();
    $("input[name='contact[contact_form_only]']").hide();
    $("select[name='contact[irrelevant]']").hide();
    $("input[name='contact[other]']").hide();
  }
  else if ($(this).val() == "Contact Form Only >>") {
    $("input[name='contact[redirect_url_change]']").hide();
    $("input[name='contact[contact_form_only]']").show();
    $("select[name='contact[irrelevant]']").hide();
    $("input[name='contact[other]']").hide();
  }
  else if ($(this).val() == "Irrelevant >>") {
    $("input[name='contact[redirect_url_change]']").hide();
    $("input[name='contact[contact_form_only]']").hide();
    $("select[name='contact[irrelevant]']").show();
    $("input[name='contact[other]']").hide();
  }
    else {
    $("input[name='contact[redirect_url_change]']").hide();
    $("input[name='contact[contact_form_only]']").hide();
    $("select[name='contact[irrelevant]']").hide();
    $("input[name='contact[other]']").hide();
  }
 })

$("select[name='contact[irrelevant]']").change(function () {
  if ($(this).val() == "Other >>") {
    $("textarea[name='contact[other]']").show();
  }
  else {
    $("textarea[name='contact[other]']").hide();
  }
})  

When I open up the dialog modal, paste the above into the console and then press Run it works perfectly. But, it still doesn't run in the application. I've tried to put it in the application.js and also in the contact.js, but neither one works. At this point, since the code works in the console, I suspect it might be either something needs to be run to load the code into the browser, or else something is interfering. I am running Turbolinks right now, but I don't think it is necessary for the application.

Can someone please help me get the rest of the way by showing where this needs to be put and how to call it, or assisting me in troubleshooting what is interfering?

Thanks

Let's walk through this...

I'm going to implement this rule: If a user selects, say '404' from the Notes select, make the 'redirect_url_change' input appear.

I know your exact logic might be different. Hopefully mixing-and-matching jQuery selectors can get you the rest of the way.

Using jQuery...

application.js

$(document).on("page:load", function() {
  $("select[name='contact[notes]']").change(function () {
    alert("Howdy!");
    if ($(this).val() == "404") {
      $("input[name='contact[redirect_url_change]']").css("display", "block");
    }
  });
});

One line up there is for debugging. Sometimes JS can fail in somewhat silent ways and it's hard to determine why events aren't firing. I use alert() to help highlight which things are happening, and which aren't. YMMV.

This script doesn't explicitly have to go in application.js, but it should go into a .js file in your javascripts folder so Rails compiles it into your app's JavaScript.

Some references:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM