Javascript not being rendered at script but as html instead
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 (whi开发者_开发技巧ch 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.
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.
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.
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.
精彩评论