简体   繁体   中英

Rails 4 - Rendering partial with AJAX/JS

I need to add some AJAX/JS functionality to my rails application.

This is the page I'm working on: 在此处输入图片说明

To display the content of the tab above, I'm calling

<%= render 'tape_bulk_cocs/sporeCounts' %>

Inside this partial is the following code (minus the html tags to display text):

 <div id="samples">
    <% if @tape_bulk_coc.tape_bulk_coc_samples.any? %>    
       <% @tape_bulk_coc.tape_bulk_coc_samples.each do |cur| %>  
          <% if !cur.spore_type_count %>
             <%= link_to 'Add Spore Count', new_spore_type_count_path(:tape_bulk_coc_sample_id=>cur.id), :remote=>true, :id => "new_spore_count", class: "tiny button expanded" %>
          <% end %>
       <% end %>
    <% end %>
 </div>

Inside my spore_type_counts_controller/new I have:

  def new
    @spore_type_count = SporeTypeCount.new
    @tape_bulk_sample_id = params[:tape_bulk_coc_sample_id]
    @category_count = [["Rare: 1 to 10","Rare: 1 to 10"], ["Low: 11 to 100","Low: 11 to 100"], ["Medium: 101 to 1000","Medium: 101 to 1000"], ["High: > 1000","High: > 1000"]]

    respond_to do |format|
      format.js
    end
  end

Then, in app/views/spore_type_counts/new.js.erb

$('#samples').hide().after( '<%= j render("spore_type_counts/form") %>' );

So far everything works as intended, and when I click "Add Spore Count" the tab changes to appear like so: 在此处输入图片说明

This is where the problem I'm having happens.

When I submit the spore_type_counts/form I go into the create action for the controller which is this:

  def create
    @spore_type_count = SporeTypeCount.new(spore_type_count_params)

    respond_to do |format|
      if @spore_type_count.save
        format.js { render 'tape_bulk_cocs/sporeCounts'}
      end
    end
  end

Once here, everything submits to the database correctly, but the page does not change. I cannot figure out how to re-render the tape_bulk_cocs/sporeCounts partial (first picture).

Essentially, once I submit the form, I need to get from the spore_type_count_controller/new back to the tape_bulk_coc_controller/show and update my objects, without refreshing the page.

How can I do this? Or do I need to restructure my application to work differently?

You need to update the DOM using the content from the partial, much like you did in the new.js.erb template. Right now you are just saying "render this partial" but the page does not know how to update itself with that content unless you tell it how to via JavaScript.

Try creating a spore_type_counts/create.js.erb file which will be executed after the SporeTypeCounts#create action is run. Inside that template, add the JavaScript code which will update your page using the content that you render from the partial.

For example,

// hide the previous content
$("#spore-count-form").remove();

// show the new content
$('#samples').html("<%= j render('tape_bulk_cocs/sporeCounts') %>");

A few things to note:

  • Update the selectors above to fit your app. I usually use data-attributes to mark something that I'm going to manipulate using JavaScript (eg data-ujs-target=spore-form ). That way the JS interactions don't get broken by someone accidentally changing an ID or CSS class.

  • You may have to update your markup in order to modify it using jQuery.

  • If tape_bulk_cocs/sporeCounts uses any instance variables, make sure they are defined within the the SporeTypeCounts#create action otherwise the partial won't render. ( NOTE : you really should avoid using instance variables within partials for this reason)

Hope that helps!

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