DavyJonesLocker / client_side_validations

Client Side Validations made easy for Ruby on Rails
MIT License
2.69k stars 405 forks source link

validation generated only for one of two nested simple_field_for #568

Closed onlinetocode closed 7 years ago

onlinetocode commented 11 years ago

Hi there,

I've got a problem with a multi level nested form on the third level. I've got three models which are involved in my form.

class School < ActiveRecord::Base
  has_many :years
  validates_presence_of :name
  accepts_nested_attributes_for :years
end
class Year < ActiveRecord::Base
  belongs_to :school
  has_many :year_contacts
  validates_presence_of :year_name
  accepts_nested_attributes_for :year_contacts
end
class YearContact < ActiveRecord::Base
  belongs_to :year
  validates_presence_of :contact_name
end

This is my form:

<%= form_for @school, :validate => true do |f| %>
  <h4>School</h4>
  <%= f.label 'Name', :class => 'control-label' %>
  <%= f.text_field :name, :class => 'span12', :placeholder => "School name"  %>
  <h4>Year of Graduating</h4>
  <%= f.fields_for :years do |fo| %>
    <%= fo.label 'Year' %>
    <%= fo.text_field :year_name  %>
    <h4>Contact</h4>
    <%= fo.fields_for :year_contacts do |foo| %>
      <%= foo.label %>
      <%= foo.text_field :contact_name %>
    <% end %>
  <% end %>
  <%= f.submit %>
<% end %>

The client side validation works like a charm for the school attribute and also for the nested year attribute. But when it comes to the third level nesting it didn't work. There isn't any client side validation for the year_contacts attribute.

I'm not sure if it's a bug, a known limitation of client_side_validations or a error on my side. All known Issues I found were only for two models nested under another model but no true multi level structure like mine.

I use Rails 3.2.1 and client_side_validations 3.2.5

The form works well. All data is saved as expected.

onlinetocode commented 11 years ago

Isn't there anybody who knows if this gem works with multilevel nested forms? Would be really nice if somebody could say me if it's my fault or if this is a know limitation of this gem.

Glad for any help!

onlinetocode commented 11 years ago

Server-side validation works well!

onlinetocode commented 11 years ago

ok, i tried this multi level setting with the app of ryan bates railscast episode 263. There it works. So it seems to be a fault on my side. Have to dig deeper into my code!

onlinetocode commented 11 years ago

I don't get it. The JavaScript seems to be generated properly. I striped nearly everything away in my app to identify the error. Then it looked very similar to the working railscast app. But the validation in the simple_fields_for :yearkontakts form doesn't show up.

I updated client_side_validations to 3.2.6 but that doesn't help.

This is the generated html:

<form accept-charset="UTF-8" action="/schools" class="simple_form form-horizontal" data-validate="true" id="new_school" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="JWKD6YuWm/474gjPivE2h3e7+sKhyeSby/d6OX0/7M0=" /></div>
  <p>School</p>
  <div class="control-group string required school_name"><label class="string required control-label" for="school_name"><abbr title="required">*</abbr> Name</label><div class="controls"><input class="string required" id="school_name" name="school[name]" size="50" type="text" /></div></div>
  <div class="control-group string required school_street"><label class="string required control-label" for="school_street"><abbr title="required">*</abbr> Street</label><div class="controls"><input class="string required" id="school_street" name="school[street]" size="50" type="text" /></div></div>
  <div class="control-group string required school_plz"><label class="string required control-label" for="school_plz"><abbr title="required">*</abbr> Plz</label><div class="controls"><input class="string required" id="school_plz" name="school[plz]" size="50" type="text" /></div></div>
  <div class="control-group string required school_city"><label class="string required control-label" for="school_city"><abbr title="required">*</abbr> City</label><div class="controls"><input class="string required" id="school_city" name="school[city]" size="50" type="text" /></div></div>
  <div class="control-group select required school_state_id"><label class="select required control-label" for="school_state_id"><abbr title="required">*</abbr> State</label><div class="controls"><select class="select required" id="school_state_id" name="school[state_id]"><option value=""></option>
