views:

278

answers:

3

I am running into a strange problem.
I simply want to display a loading icon on the page when pressing a button.
If my call to form_remote_for contains Ajax options then the RJS script does not work.

This works ("loading" is hidden by the controller and RJS):

View:

<%=form_remote_for(:job, @job, {:url => {:action=>:create}}) do |f| %>
[...]
<div id="loading">Loading...</div>

controller:

def create  
  render :action => "create.js.rjs"   
end

RJS:

page.hide 'loading'

This does not work (just adding :loading=> and loading is shown by the view but not hidden back by the controller as it was before):

<%=form_remote_for(:job, @job, {:url => {:action=>:create}}, {:loading=>"$('loading').show()"}) do |f| %>
[...]
<div id="loading" style="display:none;">Loading...</div>

So if my call to form_remote_for contains Ajax options then the RJS script does not work. Why?

A: 

Change your form to:

<% form_remote_for (:job, @job, :url => {:action => :create}, :loading =>"$('loading').show()") do |f| %>
# ...
<% end %>

Make sure create is:

  # POST /jobs
  # POST /jobs.xml
  def create
    render :action => "create.js.rjs"
  end

And make sure your create.js.rjs is:

page.hide 'loading'

This scenario works for me. As you had it, it was returning the erb in the template because it was posting to "new" -- based on a quick scaffold implementation I did. Now I might still be missing something because as I said before the massive edit, I'm new, but this should get you going.

EDIT: Removed "is this your code?" post.

andymeadows
If was not my actual code :) I've corrected my post.
MickTaiwan
I don't understand why- it work when not using RJS (with braces)- it does not when using RJS (still with braces)- and removing the braces it works with RJS
MickTaiwan
When the braces are removed it posts back to /jobs and with the braces it posts back to /jobs/new -- not the intended location. I don't know enough to answer why, I just noted observed behavior. Glad it's working for you.
andymeadows
A: 

While not directly answering your question of "why" it isn't working, have you looked at using the :loaded parameter to hide the loading DIV rather than rely on the rjs file?

Scott
It works well with `:loaded` and I am using it often. But sometimes when your controller logic and your client javascript is complex, it works better with RJS. My example was simplified.
MickTaiwan
A: 

Assuming your using prototype you should use the Ajax.Responders to do the show/hide:

Ajax.Responders.register({
  onCreate: function() {
    Ajax.activeRequestCount++;
     if($('loading') && Ajax.activeRequestCount>0) {
      Effect.Appear('loading',{duration:0.4,queue:'end'});
     };   
  },
  onComplete: function() {
    Ajax.activeRequestCount--;
     if($('loading') && Ajax.activeRequestCount==0) {
        Effect.Fade('loading',{duration:0.4,queue:'end'});
     };    
  }
});

You can stick it in public/javascripts/application.js

Unobtrusive javascript - will work on any page with a hidden loading div and ajax events.

inkdeep