views:

77

answers:

3

This question is to piggy back off of a previous one I asked yesterday, which deals with moving the create/edit feature of a model onto its index page. One last issue I am having is that I when I go to delete a model, I have some javascript that is supposed to run that reloads the list of models to reflect the change in the database. This js is being rendered as html. Here is the code that I think is relevant:

in my controller:

def destroy
  @post = Post.find(params[:id])
  @post.destroy
  flash[:notice] = "Successfully destroyed post."
  @posts = Post.all
  respond_to do |format|
    format.js {render :content_type => 'text/javascript' }
  end
end

my list of posts partial (which has the destroy link that I am referring to):

<table>
  <tr>
    <th>Title</th>
    <th>Content</th>
  </tr>
  <% for post in @posts %>
    <tr>
      <td><%= post.title %></td>
      <td><%= post.content %></td>
      <td><%= link_to "Edit", edit_post_path(post), :class => "edit" %></td>
      <!--
        This is the problem here... I can't seem to get it to work.
        It DOES delete the record, but then gets redirected to /posts/:id
        and displays my javascript as html.
      -->
      <td><%= link_to "Destroy", post , :confirm => 'Are you sure?', :method => :delete, :class => 'destroy' %></td>
    </tr>
  <% end %>
</table>

destroy.js.erb:

$("#post_errors").hide(300);
$("#flash_notice").html("<%= escape_javascript(flash[:notice])%>");
$("#flash_notice").show(300);
$("#posts_list").html("<%= escape_javascript( render(:partial => "posts") ) %>");

javscript that gets loaded as the page loads:

// Setting up the ajax requests for the forms/links.
$(document).ready(function() {
  $("#new_post").submitWithAjax();
  $("a.edit").each(function(){
    $(this).getWithAjax();
  });
  $("a.destroy").each(function(){
    $(this).postWithAjax();
  });
});

// Setting up ajax for sending javascript requests
jQuery.ajaxSetup({
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});

jQuery.fn.submitWithAjax = function() {
  this.submit(function() {
    $.post(this.action, $(this).serialize(), null, "script");
    return false;
  });
  return this;
};

jQuery.fn.getWithAjax = function() {
  this.click(function() {
    $.get(this.href, null, null, "script");
    return false;
  });
  return this;
};

jQuery.fn.postWithAjax = function() {
  this.click(function() {
    $.post(this.href, null, null, "script");
    return false;
  });
  return this;
};

To see all of the code that I'm using, check out the other question I posted, but I think that this is enough to see what I'm doing wrong. Also, when I'm running chrome and click the destroy link, chrome shows me a javascript warning:

Resource interpreted as document but transferred with MIME type text/javascript.
A: 

Setting the MIME type manually may be the source of the problem. JavaScript is often sent as application/x-javascript instead of text/javascript so it's best to leave it up to the rendering engine to set that for you.

Also it might be better to use .js.rjs for simple cases like this as it makes your JavaScript largely framework independent.

tadman
This doesn't work. Also, renaming destroy.js.erb to destroy.js.rjs causes a compiler error in that file. Isn't RJS an older way of doing it? I should be able to get it to work using .js.erb since that works for my other ajax requests.
DJTripleThreat
RJS is the newer way, but the syntax is different from .erb so you will have to convert your script before it works. With the proper MIME type you should be okay though.
tadman
A: 

I ran into the same problem. The solution was to use the script provided here: http://www.danhawkins.me.uk/2010/05/unobtrusive-javascript-with-rails-2-3-5/
All You have to do, after using it as described, to delete an object, is to use something similar to this code:

 <%= link_to "Destroy", post , :confirm => 'Are you sure?', :class => 'remote destroy' %>

For me this works like a charm.

Jeznet
A: 

The answer to this problem is that in the request headers, the Accept header should have been set to text/javascript or something similar. This should have been done in this js function:

jQuery.ajaxSetup({
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});

for POST requests, this was happening just fine, but when I wanted to do a PUT request or a DELETE request, this wouldn't get called somehow or it was being ignored. I realize that using the rails.js plugin for jQuery/AJAX was needed to be referenced since I am using HTML5.

For the edits and deletes to work, I did this to my link_to methods:

link_to "Edit", edit_post_path(post), "data-remote" => 'true', 'data-method' => 'get'      
link_to "Destroy", post , "data-confirm" => 'Are you sure?', "data-remote" => 'true', "data-method" => 'delete'

adding those html attributes to my anchor tags allowed rails.js to determine that I wanted to do some ajax requests with them. They started working after that.

DJTripleThreat