Ruby On Rails – HOWTO Build Ajax Timer

This is a simple article to demonstrate how easy, simple and effective it can be utilising the web2.0 functionality made simple in Ruby On Rails.
What we are trying to achieve is a javascript timer, which we can use to fire ajax requests to make our screen appear dynamic or automatically update.

1.

Include the Javascript libraries. This is best placed in your layout, so in a default project using the standard layout, open app/view/layouts/standard.rhtml. After the head tag put the following:

< %= javascript_include_tag :defaults %>

2.

Create a form or link to initiate your timer. I created a form and a link to demonstrate the use of both types.
The partial used in the above example is as follows:

Example:

< % remote_form_for(:example,
                   :url => "example_start",
                   :html => { :multipart => true }) do |form| %>
 < %= submit_tag "Start", :id => "example_submit_button" %>

< % end -%>

< %= link_to_remote "Stop",
                   :url => { :controller=>"articles" , :action => "example_stop" } %>

When the ‘Start’ button is pressed, it does an AJAX request to the location specified by the :url tag in this case action ‘example_start’.
The ‘Stop’ link also does an AJAX request to the action ‘example_stop’. We will define these two functions next.
The div at the end is the field we will be updating using AJAX and javascript.

3.

Now we open our controller and write the actions ‘example_start’ and ‘example_stop’.

  def example_start
    # initialize counter
    session[:counter] = 0

    # initialize stop loop variable
    session[:stop_timer] = false
    render :update do |page|

      # update the status
      page.replace_html 'example_use_me', 'Starting....'
      # disable the button

      page < < "document.getElementById('example_submit_button').disabled = true;"
      # start the timer
      page << "example_initialize_polling(300);"
      # highlight the updated div - so client notices

      page.visual_effect :highlight, 'example_use_me'
    end
  end

  def example_stop
    # change our conditional stop loop variable
    session[:stop_timer] = true

    render :update do |page|
      # enable the button
      page << "document.getElementById('example_submit_button').disabled = false;"

    end
  end

These actions are fairly straight forward. I define a conditional so we can stop our looping timer, set the counter to 0. I used the session variable purely for simplicity, as I didn't want to pass variables around - however you can do this, I just chose not to. I also enable and disable the start button depending on the state of our loop.

4.

I refer to a Javascript function

page < < "example_initialize_polling(300);"

in the controller which we will need to define before we can use it.
'example_initialize_polling()' uses a couple of other simple javascript functions which you will need to add. In this tutorial, I have used pure Javascript as I am still learning RJS.

Open up your applications local javascript file 'public/javascripts/application.js'

var e_timerRunning = false
var e_timerID = null

var e_delay = 3000

function example_initialize_polling(e_seconds)
{

    // Set the length of the timer, in seconds

    e_secs = e_seconds
    example_StopTheClock()
    example_StartTheTimer()
}

function example_StopTheClock()
{
    e_secs = 0
    if(e_timerRunning)

        clearTimeout(e_timerID)
    e_timerRunning = false
}

function example_StartTheTimer()

{
    if (e_secs==0)
    {
        example_StopTheClock()

        new Ajax.Request('/articles/update_example_status', {
          method:     'post'

        });
        //initialize_polling(e_seconds)
    }
    else

    {
        e_secs = e_secs - 1
        e_timerRunning = true

        e_timerID = self.setTimeout("StartTheTimer()", e_delay)
    }

}

There are a couple of constants you can configure here, to make you refresh slower or faster as needed. You can see the AJAX request posts to: ‘/articles/update_example_status’.

5.

Back in your controller you will need to define this action ‘update_example_status’

def update_example_status

    # count
    session[:counter] += 1
    render :update do |page|

      if session[:stop_timer] == false
        # update the status
        page.replace_html 'example_use_me', "Im Counting. At: #{session[:counter]}"

        # restart the timer
        page < < "example_initialize_polling(300);"
      else
        page.replace_html 'example_use_me', "Stopping.... reached: #{session[:counter]} "

        # highlight the updated div - so client notices
        page.visual_effect :highlight, 'example_use_me'
      end

    end
  end

When the Ajax request calls this action, you will notice the 'clock' has stopped, and therefore we need to re-initialize it from within our controller - if the stop condition variable isn't set. I also put the counting logic, and update the div in this section, you could put anything you need here.


Leave a Reply

Spam protection by WP Captcha-Free