<option value="2">Baden-Württemberg</option>
<option value="3">Bayern</option>
<option value="4">Berlin</option>
<option value="5">Brandenburg</option>
<option value="6">Bremen</option>
<option value="7">Hamburg</option>
<option value="8">Hessen</option>
<option value="9">Mecklenburg-Vorpommern</option>
<option value="10">Niedersachsen</option>
<option value="11">Nordrhein-Westfalen</option>
<option value="12">Rheinland-Pfalz</option>
<option value="13">Saarland</option>
<option value="14">Sachsen</option>
<option value="15">Sachsen-Anhalt</option>
<option value="16">Schleswig-Holstein</option>
<option value="17">Thüringen</option></select></div></div>
  <p>
    Year</p>

    <div class="control-group select required school_years_jahrgang_id"><label class="select required control-label" for="school_years_attributes_0_jahrgang_id"><abbr title="required">*</abbr> Jahrgang</label><div class="controls"><select class="select required" id="school_years_attributes_0_jahrgang_id" name="school[years_attributes][0][jahrgang_id]"><option value=""></option>
<option value="4">2012 / 2013</option>
<option value="5">2013 / 2014</option></select></div></div>
    <div class="control-group select required school_years_count_id"><label class="select required control-label" for="school_years_attributes_0_count_id"><abbr title="required">*</abbr> Count</label><div class="controls"><select class="select required" id="school_years_attributes_0_count_id" name="school[years_attributes][0][count_id]"><option value=""></option>
<option value="2">weniger als 40</option>
<option value="3">40 - 60</option>
<option value="4">60 - 80</option>
<option value="5">80 - 100</option>
<option value="6">100 - 120</option>
<option value="7">120 - 140</option>
<option value="8">140 - 160</option>
<option value="9">mehr als 160</option></select></div></div>
    <div class="control-group select required school_years_schuldauer_id"><label class="select required control-label" for="school_years_attributes_0_schuldauer_id"><abbr title="required">*</abbr> Schuldauer</label><div class="controls"><select class="select required" id="school_years_attributes_0_schuldauer_id" name="school[years_attributes][0][schuldauer_id]"><option value=""></option>
<option value="2">12 Jahre</option>
<option value="3">13 Jahre</option>
<option value="4">12 und 13 Jahre</option></select></div></div>
    <p>
      Contact</p>

      <div class="control-group select required school_years_yearkontakts_sex"><label class="select required control-label" for="school_years_attributes_0_yearkontakts_attributes_0_geschlecht_id"><abbr title="required">*</abbr> Sex</label><div class="controls"><select class="select required" id="school_years_attributes_0_yearkontakts_attributes_0_geschlecht_id" name="school[years_attributes][0][yearkontakts_attributes][0][geschlecht_id]"><option value=""></option>
<option value="2">Herr</option>
<option value="4">Frau</option></select></div></div>
      <div class="control-group string required school_years_yearkontakts_vorname"><label class="string required control-label" for="school_years_attributes_0_yearkontakts_attributes_0_vorname"><abbr title="required">*</abbr> Vorname</label><div class="controls"><input class="string required" id="school_years_attributes_0_yearkontakts_attributes_0_vorname" name="school[years_attributes][0][yearkontakts_attributes][0][vorname]" size="50" type="text" /></div></div>
      <div class="control-group string required school_years_yearkontakts_nachname"><label class="string required control-label" for="school_years_attributes_0_yearkontakts_attributes_0_nachname"><abbr title="required">*</abbr> Nachname</label><div class="controls"><input class="string required" id="school_years_attributes_0_yearkontakts_attributes_0_nachname" name="school[years_attributes][0][yearkontakts_attributes][0][nachname]" size="50" type="text" /></div></div>
      <div class="control-group email required school_years_yearkontakts_email"><label class="email required control-label" for="school_years_attributes_0_yearkontakts_attributes_0_email"><abbr title="required">*</abbr> Email</label><div class="controls"><input class="string email required" id="school_years_attributes_0_yearkontakts_attributes_0_email" name="school[years_attributes][0][yearkontakts_attributes][0][email]" size="50" type="email" /></div></div>
      <div class="control-group text optional school_years_yearkontakts_notizen"><label class="text optional control-label" for="school_years_attributes_0_yearkontakts_attributes_0_notizen">Notizen</label><div class="controls"><textarea class="text optional" cols="40" id="school_years_attributes_0_yearkontakts_attributes_0_notizen" name="school[years_attributes][0][yearkontakts_attributes][0][notizen]" rows="20"></textarea></div></div>
  <input name="commit" type="submit" value="Create School" />
</form>

And this the generated JavaScript:

