user2675010
user2675010

Reputation:

Dynamically changing form fields from previously selected fields, iterative javascript

My question is almost similar to this one. Just a slight difference.

I have two models- Family and Person with has_many from family to person and accepts_nested_attributes_for :persons in family.rb

In my FamiliesController I have edit method for editing the records.There I'm using nested forms for a family and the corresponding persons. (So a single family can have many persons)

In my edit.html.erb I have form like:

<%= simple_form_for @family do |f| %>
  #family fields here
  <%= f.simple_fields_for :persons do |p| %>
   <%= p.input :gender,as: :radio_buttons,collection: ["Male","Female"],wrapper_html: {id: "gender"} %>
   <%= p.input :question,wrapper_html: {id: "question"} %>
  <% end %>
  <%= f.submit "Submit" %>
<% end %>  

(Similar to the question as in the link)

And I applied the same javascript as mentioned in the answer. (here)

    $(function(){
    var toggle_gender = function(visible) {
        if (visible){
            $("#question").show();
        } else {
            $("#question").hide();
        }
    }

    $("#gender input").change(function(){
        toggle_gender($(this).val()=="Male")
    })

    toggle_gender($("#gender input:checked").val()=="Male")
})();  

Generated HTML:

<div class="control-group radio_buttons required family_persons_gender gender">
 <label class="radio_buttons required control-label">
  <abbr title="required">*</abbr>
  Gender
 </label>
 <div class="controls">
  <label class="radio">
   <input id="family_persons_attributes_1_gender_male" class="radio_buttons required" type="radio" value="Male" name="family[persons_attributes][1][gender]" checked="checked">
Male
  </label>
  <label class="radio">
   <input id="family_persons_attributes_1_gender_female" class="radio_buttons required" type="radio" value="Female" name="family[persons_attributes][1][gender]">
Female
  </label>
 </div>
</div>  

<div class="control-group string required family_persons_mobnum mobnum">
 <label class="string required control-label" for="family_persons_attributes_1_mobnum">
  <abbr title="required">*</abbr>
  Mobile No.
 </label>
 <div class="controls">
  <input id="family_persons_attributes_1_mobnum" class="string required" type="text" value="9099067758" size="50" name="family[persons_attributes][1][mobnum]">
 </div>
</div>  

But this only works for the first person. Meaning If I have 1 family and 3 persons the javascript only works for the first person. Why so?

Meaning If there are 2 persons and I change the gender in 2nd person the javascript works on the first person and not on the 2nd person

How do I fix this problem?

I read somewhere to use iterative javascript (some even said underscore.js).

Or suggest any alternative way to do this

Upvotes: 1

Views: 1197

Answers (1)

tihom
tihom

Reputation: 8003

This is because your are using id to get the DOM elements. A page is supposed to have unique ids so jQuery matches the first element it finds with that id. You need to use class. Change the html and functions to sthing like this (code not tested so beware):

<%= simple_form_for @family do |f| %>
  #family fields here
  <%= f.simple_fields_for :persons do |p| %>
   <%= p.input :gender,as: :radio_buttons,collection: ["Male","Female"],wrapper_html: {class: "gender"} %>
   <%= p.input :question,wrapper_html: {class: "question"} %>
  <% end %>
  <%= f.submit "Submit" %>
<% end %>


  $(function(){
    var toggle_gender = function(elem) {
       elem.closest(".gender").siblings('.question').toggle(elem.val() =="Male");

    }

    $(".gender input").change(function(){
       toggle_gender($(this))
    })

    $(".gender input:checked").each(function(){
       toggle_gender($(this))
    })

 })();  

Upvotes: 1

Related Questions