JQuery not updating nested form in Rails

I am following Railcasts 197 to make a nested form in my application. I am trying to show a "delete" link that hides a row from a form using jQuery.

enter image description here

If I click on delete, nothing happens, but if I click Submit and errors appear on the page, the line is deleted!

enter image description here

I've been trying to fix it for days but I just can't see if something is missing or I need to add something, any help would be appreciated.

code:

model / album _review_proposal.rb

class AlbumReviewProposal < ActiveRecord::Base
  attr_accessible :description, :user_id, :album_attributes
  validates :description, :presence => true

  has_one :album, :dependent => :destroy
  accepts_nested_attributes_for :album , :allow_destroy => true
end

      

model /album.rb

class Album < ActiveRecord::Base
  attr_accessible :album_name, :artist,  :year, :tracks_attributes

  validates :album_name, :artist, :presence => true
  validates :year, :numericality => { :only_integer => true }

  belongs_to :album_review_proposal
  has_many :tracks
  accepts_nested_attributes_for :tracks, :allow_destroy => true
end

      

model /track.rb

class Track < ActiveRecord::Base
  attr_accessible :track_name, :track_number

  validates :track_name, :track_number,  :presence => true

  belongs_to :album
end

      

view / album _review_proposals / _form.html.erb

<%= form_for(@album_review_proposal) do |f| %>
  <% if @album_review_proposal.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@album_review_proposal.errors.count, "error") %> prohibited this album_review_proposal from being saved:</h2>

      <ul>
      <% @album_review_proposal.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

    <%= f.fields_for :album do |album| %>
        <div class="field">
          <%= album.label :album_name %><br />
          <%= album.text_field :album_name %>
        </div>
        <div class="field">
          <%= album.label :artist %><br />
          <%= album.text_field :artist %>
        </div>
        <div class="field">
          <%= album.label :year %><br />
          <%= album.text_field :year %>
        </div>

        <div class="field">
          <%= f.label :description %><br />
          <%= f.text_area :description %>
        </div>

        <legend>Tracks</legend>
        <table>
            <th>#</th>
            <th>Name</th>
            <th></th>

            <%= album.fields_for :tracks do |track|  %>
            <tr>
            <div  class="fields">
                <td><%= track.text_field :track_number, :size => 2 %></td>
                <td><%= track.text_field :track_name, :size => 50 %> </td>

              <td><%= track.hidden_field :_destroy %></td>
                <td><%= link_to_remove_fields "remove", track   %></td>
            </div>
            </tr>
            <% end %>
        </table>

    <% end %>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

      

controllers / album_review_proposals.controller.rb (only modified method from the scaffold)

  def new
    @album_review_proposal = AlbumReviewProposal.new

    @album = @album_review_proposal.build_album

    4.times { @album.tracks.build }

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @album_review_proposal  }
    end
  end

      

application.js

//= require jquery
//= require jquery_ujs
//= require_tree .

function remove_fields(link) {
    $(link).prev("input[type=hidden]").val("1");
    $(link).closest(".fields").hide();
}

function add_fields(link, association, content) {
    var new_id = new Date().getTime();
    var regexp = new RegExp("new_" + association, "g")
    $(link).parent().before(content.replace(regexp, new_id));
}

      

application_helper.rb

module ApplicationHelper
  def link_to_remove_fields(name, f)
    f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
  end

  def link_to_add_fields(name, f, association)
    new_object = f.object.class.reflect_on_association(association).klass.new
    fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
      render(association.to_s.singularize + "_fields", :f => builder)
    end
    link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")
  end


end

      

HTML part of HTML I want to remove

 <legend>Tracks</legend>
        <table>
          <thead>
          <tr>
            <th>#</th>
            <th>Name</th>
            <th></th>
          </tr>
          </thead>
          <tbody>

            <div class="fields">
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_0_track_number" name="album_review_proposal[album_attributes][tracks_attributes][0][track_number]" size="2" type="text" /></td>
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_0_track_name" name="album_review_proposal[album_attributes][tracks_attributes][0][track_name]" size="50" type="text" /></td>
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_0__destroy" name="album_review_proposal[album_attributes][tracks_attributes][0][_destroy]" type="hidden" value="false" /><a href="#" onclick="remove_fields(this); return false;">remove</a></td>
            </tr>

            <div class="fields">
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_1_track_number" name="album_review_proposal[album_attributes][tracks_attributes][1][track_number]" size="2" type="text" /></td>
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_1_track_name" name="album_review_proposal[album_attributes][tracks_attributes][1][track_name]" size="50" type="text" /></td>
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_1__destroy" name="album_review_proposal[album_attributes][tracks_attributes][1][_destroy]" type="hidden" value="false" /><a href="#" onclick="remove_fields(this); return false;">remove</a></td>
            </tr>

            <div class="fields">
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_2_track_number" name="album_review_proposal[album_attributes][tracks_attributes][2][track_number]" size="2" type="text" /></td>
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_2_track_name" name="album_review_proposal[album_attributes][tracks_attributes][2][track_name]" size="50" type="text" /></td>
              <td><input id="album_review_proposal_album_attributes_tracks_attributes_2__destroy" name="album_review_proposal[album_attributes][tracks_attributes][2][_destroy]" type="hidden" value="false" /><a href="#" onclick="remove_fields(this); return false;">remove</a></td>
            </tr>

            <!-- repeat 3 times... -->
            </tr>
          </tbody>
        </table>

      

+3


source to share


1 answer


In your view, views/album_review_proposals/_form.html.erb

instead of adding a class fields

in div

inside each tr

track, add it directly to tr

. The problem is that the div doesn't behave as expected when added inside a table row.



+2


source







All Articles