Reputation: 695
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?
Upvotes: 0
Views: 780
Reputation: 7434
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 (e.g. 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!
Upvotes: 1