views:

554

answers:

3

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?

A: 

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

Quotidian
A: 

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')"
Mike Sutton
Showing the spinner is not really the challenge here though, the problem is that the remote function call simply sets up the delayed_job, which will be executed by the delayed_job process. What i need is some kind of observer function, that repeatedly polls the server to find out if the job has completed, and one it has, i need to hide the specific spinner associated with that job.
Globalkeith
A: 

Simple.

  1. Create a hidden element to show our images
  2. Use CSS to format the layout
  3. Use Javascript to turn the effect on /off

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 &gt; 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

Eddie