TurboGears and AJAX

Many beginner web developers ask questions like “how do i do something without refreshing page?” or “how can i load another page in my page?” etc. The answer is AJAX. AJAX stands for “Asynchronous JavaScript and XML”. With AJAX, you can retrieve or send data to the server in the background using an “XMLHttpRequest.”

Troll Cat

Before going further, i would like to take your time and advise you to learn JavaScript. If you are a web developer, no matter if you are back-end or front-end one, at some point in your career you will have to use JavaScript. In order to be ready for those times, go and learn JavasSript. There are awesome resources.

Do not be one of those people who think learning jQuery is enough and how you don’t need to know JavaScript. jQuery is a JS framework. It’s a great one and that’s all. Learn JavaScript.

There are many techniques to use AJAX in a web application. In these examples we are going to use jQuery framework and it’s powerful “$.get” and “$.post” methods.

Open up your terminal, cd into your TurboGears environment, activate it, upgrade it to the most recent version which is 2.1.5 with:

easy_install -U -i http://tg.gy/current tg.devtools

Go to your controllers/root.py and change the index action like this:

@expose('ideas.templates.index')
def index(self):
    """Handle the front-page."""
    projects = DBSession.query(Project).all()
    return dict(page='index', projects=projects)

And this is our new “templates/index.mak”:

<%inherit file="local:templates.master"/>

<%def name="title()">
  Welcome to IDEAS.
</%def>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
    $("a.project_link").click(function(){
        var context = this;
        $.get(this.href, function(response){
            $(context).parent().next().html(response);
        });
        return false;
    });
});
</script>

<div style="margin-bottom: 50px;">
    <h1>Projects</h1>
    % for project in projects:
        <div class="project">
            <div style="margin-bottom: 5px;"><a class="project_link" href="${url('/show_tasks/%s' % project.id)}">${project.project_name}</a></div>
        <div class="tasks"></div>
    % endfor
</div>

<%def name="sidebar_bottom()"></%def>

In our “show_tasks.mak” template:

  • We are listing the projects in a for loop.
  • We create a “div” element with the class “tasks” to use in our JavaScript.
  • We include jQuery framework via Google CDN.

So whenever we click to a project’s link, its tasks will be listed under the “tasks” div.

Let me walk you through the simple JavaScript codes we wrote.

In the first line, we tell jQuery “when the DOM is ready”, use all these child scripts of yours. So it attaches the event listener, changes css classes, anything we want to do.

In the second line, we tell, whenever an “a” element with a “project_link” class is clicked, create an AJAX request and append the result to the closest div with the class “tasks” to the “a” element’s parent.

In JavaScript, whenever a new scope is opened like the second line, the keyword “this” changes meaning. In line 3 of our script, it references to the clicked “a” element however in the line 5 it references the response object. This is why I have created the “context” variable and mapped it to “this” which is the clicked “a” element. This way, I am able to use the clicked a element.

We are missing two things here. The corresponding TurboGears action and it’s template. So let’s create them. In your RootController, add the following action:

@expose('ideas.templates.show_tasks')
def show_tasks(self, project_id):
    tasks = DBSession.query(Task).filter_by(project_id=project_id).all()
    return dict(tasks=tasks)

And the following goes by “show_tasks.mak” under the “templates” directory.

% if tasks:
    % for task in tasks:
        <div>${task.task_name}</div>
    % endfor
% else:
    <div>This project does not have any tasks, yet.</div>
% endif

That’s all. Run your server and open it up in your browser. Let’s see how it goes.

In the next post, I will show you how to use the $.post method and deal with JSON responses from the server when using AJAX. I hope you guys enjoyed all these. Please do not hesitate to ask any question. You are more than welcome.

Advertisements
This entry was posted in AJAX, JavaScript, jQuery, TurboGears and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s