Reputation: 2473
My specific example is highly complex, so I will use the example shown by Ryan from Railscasts to discuss this:
http://railscasts.com/episodes/197-nested-model-form-part-2
Background
I have a form, let's say "Survey", which contains an arbitrary number of "Questions".
Senario
Give i am on the "Edit Survey" page.
I would like to add a button to each "Question" field which calls a remote_function, which in turn queue's up a delayed_job to execute some processing on the "Question".
To give feedback to the user, i would like to disable the button, and show an animated spinner, which remains until the delayed_job has processed the "Question".
Hint - I can add methods to the "Question" model to indicate the status of the delayed_job.
So, with best practices in mind, what is the best way to achieve this?
Upvotes: 1
Views: 6490
Reputation: 7167
Do the polling and respond with a json similar to this:
{"finished": [1,3,3]}
Then add the polling JavaScript
var interval = setInterval(function() {
$.get("test.json", function(data) {
for(i in data.finished) {
//Hide spinner with id = data.finished[i]
}
})
}, 5000) //Time in milliseconds
Upvotes: 3
Reputation: 10148
Simple.
Put the html in your page template
//hidden div that has spinner image
<div id="LoadingDiv" style="display:none;">
<img src="ajax-loader.gif" alt="" /></div>
Some simple CSS to format the block (this created the translucent background that blocks user interaction)
/*the basics, and works for FF*/
#LoadingDiv{
margin:0px 0px 0px 0px;
position:fixed;
height: 100%;
z-index:9999;
padding-top:200px;
padding-left:50px;
width:100%;
clear:none;
background:url(/img/transbg.png);
/*background-color:#666666;
border:1px solid #000000;*/
}
/*IE will need an 'adjustment'*/
* html #LoadingDiv{
position: absolute;
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
}
Then turn it on and off as needed
var ldiv = document.getElementById('LoadingDiv');
ldiv.style.display='block';
/*Do your ajax calls, sorting or laoding, etc.*/
ldiv.style.display = 'none';
If you want more details, or need a translucent pixel to use, see my full article
How to fade window and show translucent progress bar
Upvotes: 1
Reputation: 4211
First you'll need an animated spinner graphic. Google and there are loads of sites which will generate them for you.
Reference the gif in you layout (or view) with:
<%= image_tag 'spinner.gif', :id => 'spinner', :style => "display:none;position:absolute;top:300px;left:500px;" %>
(this assumes a fixed position on the page)
Then add the following to your remote_function call:
:before => "Element.show('spinner')",
:after => "Element.hide('spinner')"
Upvotes: 1
Reputation: 2940
Using jQuery you should be able to turn the throbber (yeah... that's the "official" name) on and off using callbacks.
Or, if it's more complex I've used this before:
http://plugins.jquery.com/project/throbber
Upvotes: 0