<script>//<![CDATA[
if(window.ClientSideValidations===undefined)window.ClientSideValidations={};window.ClientSideValidations.disabled_validators=[];window.ClientSideValidations.number_format={"separator":".","delimiter":","};if(window.ClientSideValidations.patterns===undefined)window.ClientSideValidations.patterns = {};window.ClientSideValidations.patterns.numericality=/^(-|\+)?(?:\d+|\d{1,3}(?:\,\d{3})+)(?:\.\d*)?$/;if(window.ClientSideValidations.forms===undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['new_school'] = {"type":"SimpleForm::FormBuilder","error_class":"help-inline","error_tag":"span","wrapper_error_class":"error","wrapper_tag":"div","wrapper_class":"control-group","wrapper":"bootstrap","validators":{"school[years_attributes][][yearkontakts_attributes][][geschlecht_id]":{"presence":[{"message":"can't be blank"}]},"school[years_attributes][][yearkontakts_attributes][][vorname]":{"presence":[{"message":"can't be blank"}]},"school[years_attributes][][yearkontakts_attributes][][nachname]":{"presence":[{"message":"can't be blank"}]},"school[years_attributes][][yearkontakts_attributes][][email]":{"presence":[{"message":"can't be blank"}]},"school[years_attributes][][jahrgang_id]":{"presence":[{"message":"can't be blank"}]},"school[years_attributes][][count_id]":{"presence":[{"message":"can't be blank"}]},"school[years_attributes][][schuldauer_id]":{"presence":[{"message":"can't be blank"}]},"school[name]":{"length":[{"messages":{"minimum":"is too short (minimum is 4 characters)"},"allow_blank":true,"minimum":4}],"presence":[{"message":"can't be blank"}]},"school[street]":{"presence":[{"message":"can't be blank"}]},"school[plz]":{"presence":[{"message":"can't be blank"}]},"school[city]":{"presence":[{"message":"can't be blank"}]},"school[state_id]":{"presence":[{"message":"can't be blank"}]}}};
//]]></script>

This is my school_controller:

class SchoolsController < ApplicationController
  # GET /schools/new
  # GET /schools/new.json
  def new
    @school = School.new
    @year = @school.years.build
    @yearkontakt = @year.yearkontakts.build
    @standardformat = @school.standardformats.build
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @school }
    end
  end

end

This my form:

<%= simple_form_for @school, :html => { :class => "form-horizontal"}, :validate => true do |s| %>
  <p>School</p>
  <%= s.input :name %>
  <%= s.input :street %>
  <%= s.input :plz %>
  <%= s.input :city%>
  <%= s.input :state_id, collection: State.all %>
  <p>
    Year</p>
  <%= s.simple_fields_for :years, :year do |y| %>
    <%= y.input :jahrgang_id, collection: Yearname.yearnames_aktuell_future %>
    <%= y.input :count_id, collection: Count.all%>
    <%= y.input :schuldauer_id, collection: Length.all %>
    <p>
      Contact</p>
    <%= y.simple_fields_for :yearkontakts, :yearkontakt do |yk| %>
      <%= yk.association :sex %>
      <%= yk.input :vorname %>
      <%= yk.input :nachname %>
      <%= yk.input :email %>
      <%= yk.input :notizen  %>
    <% end %>
  <% end %>
  <%= s.submit %>
<% end %>

And here are my three models

class School < ActiveRecord::Base
  has_many :years, :dependent => :destroy
  belongs_to :state
  validates_length_of :name, :minimum => 4, :allow_blank => true
  validates_presence_of :name
  validates_presence_of :street
  validates_presence_of :state_id
  validates_presence_of :plz
  validates_presence_of :city
  accepts_nested_attributes_for :years
end
class Year < ActiveRecord::Base
  has_many :yearkontakts, :dependent => :destroy
  belongs_to :count
  belongs_to :yearname, :foreign_key => "jahrgang_id"
  belongs_to :length, :foreign_key => "schuldauer_id"
  belongs_to :school
  validates_presence_of :jahrgang_id
  validates_presence_of :schuldauer_id
  validates_presence_of :count_id
  accepts_nested_attributes_for :yearkontakts
end
class Yearkontakt < ActiveRecord::Base
    belongs_to :sex, :foreign_key => :geschlecht_id
    belongs_to :year
    validates_presence_of :vorname
    validates_presence_of :nachname
    validates_presence_of :geschlecht_id
    validates_presence_of :email
end
sumanranjanpanda commented 7 years ago

Hi, I am facing the exact issue. Did you able to fix this issue? Please let me know how you fixed this. I am using Rails 4.2.7.1, Ruby 2.3.0 & client_side_validations-4.2.11 with simple_form

Thanks

tagliala commented 7 years ago

Hi,

I'm shutting down old issues.

If it still is an issue, feel free to open a new one but make sure it meets our Contributing Guidelines

Please note that if simple_form is involved, then the proper repo to report this is --> https://codeclimate.com/github/DavyJonesLocker/client_side_validations-simple_form