0

I currently have a simple form_for that deletes an object. Right now it's a static page that refreshes every time the object is deleted. We are getting a customer request that would like the index page to delete the object without refreshing the page. Obviously ajax can fix this problem but I have very limited experience with javascript. If someone could point me in the right direction I would greatly appreciate it. Here is my code for clarity.

FORM

This is the form that pops up the modal when delete is pressed.

 <%= link_to 'Delete', delete_snitch_path(snitch), rel: 'modal:open',
   data: { tooltip: "Delete" },
   class: 'icon icon-delete delete', title: "Delete #{snitch.name}" %>

-

 <%= form_for @snitch, html: { class: "form-actions", method: 'delete' } do |form| %>
 <span class="button-text"><%= link_to 'NO WAY!', home_base_url_or_default(root_path), rel: "modal:close" %></span>
 <input type="submit" class="button button--modal" value="Yes, delete it.">
 <% end %> 

Controller

  def destroy
    DestroySnitch.perform(snitch: @snitch)

    respond_to do |format|

      format.html do
        redirect_to snitches_path, notice: "Snitch was successfully deleted."
      end

      format.json do
        render json: @snitch.all
      end

    end
  end  

VIEW

<table class="snitch-list">
  <%= render partial: 'snitch', collection: @presenter.snitches %>
</table>

CURRENT JS (NOT WORKING OBVI)

$('ajax').bind('ajax:success', function() {
    $(this).closest('tr').fadeOut();
});

Entire snitch partial

  <tbody>
  <tr class="<%= snitch.classes %>">
    <td>
        <%= link_to "<span class='icon led'></span><span>#{snitch.name}</span>".html_safe, snitch_path(snitch), class: "name"%>
    </td>
    <td class="interval"><span class="vspace"><%= snitch.interval %></span></td>
    <td class="last-checked">
      <span class="vspace">
        <% if snitch.source.checked_in_healthy_at %>
          <span data-tooltip="Checked in healthy at UTC(<%= snitch.source.checked_in_healthy_at.to_i %>) || LOCAL(<%= snitch.source.checked_in_healthy_at.to_i %>)">
            Last seen <strong><%= snitch.checked_in_healthy_at(title: nil) %></strong>
          </span>
        <% else %>
          <strong><%= snitch.checked_in_healthy_at %></strong>
        <% end %>
      </span>
    </td>
    <td class="snitch-controls" data-icons="<%= snitch.pauseable? ? "5" : "4" %>">
      <%= render 'menu', snitch: snitch %>
      <nav class="snitch-states" >
        <% if snitch.pauseable? %>
          <%= link_to 'Pause', pause_snitch_path(snitch), class: 'icon icon-pause pause',
            data: { tooltip: "Pause" },
            rel: "modal:open" %>
        <% end %>

        <%= link_to 'Delete', delete_snitch_path(snitch), rel: 'modal:open',
          data: { tooltip: "Delete" },
          class: 'icon icon-delete delete', title: "Delete #{snitch.name}" %>
        </nav>
    </td>
  </tr>
</tbody>

I dont have any javascript in place and I'm starting this story just now but I'm already getting confused while googling. also, is there a good way to test ajax with Rspec and Capybara?

3
  • In order to answer this I need the code for the modal that pops up asking for the confirmation. The ajax will be tied to that button, not the button in the form. Can you post the modal code? Also it would be helpful to have the code for the page this item is on, that way the code to hide or remove the div can be in an answer as well. Commented Sep 30, 2016 at 19:11
  • @RockwellRice Updated. Let me know if you need more Commented Sep 30, 2016 at 19:25
  • I do not see the html for the modal, It looks like the button in the form opens the modal correct? The actual delete will happen when the button inside the modal is pressed so that is the button I need to see to write the code. Also, give the code inside that partial, I need to see the actual div that will be removed or hidden. Commented Sep 30, 2016 at 19:28

2 Answers 2

1

Attach a class to the button (my ajax here uses "delete-snitch") that confirms the delete in the modal.

Add the "data-snitch-id" property to that button. You will need the id of the object in there to delete the right object.

(This needs to be added to the button in the modal, the one being clicked.)

<button class="delete-snitch ...any other classes..." data-snitch-id="<%= snitch.id %>"> ... </button>

In your javascript file put something like below

  $(document).on('click','.delete-snitch', function() {

    var snitchID = $(this).attr('data-snitch-id'); 
    $.ajax({
        type: 'DELETE',
        url: '/snitch/' + snitchID,
        success: function(){
            $('#tr-for-snitch-' + snitchID).fadeOut;
        }
    });
});

You have to make sure that data-snitch-id property has the id in it before this will work.

Add an id to the tr you are trying to remove.

<tr id="tr-for-snitch-<%[email protected]%>" class="<%= snitch.classes %>">
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the help. Where do I put remote: true?
I do not think you will need it, the javascript I posted is handling the ajax request.
Ahh I see. Same goes for the "respond_to" stuff in the controller?
The stuff in the controller leave as is
Just a note, If you are connecting this to the submit button then you need to adjust the first line of the javascript code like this (notice the e in parenthesis) : "$(document).on('click','.delete-snitch', function(e) { " and then directly below that line put this " e.preventDefault(); "
|
1

Here are some steps because I dont have your entire source code with views and all.

  1. Create an html button with a specific class.
  2. Add a listener ($('.button-class').click(sendDeleteRequest(e)))onto the button making the request to your delete API. https://api.jquery.com/click/ documentation if you need it.
  3. On success 200 of the response from your delete API, delete the item.
  4. To delete the item, select with jquery. ie. $('.class-of-object).remove();
  5. On failure, window.alert("Oops, that didn't work") or window.reload()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.