rails 3.1: Is it ajax? - ruby-on-rails

In rails 3.1, I implement as:
1. Define test action in post controller:
def test
#p = Post.first
respond_to do |format|
format.js
end
end
2. Define in routes.rb:
resources :posts do
collection do
get 'test'
end
end
3. In index.html.erb of post folder, I add link:
<%= link_to "test", test_post_path, :remote => true %>
4. Create test.js.erb file in post folder:
code jQuery
My question is: "Is my implement Ajax in rails 3.1?" I don't really understand about ajax in rails.
If no, can you give me a link about ajax in rails 3.1 and the technique I set up, what is it?

Yes it is ajax. When you add :remote => true to links and forms in rails, it automatically sends data to the server without refreshing your page on the browser. That's how ajax works in every language/script.
In your case, you can put js code in your test.js.erb file to update/interact the page (with jQuery). You might want to update some html div elements with the attributes of instance variable you set up #p .
Eg. in your test.js.erb
$("#some_div").html("<%= #p.title%>");
Then you have essentially made an ajax request to the server and update the client browser page with the server data without refreshing.

You request is do by Ajax from your link. But the return of your action can be not usefull to you.
You need add in your app/view/posts directory a test.js.erb file and fill it with Javascript behaviour you want.

Related

rails form post action without changing path

