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.







