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.
Related
I was just going through this
old rails cast episode, and one thing it mentions is the (now obsolete, apparently) link_to_function code. One interesting snippet it mentions is
link_to_function "Add a Task" do |page|
page.insert_html :bottom, :tasks, :partial => 'task', :object => Task.new
end
In short, clicking the "Add a Task" link appends the "task" partial to the page without ajax.
I'm familiar with how to do this in Rails 3/3.1 via AJAX and/or manual javascript, but how do you pull in a template partial on the fly without touching ajax?
It just simply stores the html content within the javascript code, which it's rendered while the page is rendered. So when you click "Add a task" the partial is already there escaped in the javascript code of the add task action. Just take a look to the content of the page with firebug.
Also the docs shows that the instert_html looks like this for prototype:
def insert_html(position, id, *options_for_render)
content = javascript_object_for(render(*options_for_render))
record "Element.insert(\"#{id}\", { #{position.to_s.downcase}: #{content} });"
end
So you can see that the content is actually the task partial, and it's inserted into javascript code.
Also i have to mention that this is an obtrusive way to use javascript.
Take a look at the docs.
I was going through the same railscast, and I figured out the reason why this is not working is because this method uses Prototype, which by default is unavailable with the Rails 3.1 .
You could get this working by installing prototype gem from:
https://github.com/rails/prototype-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 %>
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')
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.
I have a mystifying problem. In a very simple Ruby app i have three classes: Drivers, Jobs and Vehicles. All three classes only consist of Id and Name. All three classes have the same #index and #show methods and only render in JSON or XML (this is in fact true for all their CRUD methods, they are identical in everything but name). There are no views. For example:
def index
#drivers= Driver.all
respond_to do |format|
format.js { render :json => #drivers}
format.xml { render :xml => #drivers}
end
end
def show
#driver = Driver.find(params[:id])
respond_to do |format|
format.js { render :json => #driver}
format.xml { render :xml => #driver}
end
end
The models are similarly minimalistic and only contain:
class Driver< ActiveRecord::Base
validates_presence_of :name
end
In routes.rb I have:
map.resources :drivers
map.resources :jobs
map.resources :vehicles
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
I can perform POST/create, GET/index and PUT/update on all three classes and GET/read used to work as well until I installed the "has many polymorphs" ActiveRecord plugin and added to environment.rb:
require File.join(File.dirname(__FILE__), 'boot')
require 'has_many_polymorphs'
require 'active_support'
Now for two of the three classes I cannot do a read any more. If i go to localhost:3000/drivers they all list nicely in XML but if i go to localhost:3000/drivers/3 I get an error:
Processing DriversController#show (for 127.0.0.1 at 2009-06-11 20:34:03) [GET]
Parameters: {"id"=>"3"}
[4;36;1mDriver Load (0.0ms)[0m
[0;1mSELECT * FROM "drivers" WHERE ("drivers"."id" = 3) [0m
ActionView::MissingTemplate
(Missing template drivers/show.erb in view path app/views):
app/controllers/drivers_controller.rb:14:in `show'
...etc
This is followed a by another unexpected error:
Processing ApplicationController#show (for 127.0.0.1 at 2009-06-11 21:35:52)[GET]
Parameters: {"id"=>"3"}
NameError (uninitialized constant ApplicationController::AreaAccessDenied):
...etc
What is going on here? Why does the same code work for one class but not the other two? Why is it trying to do a #view on the ApplicationController?
I found that if I create a simple HTML view for each of the three classes these work fine. To each class I add:
format.html # show.html.erb
With this in place, going to localhost:3000/drivers/3 renders out the item in HTML and I get no errors in the log. But if attach .xml to the URL it again fails for two of the classes (with the same error message as before) while one will output XML as expected. Even stranger, on the two failing classes, when adding .js to the URL (to trigger JSON rendering) I get the HTML output instead!
Is it possible this has something to do with the "has many polymorphs" plugin? I have heard of people having routing issues after installing it. Removing "has many polymorphs" and "active support" from environment.rb (and rebooting the sever) seems to make no difference whatsoever. Yet my problems started after it was installed. I've spent a number of hours on this problem now and am starting to get a little desperate, Google turns up virtually no information which makes me suspect I must have missed something elementary. Any enlightenment or hint gratefully received!
JS
If you installed has many polymorphs as a plugin, you have to remove it from vendor/plugins not from environment.rb. Can you please rm -rf that plugin and try again.
Ok. I gave up. Went back to a pre "has many polymorphs" version and appled my changes one by one, running tests after each one to make sure it was still working. About an hour later and I think all the /app/ stuff is the same as when I ran into trouble. "has many polymorphs" is re-installed and required along with "active support" and the classes/models/views are correct (i.e. no HTML render & no views). And guess what; it's all working perfectly! I don't know whether that should make me happy or sad - in any case I'd still really like to know what it was that went wrong here...
JS
P.S. Oh, and if I'm going to continue with RoR I will have to make SVN a priority. It's a total necessity even for such a tiny project since it seems RoR breaks very easily and mysteriously (this is not the first 5+ hour WTF I've had).
You best bet at this time may be to restart your app from scratch. rails is good like that.