I've got a view that renders a contact form. This contact form is rendered through javascript. There is also a javascript filter that the user can set viewing options in. (Depending on the settings, different markers are shown on a google map. The user can then click on the markers and in the viewbox click on a view button that renders some info and the contact form below the map)
If I were to make a normal form and use the post method with a #contact and contact routes, I would have to rerender the entire page after the #contact#create method was called. Which would mean all of the current users filter options would be unset. I could obviously save the settings, but feel like this is a hassle.
What I would like is for the contact form to call a method upon submit without actually changing paths, but I have no idea if this is even possible. (i'm using simple form so an answer for that would be preferable)
Since your question is quite broad, I'll have to answer as such:
if this is even possible
Yes it's possible.
You'll have to use ajax to send an asynchronous request to your server.
Ajax (Asynchronous Javascript And Xml) sends requests out of scope of typical HTTP; you can send/receive "hidden" data without reloading (this is what you want):
Don't worry - ajax is really simple once you understand it.
There's a great Railscast about it here:
Implementation
For you, you will just have to get your form to submit over ajax (javascript). There are two ways to do this:
Standard JS (JQuery)
Rails UJS (unobtrusive Javascript)
Basically, javascript acts as a mini browser, opening a url on your server, handling the returned data & doing what you tell it on the path:
<% form_tag contact_path, remote: true %>
<%= text_field_tag "name %>
<%= email_field_tag "email" %>
<%= submit_tag %>
<% end %>
You'll then be able to back this up with the corresponding controller action on your server:
#app/controllers/contact_forms_controller.rb
class ContactFormsController < ApplicationController
def create
... #-> your own logic here
respond_to do |format|
format.js #-> when receiving a pure xml request, this will fire
format.html
end
end
end
#app/views/contact_forms/create.js.erb
$("body").append("<%=j #variable %>");
Without going into too much detail, this is the most efficient way to achieve what you want. I can elaborate if required.

Rails + ajax, my "edit.js.erb" is not being run

I'm trying to setup ajax within rails, but I am having trouble getting my "edit.js.erb" to be ran
My edit.html.haml
= f.check_box :foo, {checked: eligibility_data.foo, class: "foo", remote: true}
controller
def edit
#survey = Foo.find_by_id(params[:id])
respond_to do |format|
format.html
format.js
end
end
edit.js.erb
alert("Testing");
How can I get edit.js.erb to run? Once it's working I want to append html to my view, will I be able to place that html right into my js.erb, or will I have to make a partial of some sort?
You can't append remote: true to a checkbox and expect it to fire off.
It needs to either be attached to the parent form tag of said checkbox, or you need to write some js that watches that checkbox.
If you go the watcher route, the JS will send an ajax call when the box gets clicked on.
Here is a link on how to do AJAX with jQuery (which is built into rails)

Rails link_to with remote: true processing html instead of js after page refresh

I have a search page in my app, where there is an ajax search form. The search form works properly, passing parameters to the model to filter the search, and the model returning a collection of results. Upon search submit, #results are rendered on the page. Each #result then has a link to an action on it, like:
<%=link_to "Message", message_user_path(:id => user.id), :remote => true%>
Where this action in the controller is:
respond_to :js, :html
def message
#user_id = params[:id]
#user = User.find_by_id(#user_id)
respond_to do |format|
format.html
format.js
end
end
and this responds with message.js.erb, which triggers a messaging panel to pop up with a message to the user. All of this is working correctly, checking the log I see the correct get request sent, and the correct format being processed:
Started GET "/users/3/message"
Processing by UsersController#message as JS
However, if I refresh the page and try to click the same link that was working before, I get the error Template is Missing. Checking the log, I see that now there are two requests sent, first an html then the same js request.
Started GET "/users/4/message"
Processing by StudentsController#message as HTML
...
Completed 406 Not Acceptable in 3ms (ActiveRecord: 1.0ms)
Started GET "/users/4/message"
Processing by StudentsController#message as JS
The html request throws the missing template error. Does anyone know why refreshing the page causes rails to attempt to respond with an html request to a remote link?
EDIT: routes.rb
resources :students do
member do
get 'message'
end
end
Does your app/assets/javascripts/application.js contain
//= require jquery
//= require jquery_ujs
?
And your erb contains <%= javascript_include_tag "application" %>?
I was just struggling with a problem like this for HOURS and the last of those two points fixed it; I saw the first point mentioned in some other questions so I'll repeat it here.
Hope that helps.
(Credit where credit's due)
What solver it for me was adding :format => "js"
So in your case:
<%=link_to "Message", message_user_path(:id => user.id, :format => "js"), :remote => true %>
In general, when you use link_to on a particular button or so, when you press the button, as js request is send to the controller, but also searches for the respective .js.erb file and so on.
My solution was to replace
format.json do
with
format.js do
you can troubleshoot the request by setting a breakpoint (i use pry) in the controller and then look at the variable
request.format
For newer versions of Rails, this should be fixed where using remote: true within the link_to code, as the original poster was doing, will only look for a .js format to respond with. As others have said, if you never need an html response, then you can remove that from your code all together; you won't even need a respond_to, respond_with, etc as Rails will auto respond with JS looking for the template you already have made. So your controller code would look like this:
def message
#user_id = params[:id]
#user = User.find_by_id(#user_id)
end
And the link would still be this:
<%=link_to "Message", message_user_path(:id => user.id), :remote => true %>
Or this would work as well (my preferred way of syntax):
<%=link_to "Message", message_user_path(id: user.id), remote: true %>
This code will call the controller action which will look for the template message.js.erb.
I know this question is old now, but for anyone looking for answers and using current Rails 6+ (I'm using 7.0.0alpha), and if you are getting this same type of issue where both HTML and JS templates are being requested; check that turbolinks is not what is causing the issue. Sometimes turbolinks can cause a request to be sent twice and it may be sending the first request as an HTML request.
My form with remote: true was inside another form and I didn't know it.
So make sure it isn't inside another form.

Rails jQuery with Ajax?

I'm a rails newbie and I cant seem to get jquery with ajax to work. I have installed the jquery-rails and done rails g jquery:install. Then I did a sample test by calling an alert in the application.js file and it worked. Then I created a controller action 'index' and made a link to it on one of my other pages. I thought to get ajax to work with it, I would simply create a index.js.erb file. However I then got an error saying template missing, so in my controllers' index action, I put the following code:
respond_to do |format|
format.html
format.js
end
However, I am not getting anything displayed on my page. In my index.js.erb file I have a simple alert message to test out if its working, and I cannot get that to even come up. Any suggestions? I don't know if it matters but I am using rails 3.0.7. Thanks in advance
RJS files didn't work with jQuery Plugin, so, you have to use *.js.erb extension in order to use javascript template, and these files are a kind of erb + javascript combination (like *html.erb files).
Just wrote this using rails 3.0.7, jquery plugin should be compatible with rjs syntax
routes.rb
get "main/index"
get "main/hello"
main_controller.br
class MainController < ApplicationController
def index
end
def hello
end
end
hello.js.rjs
page.alert("test");
index.html.erb
<%= link_to 'test', main_hello_path, :remote => true %>

rails ajax update only once

I have a remote_form_for that I use to let a user know if their form was submitted successfully. In this method I have :success=>'updateMain()
I would like to add an ajax update request to updateMain. The problem is that I can't find a way to make a single update request in rails (I know this is available in prototype).
The closest thing I've found is periodically_call_remote but this is not what I'm looking for as it continues to poll the server (and I only need it to happen once)
Another issue is that the ajax code needs to go into the updateMain js method, so I can't use periodically_call_remote as it automatically wraps the its js code with <script></script>.
I could write this manually with prototype but it would be nice to do it with rails. Any ideas?
In your controller method that your remote_form_for is submitting to, why don't you just use render :update?
def ajax_method
# If the form was valid
render :update do |page|
page.replace_html 'id_of_div_to_update', :partial => 'successful_form_submission'
end
end
The page will be updated each time you submit the ajax form.

Resources