Rails jQuery with Ajax? - ruby-on-rails

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 %>

Related

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 3.1: Is it ajax?

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.

Some issue with Ajax on Rails

I'm using Ruby on Rails 2.3.8. I've got a vote link that when you click it executes the following action:
def vote
render :update do |page|
page.select(".divbrian").each do |d|
page.replace_html d, "YA SEEE"
end
page.select('.d_voting_links_' + params[:post_id].to_s).each do |d|
page.replace_html d, :partial => 'post_votes/voted'
end
page.select('.d_vote_count_' + params[:post_id].to_s).each do |d|
page.replace_html d, Post.find(params[:post_id]).get_vote_count
end
end
end
In the HTML, there are as much divs of class "d_voting_links_" as posts displayed in the html page.
I don't know why, after I've installed Paperclip, Rails TinyMCE, and Hpricot plugins (all of them on the latest version), these ajax requests stopped working (really crazy).
I haven't changed anything of my code, I've even checked on my previous versions in which it works and nothing had changed, but those plugins.
I've also tried to created a simple div and calling it from the same action but it didn't recognize it (it does if I delete the "." from the request, but that will search for IDs, and I need to search for class).
Do you know about any known issue between those plugins and this ajax syntax? Or maybe...do you have a clue about what the problem could be?
I don't know why that block of code stopped working...but I've now figured out that without the page.select block, it will work anyway and replace all of the divs with those class names.

Rails 3: Simple AJAXy Page updates?

I can't believe I've been looking four hours for this simple task, but I have.
In Rails 2.3, I could replace one section of a page with this simple code:
render :update do |page|
page.replace_html "div_id", :partial => "new_content",...
end
In Rails 3, Ryan Bates has me writing entire new javascript functions, switching from Prototype (rails default) to jQuery, and otherwise not enjoying life. The other tutes are no more straightforward.
What am I missing? How do we replace a <div> these days?
Thanks, guys. The official answer seems to be that, yes, the team felt simple is the enemy of good and made it more complicated.
The first key is to create a .js.erb file NAMED for the method CALLING the ajax update. So if the index method handles the update, put the raw javascript in index.js.erb. This goes in the views folder.
Second, the code that worked in index.js.erb was
m = $('list_users');
m.innerHTML = "<%= escape_javascript(render :partial => "reload_users") %>";
Then to make the call, add in the respond_to block of the controller method, add:
format.js
Finally, the calling view has:
<%= link_to "Update User List", #reload_users_path, :remote => true %>
By the way, supposedly all the old pages using page.replace will work if you install a plugin. The plugin download page suggests that it broke in the last releases of Rails 3 and has not been fixed. Also, various bloggers will come to your home and birch-switch you if you use it.
The whole RJS stuff makes the javascript inline and makes the dom very obtrusive. Also, by avoiding inline javascript you could open up other possible ways of optimizing you javascript by compressing and caching those files in browser. Thats the reason why RJS is getting out of scope from rails 3. A little bit of getting around with jQuery or Prototype for a day should get you on gears with these kind of small stuff and will help the project on long run.
Do you still have jQuery in there? I'd recommend it over Prototype any day...
If it's still there you can just use the following in your Javascript:
$.get("<%= url_for path/to/partial %>",
function(response) {
$("#div_id").html(response);
});
This gets the partial via AJAX and just dumps it into the div with id div_id.
Hope this helps!
I'm not even sure you need to make an AJAX call to load that partial. I believe that in a js.erb file, a call to render(:partial => object_or_path) will just return a string with all the html, which you can wrap in a jQuery object and append. Example:
$('#div_id').html($('<%= render :partial => #object %>'))
As far as I know, along the same line as the answer above, you can do something like this in your template:
<%= link_to "Update User List", #reload_users_path, :remote => true %>
And in controller, do this:
respond_to do |format|
format.js {
render :text => "alert('reloaded')"
}
end
This way you can have controller "execute" client side JS much the same as as render :update used to do. This is equivalent to doing the following in Rails 2:
render :update do |page|
page << "alert('reloaded')"
end
Is there any reason why this approach is not advisable?
Try this:
page.call "$('#div_id').html", render(:partial => 'new_content')

Resources