Reputation: 25
I am trying to get an ajax 'delete' button to work.
The button is deleting the object from my database, but is not updating the index page. so, the deleted object is still present in index until you refresh the page.
In my view:
<%= link_to "Delete Fabric", delete_fabric_path(fabric), method: :delete, data: { confirm: 'Are you sure?' }, :remote => true, :class => 'delete_fabric', class: "btn btn-primary btn-sm"%>
Routes:
delete "/fabrics/:id" => "fabrics#destroy", as: 'delete_fabric'
get "/fabrics/collection" => "fabrics#index", as: "index_fabrics"
Controller:
def destroy
@fabric = Fabric.find(params[:id])
@fabric.destroy
respond_to do |format|
format.html { redirect_to index_fabrics_url }
format.json { head :no_content }
format.js { render layout: false }
end
end
destroy.js.erb:
$('.delete_fabric').bind('ajax:success', function() {
$(this).closest('tr').fadeOut();
});
If anyone has an idea of where I am going wrong, it would be much appreciated! Thanks.
This is the tutorial I was following.
Server logs:
Started DELETE "/fabrics/46" for 127.0.0.1 at 2018-08-17 15:57:22 +0800
Processing by FabricsController#destroy as JS
Parameters: {"id"=>"46"}
Fabric Load (1.4ms) SELECT "fabrics".* FROM "fabrics" WHERE "fabrics"."id" = $1 LIMIT $2 [["id", 46], ["LIMIT", 1]]
↳ app/controllers/fabrics_controller.rb:70
(0.4ms) BEGIN
↳ app/controllers/fabrics_controller.rb:71
Fabric Destroy (0.5ms) DELETE FROM "fabrics" WHERE "fabrics"."id" = $1 [["id", 46]]
↳ app/controllers/fabrics_controller.rb:71
(6.3ms) COMMIT
↳ app/controllers/fabrics_controller.rb:71
Rendering fabrics/destroy.js.erb
Rendered fabrics/destroy.js.erb (9.4ms)
Completed 200 OK in 83ms (Views: 30.4ms | ActiveRecord: 8.6ms)
Full view:
<!-- SHOW FABRIC COLLECTION / FABRIC OPTIONS-->
<div class="card-deck">
<% @fabrics.each do |fabric| %>
<div class="col-sm-6 col-md-4 col-lg-3">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="<%=fabric.image%>">
<div class="card-body">
<h5 class="card-title"><%= fabric.fabric_name%></h5>
<p class="card-text"><%= fabric.fabric_description%></p>
<p class="card-text"><%= fabric.printed%></p>
<!-- Listing fibre types -->
<p class="card-text"><small class="text-muted">Composition:
<% fabric.fibre.each do |fibre| %>
<%=fibre %>
<%end%>
</small></p>
<!-- Listing colours -->
<p class="card-text"><small class="text-muted">Colours:
<% fabric.colour.each do |colour| %>
<%=colour %>
<%end%>
</small></p>
<!-- Listing suitable for -->
<p class="card-text"><small class="text-muted">Suitable For:
<% fabric.suitable_for.each do |item| %>
<%=item %>
<%end%>
</small></p>
<!-- Show page button -->
<%= link_to "Full Details", show_fabrics_path(fabric), class: "btn btn-primary btn-sm" %>
<!-- AJAX DELETE BUTTON IN PROGRESS-->
<%= link_to "Delete Fabric", delete_fabric_path(fabric), method: :delete, data: { confirm: 'Are you sure?' }, :remote => true, :class => 'delete_fabric'%>
<!-- AJAX DELETE BUTTON -->
</div>
</div>
</div>
<% end %>
</div>
Full, full view:
<!-- MODEL FOR UPLOAD FABRIC -->
<!-- Button trigger modal -->
</br><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Add Fabric to collection
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Fabric</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!-- Form to add fabric -->
<%= form_with scope: :fabrics, url: new_fabrics_path, local: true do |form| %>
<p>
<%= form.label :fabric_name %><br>
<%= form.text_field :fabric_name %>
<%= form.label :fabric_description %><br>
<%= form.text_field :fabric_description %>
<%= form.label :purchased_from %><br>
<%= form.text_field :purchased_from %>
<%= form.label :meterage %><br>
<%= form.select :meterage, (0..500) %>
<%= form.label :select_fibres %><br>
<%@fibres.each do |fibre|%>
<%= form.label fibre %>
<%= form.check_box :fibre, {multiple: true}, fibre.to_s, nil %></br>
<% end %>
<%= form.label :main_fabric_colours %><br>
<%@colours.each do |colour|%>
<%= form.label colour %>
<%= form.check_box :colour, {multiple: true}, colour.to_s, nil %></br>
<% end %>
<%= form.label :suitable_for %><br>
<%@suitable_for.each do |item|%>
<%= form.label item %>
<%= form.check_box :suitable_for, {multiple: true}, item.to_s, nil %></br>
<% end %>
<%= form.label :printed? %><br>
<%= form.check_box :printed %><br>
<%= form.submit "Add Fabric" %>
</p>
<% end %>
<!-- Form to add fabric -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Add Fabric</button>
</div>
</div>
</div>
</div></br></br>
<!-- MODEL FOR UPLOAD FABRIC -->
<!-- FILTER BAR -->
<% if @filtered == true %>
<%= form_with scope: :filter, url: filter_fabrics_path, local: true do |form| %>
<p>
<%= form.select(:fibre, ['Silk', 'Linen', 'Cotton', 'Bamboo'], {:prompt => "Fibre Type"}) %>
<%= form.select(:colour, ['Blue', 'Yellow', 'Purple', 'Green'], {:prompt => "Select Colour"}) %>
<%= form.select(:suitable_for, ['Pants', 'Skit', 'Shirt', 'Skirt'], {:prompt => "Suitable For"}) %>
<%= form.submit "Filter Results" %>
</p>
<% end %>
<% else %>
<%= form_with scope: :filter, url: filter_fabrics_path, local: true do |form| %>
<p>
<%= form.select(:fibre, ['Silk', 'Linen', 'Cotton', 'Bamboo'], {:prompt => "Fibre Type"})%>
<%= form.select(:colour, ['Blue', 'Yellow', 'Purple', 'Green'], {:prompt => "Select Colour"})%>
<%= form.select(:suitable_for, ['Pants', 'Skit', 'Shirt', 'Skirt'], {:prompt => "Suitable For"})%>
<%= form.submit "Filter Results" %>
</p>
<% end %>
<% end %>
<!-- FILTER BAR -->
<!-- DISPLAYS CURRENTLY SELECTED FIELDS IF @FILTERED VIEW -->
<p><% if @filtered == true %>
<% if @selected_fibre != "Fibre Type" %>
<%= "Filtering by Fibre: #{@selected_fibre} "%>
<% end %></br>
<% if @selected_colour != "Select Colour" %>
<%= "Filtering by Colour: #{@selected_colour} "%>
<% end %></br>
<% if @selected_suitable_for != "Suitable For" %>
<%= "Filtering by Project: #{@selected_suitable_for} "%></p>
<% end %></p>
<%= link_to "Clear Filters", index_fabrics_path, class: "btn btn-primary btn-sm" %><br><br>
<% end %>
<!-- SWITCHES STATEMENT BASED ON FILTERED YES/NO-->
<% if @fabrics.length == 0 %>
<h4> NO SEARCH RESULTS (PROMOTE FABRICS THAT MATCH SEARCH FROM RETAILER) </h4></br>
<% else %>
<% if @filtered == true %>
<h4> OPTIONS FOR YOUR SEWING PROJECT</h4></br>
<% else %>
<h4> YOUR FABRIC COLLECTION</h4></br>
<% end %>
<% end %>
<!-- SHOW FABRIC COLLECTION / FABRIC OPTIONS-->
<div class="card-deck">
<% @fabrics.each do |fabric| %>
<div class="col-sm-6 col-md-4 col-lg-3">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="<%=fabric.image%>">
<div class="card-body">
<h5 class="card-title"><%= fabric.fabric_name%></h5>
<p class="card-text"><%= fabric.fabric_description%></p>
<p class="card-text"><%= fabric.printed%></p>
<!-- Listing fibre types -->
<p class="card-text"><small class="text-muted">Composition:
<% fabric.fibre.each do |fibre| %>
<%=fibre %>
<%end%>
</small></p>
<!-- Listing colours -->
<p class="card-text"><small class="text-muted">Colours:
<% fabric.colour.each do |colour| %>
<%=colour %>
<%end%>
</small></p>
<!-- Listing suitable for -->
<p class="card-text"><small class="text-muted">Suitable For:
<% fabric.suitable_for.each do |item| %>
<%=item %>
<%end%>
</small></p>
<!-- Show page button -->
<%= link_to "Full Details", show_fabrics_path(fabric), class: "btn btn-primary btn-sm" %>
<!-- AJAX DELETE BUTTON IN PROGRESS-->
<%= link_to "Delete Fabric", delete_fabric_path(fabric), method: :delete, data: { confirm: 'Are you sure?' }, :remote => true, :class => 'delete_fabric'%>
<!-- AJAX DELETE BUTTON -->
</div>
</div>
</div>
<% end %>
</div>
Upvotes: 0
Views: 793
Reputation: 10287
Rolandas solution should helps you resolve your issue.
On the server side, the deletion is properly happening and you're rendering the correct partial (the destroy.js.erb file.)
Additional debugging: Add a console.log($(this).closest('tr'))
in your event listener for the ajax success
.
Your javascript should looks like that:
console.log('Binding event');
$('.delete_fabric').bind('ajax:success', function() {
console.log('fading the element: ', $(this).closest('tr'));
$(this).closest('tr').fadeOut();
});
Upvotes: 1
Reputation: 6531
Add unique id for each fabric
record i.e (id="fabric_<%=fabric.id%>"
)
<!-- SHOW FABRIC COLLECTION / FABRIC OPTIONS-->
<div class="card-deck">
<% @fabrics.each do |fabric| %>
<div class="col-sm-6 col-md-4 col-lg-3" id="fabric_<%=fabric.id%>">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="<%=fabric.image%>">
<div class="card-body">
<h5 class="card-title"><%= fabric.fabric_name%></h5>
<p class="card-text"><%= fabric.fabric_description%></p>
<p class="card-text"><%= fabric.printed%></p>
<!--Listing fibre types -->
<p class="card-text"><small class="text-muted">Composition:
<% fabric.fibre.each do |fibre| %>
<%=fibre %>
<%end%>
</small>
</p>
<!--Listing colours -->
<p class="card-text"><small class="text-muted">Colours:
<% fabric.colour.each do |colour| %>
<%=colour %>
<%end%>
</small>
</p>
<!--Listing suitable for -->
<p class="card-text"><small class="text-muted">Suitable For:
<% fabric.suitable_for.each do |item| %>
<%=item %>
<%end%>
</small>
</p>
<!--Show page button -->
<%= link_to "Full Details", show_fabrics_path(fabric), class: "btn btn-primary btn-sm" %>
<!--AJAX DELETE BUTTON IN PROGRESS-->
<%= link_to "Delete Fabric", delete_fabric_path(fabric), method: :delete, data: { confirm: 'Are you sure?' }, :remote => true, :class => 'delete_fabric'%>
<!--AJAX DELETE BUTTON -->
</div>
</div>
</div>
<% end %>
</div>
In controller:-
def destroy
@fabric = Fabric.find(params[:id])
if @fabric.destroy
flash[:success] = "Fabric deleted successfully!"
end
respond_to do |format|
format.html { redirect_to index_fabrics_url }
format.json { head :no_content }
format.js { render layout: false }
end
end
In destroy.js.erb
<%if flash[:success].present?%>
$("#fabric_<%=params[:id]%>").fadeOut();
//$("#fabric_<%=params[:id]%>").remove();
<%end%>
Upvotes: 0
Reputation: 360
You're defining class twice:
:class => 'delete_fabric', class: "btn btn-primary btn-sm"
try combining those two:
class: "btn btn-primary btn-sm delete_fabric"
Upvotes: 0