I am working on a form to submit it by AJAX instead of http.
This is the form :
<%= form_for(:image, :remote => true, :url => {:controller=> 'questions',:action => 'upload'},:multipart => true) do |f| %>
<%= f.file_field :image, :onchange => "$(this).parents('form').submit();" %>
<% end %>
I have set the :remote => true option above and submitting the form with an onchange event . I have the following code in controller :
def upload
if request.xhr?
#image = Image.new(params[:image])
#image.save
respond_to do |format|
format.js { render :layout=>false }
end
else
render :text => 'Request Wasnt AJAX'
end
end
My action renders the text everytime , the request does not seem to be AJAX style despite the remote tag being set (it appears correctly even in the final HTML). I can't figure out where I am going wrong with this . I have tested it in the latest browser version of FF and Chrome , so I don't think it's a browser issue. Any ideas ?
Update : I did some more debugging attempts . The issue is with the file field , if I replace the file field with text field , the request is AJAX (everything else remaining same) . But with a file field it always sends a non AJAX request.
Note : Overall objective is to upload an image via AJAX request, with the response rendering nothing, no HTML, no redirection, no reload of the page.
Got it to work by installing the Remotipart gem . To upload image files using ajax form submission , this is the only way . Find the git here :https://github.com/JangoSteve/remotipart
JQuery form.sumbit() submits a form the normal way (Not Ajax). You have to do it differently:
$('#submitButton').click( function() {
$.ajax({
url: 'some-url',
type: 'post',
dataType: 'json',
data: $('#myForm').serialize(),
success: function(data) {
// ... do something with the data...
}
});
});
Related
I want to know if it's possible to redirect with controller from an ajax request in Rails 6 ?
I tried to use
redirect_to "url"; return and render :js => "window.location.reload" don't work for me :(
Thank you for your help :)
This works for me:
window.location.href = '/path'
Example:
$.ajax({
url: uri,
type: "POST",
data: form,
dataType: 'json',
processData: false,
contentType: false
}).done(function(e) {
window.location.href = '/project_proposals'
})
Do it in your controller.
render js: "window.location='#{goal_path(#goal)}';"
Ideally you'll want to keep as much business logic out of your JS as possible for rails apps. You also can't cleanly use your route helper methods in js. You can however setup your "redirect" in your controller.
app/view/controllers/goals/adopt_controller.rb
# :nodoc:
class Goals::AdoptController < ApplicationController
def update
# business logic....
# "redirect" the client
render js: "window.location='#{goal_path(#goal)}';"
# or make a reusable js view. this will search a wide variety of possible file names. In this case it'll match /app/view/appliation/redirect.js.erb
# #to = goal_path(#goal)
# render 'redirect'
# the above lets rails guess what you want to do. this is a bit more explicit to only render this view is the client can accept a js response. Other scenarios will throw an error
# #to = goal_path(#goal)
# respond_to do |format|
# format.js { render 'redirect' }
# end
end
end
/app/view/appliation/redirect.js.erb
window.location='<%= escape_javascript to %>';
I am a newbie of web develop, I am learning padrino framwork. But offical guide is lack of ajax content. Can any one supply me a doc or example for ajax in padrino?
eg,modifiy div .
I wrote a app,but ajax dont works fine.The refresh.js content is displayed on the #cn-status div.Followin is my ruby program
#controller
#----------------------------
get :refresh, :provides => :js do
if request.xhr?
# refresh.js.erb is js file for modify div content
render "aj/refresh", :layout => false
else
redirect url('aj/')
end
end
#link on the other erb file
<li><%= link_to 'get', url(:aj, :refresh, :format => :js), :confirm => "Are You Sure?", :remote => true %></li>
#refresh.js.erb file
$(document).ready(function(){
$("#cn-status").load("/cj/refresh_codename_get",function(responseTxt,statusTxt,xhr){
if(statusTxt=="error")
alert("Error: "+xhr.status+": "+xhr.statusText);
});
});
I'm converting our Rails 3 web app to use jQuery mobile, and I'm having problems with "remote" links.
I have the following link:
= link_to "Text", foo_url, :method => :put, :remote => true
Which, on the server, I'm handling like this:
respond_to do |format|
if foo.save
format.html { redirect_back_or_to blah_url }
format.json { render :json => {:status => "ok"} }
end
end
This used to work wonderfully. However, since I've added jQuery Mobile, the controller code goes through the "html" branch instead of the "json" one, and responds with a redirect.
I've tried adding
:data => { :ajax => "false" }
to the link, but I get the same effect.
Before jQuery Mobile, UJS was sending the request with the following accept header:
Accept:application/json, text/javascript, */*; q=0.01
while with jQuery Mobile, I'm getting this header:
Accept:*/*;q=0.5, text/javascript, application/javascript, application/ecmascript, application/x-ecmascript
I believe this change in headers is the culprit of the change in server-side behaviour. I haven't been able to debug through the client side to figure out who's doing what exactly. UJS is clearly still doing something, since I'm getting a "PUT request" of sorts, things get routed appropriately, etc, but I'm not sure what's changing the headers.
Thank you!
Daniel
By default remote: true goes to the format.js clause (and searches for some .js.erb template to send back), and defaults to format.html and sends back the html template.
You should use ”data-type” => :json in your link_to call if you want to return json, like:
<%= link_to 'Show Full Article', #article, :remote => true, "data-type" => :json %>
Source: http://tech.thereq.com/post/17243732577/rails-3-using-link-to-remote-true-with-jquery-ujs
I'm getting a 500 error when I try to use ajax to delete a post. It works just fine without using ajax.
In the view I have this to delete a post
<%= link_to 'Destroy', post, confirm: 'Are you sure?', method: :delete,:remote => true, :class => 'delete_post' %>
In the controller I have this for the Destroy method.
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.js
end
end
In the browser I get a 500 error.
Run Rails 3.1 Ruby 1.9.2-p290 and brand new 3.1 app
What am I doing wrong
It's probably a missing template error. If you don't specify any parameters in a format statement, Rails looks for and loads a file named action . format . template language (destroy.js.erb).
Try something like this:
format.js { render text: "Object successfully destroyed", status: :destroyed }
I have an action triggered by an AJAX request generated by Ajax.InPlaceEditor or InPlaceCollectionEditor like this:
new Ajax.InPlaceCollectionEditor('agent_email', 'inspections/<%= #inspection.id %>/update_field',
{
collection: [<% #agents.each do |agent| %>
'<%= agent.email %>',
<% end %>],
okText: 'Update',
cancelText: 'Never mind',
savingText: 'Updating...'
});
At the other end, the action contains this:
def update_field
--some code here--
if success
puts "stored change"
render :text => result
else
puts "did note change store"
render :text => inspection.errors.to_json, :status => 500
end
end
Once any of the render methods are reached, the session expires, and next time the user send a request, Devise sends them to the logon on page.
Even though I am exempting update_field from authentication (before_filter :authenticate_user!, :except => :update_field), the session is still getting reset.
I have looked at the answer at a very similar question at Devise session immediately expiring on .js call [AJAX], but it is not solving my particular problem.
Any ideas?
I got this to work by getting the code from http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails (prototype-snippet.js):
/*
* Registers a callback which copies the csrf token into the
* X-CSRF-Token header with each ajax request. Necessary to
* work with rails applications which have fixed
* CVE-2011-0447
*/
Ajax.Responders.register({
onCreate: function(request) {
var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
if (csrf_meta_tag) {
var header = 'X-CSRF-Token',
token = csrf_meta_tag.readAttribute('content');
if (!request.options.requestHeaders) {
request.options.requestHeaders = {};
}
request.options.requestHeaders[header] = token;
}
}
});
... within a Javascript block in my application.html.erb:
<script type="text/javascript">
(... the code from above)
</script>
Also don't forget to add:
<%= csrf_meta_tag %>
in the same file towards the top (if not already there).
The document "CSRF Protection Bypass in Ruby on Rails" explains why this works.