How to use AjaxGrid?

23 views
Skip to first unread message

Steve Bergman

unread,
Apr 18, 2006, 6:06:19 PM4/18/06
to TurboGears
I'm trying to get a simple AjaxGrid working as my first Ajax in TG (or
anywhere else, for that matter) and I'm sure I don't know what I'm
doing. I'm hoping once I have a working example understanding will
dawn.

Anyway, I quickstarted project 'ajaxgrid' and am following Alberto's
original sample usage here:

http://tinyurl.com/zhpcq

I'm using the controllers.py below. The example does not seem to use a
template. I don't get the grid. Just an "update" link at the top of
the page.

I know I'm missing something (and possibly a lot). But I don't know
what.

Thanks for any guidance.

-Steve

==========================================
import cherrypy
import turbogears
from turbogears import controllers, expose, redirect
from turbogears import identity
from turbogears.widgets import AjaxGrid


grid = AjaxGrid(refresh_url="/search", defaults=dict(q='turbogears'))

class Root(controllers.RootController):

@expose()
def index(self):
return grid.render()

@expose(format="json")
def search(self, q):
# get results
return dict(
headers = ["id", "program", "cool_factor"],
rows = [[i.id, i.name, i.c_factor] for i in results],
)
============================================

Steve Bergman

unread,
Apr 18, 2006, 8:52:31 PM4/18/06
to TurboGears
The controllers.py that I pasted above is not quite what I'm really
using.

Under the "# get results" comment, I have:

results = ['Test Id', 'Test Program', 'Test Factor']

so that the grid has some actual data.

FWIW, the although the other widgets are working, ajaxgrid does not
display in the toolbox widget browser. It has the update link, but
when I click it, I don't get any grid.

It does work for me here, however:

http://www.checkandshare.com/static/js/widgetUsage.html

Alberto Valverde

unread,
Apr 19, 2006, 3:21:04 PM4/19/06
to turbo...@googlegroups.com

Might be related to http://tinyurl.com/mrtvl. I cannot really help
here because it works ok on my machine... :/

Alberto

Steve Bergman

unread,
Apr 19, 2006, 4:22:17 PM4/19/06
to turbo...@googlegroups.com
Alberto Valverde wrote:

>
>
>Might be related to http://tinyurl.com/mrtvl. I cannot really help
>here because it works ok on my machine... :/
>
>
>

Hmm... I don't think it is related to that. I get no error. In fact,
the browser, receives this from the example controller:

=================
<DIV ID="ajaxgrid_0">
<A HREF="#" ONCLICK="javascript:ajaxgrid_0_AjaxGrid.refresh({&quot;q&quot;:&quot;turbogears&quot;});return false;">
Update
</A>
<DIV ID="ajaxgrid_0_update">
</DIV>
<SCRIPT TYPE="text/javascript">
addLoadEvent(partial(ajaxgrid_0_AjaxGrid.refresh, {"q":"turbogears"}));
</SCRIPT>
</DIV>
=================

Nothing is rendered except the "Update link."

Jorge Godoy

unread,
Apr 19, 2006, 5:02:48 PM4/19/06
to turbo...@googlegroups.com
Em Quarta 19 Abril 2006 17:22, Steve Bergman escreveu:

> Hmm... I don't think it is related to that. I get no error. In fact,
> the browser, receives this from the example controller:

And in your console output, do you see the same thing I reported in the bug?
Because the symptons you're describing are the same ones that I have here:
update link appears, nothing happens when clicked.

--
Jorge Godoy <jgo...@gmail.com>

Alberto Valverde

unread,
Apr 19, 2006, 5:04:09 PM4/19/06
to turbo...@googlegroups.com

On 19/04/2006, at 22:22, Steve Bergman wrote:
> Hmm... I don't think it is related to that. I get no error. In
> fact,
> the browser, receives this from the example controller:
>
> =================
> <DIV ID="ajaxgrid_0">
> <A HREF="#" ONCLICK="javascript:ajaxgrid_0_AjaxGrid.refresh
> ({&quot;q&quot;:&quot;turbogears&quot;});return false;">
> Update
> </A>
> <DIV ID="ajaxgrid_0_update">
> </DIV>
> <SCRIPT TYPE="text/javascript">
> addLoadEvent(partial(ajaxgrid_0_AjaxGrid.refresh,
> {"q":"turbogears"}));
> </SCRIPT>
> </DIV>
> =================
>
> Nothing is rendered except the "Update link."

This is normal... All rendering is done client-side by MochiKit's DOM
API. The toolbox browser works fine on my machine, that's why I
suppose it's a browser issue. Maybe if you send a quick started app
that reproduces the problem I/we can help you better...

Alberto

Steve Bergman

unread,
Apr 19, 2006, 5:45:54 PM4/19/06
to TurboGears
I just checked. And in the toolbox, yes, I do get that error.

In my example project, I get no error.

Alberto Valverde

unread,
Apr 19, 2006, 5:52:11 PM4/19/06
to turbo...@googlegroups.com

On 19/04/2006, at 23:45, Steve Bergman wrote:

>
> I just checked. And in the toolbox, yes, I do get that error.
>
> In my example project, I get no error.
>

Damn Heisenberg! ;)

Alberto

Steve Bergman

unread,
Apr 19, 2006, 5:55:03 PM4/19/06
to TurboGears
What is the preferred way to send the app? Can I just attach a tgz?
(Most lists I'm on frown upon binary attachments which is why I ask
first.)

But basically, all that I have done is:

$ tg-admin quickstart ajaxgrid

And then deleted out everything in controllers.py and replaced it with
this:

import cherrypy
import turbogears
from turbogears import controllers, expose, redirect

from turbogears.widgets import AjaxGrid

grid = AjaxGrid(refresh_url="/search", defaults=dict(q='turbogears'))

class Root(controllers.RootController):

@expose()
def index(self):
return grid.render()

@expose(format="json")
def search(self, q):
# get results

results = ["Test Id", "Test Program", "Test Factor"]

Steve Bergman

unread,
Apr 19, 2006, 5:58:03 PM4/19/06
to TurboGears
I'm not certain whether the error appears when I'm not looking. And I
don't have a cat handy to check it with.

Alberto Valverde

unread,
Apr 19, 2006, 6:03:35 PM4/19/06
to turbo...@googlegroups.com

On 19/04/2006, at 23:55, Steve Bergman wrote:

>
> What is the preferred way to send the app? Can I just attach a tgz?
> (Most lists I'm on frown upon binary attachments which is why I ask
> first.)

Upload it at ticket 741. http://tinyurl.com/kyk9g (don't send the app
that works! ;)
A description of your environment would be useful too: "tg-admin info
> myenv" and your browser brand and version number.

Thanks :)

Alberto

Alberto Valverde

unread,
Apr 19, 2006, 6:05:13 PM4/19/06
to turbo...@googlegroups.com

On 19/04/2006, at 23:58, Steve Bergman wrote:

>
> I'm not certain whether the error appears when I'm not looking. And I
> don't have a cat handy to check it with.

LOL :D

Alberto

Steve Bergman

unread,
Apr 19, 2006, 6:36:01 PM4/19/06
to TurboGears
Well, I've added a comment to the ticket with my "tg-admin info" output
and browser version (also included below.)

But I don't have an app that 'works'. I have the toolbox, which gives
the same message as Jorge sees and does not render the grid. And I
have the quickstarted app that I described in message 11 of this
thread, which does not give any error output, but also does not display
the grid.

Do the simple steps I've described in message 11 look like they should
be adequate to get me a viewable grid? (It seems like there should be
more to it, like doing something with mochikit or something.)

Oh, and while the toolbox insists on bringing up mozilla, the browser I
am using to try to view the quickstarted app is firefox 1.0.7.

Thanks for your help.

=========================================

TurboGears 0.9a4
nose 0.8.6
RuleDispatch 0.5a0
setuptools 0.6a11
FormEncode 0.4
cElementTree 1.0.5-20051216
PasteScript 0.5
elementtree 1.2.6
simplejson 1.1
SQLObject 0.7.1dev-r1588
CherryPy 2.2.0
TurboKid 0.9.3
TurboJson 0.9.1
PyProtocols 1.0a0
Cheetah 1.0
PasteDeploy 0.5
Paste 0.5dev-r4745
FormEncode 0.4
kid 0.9.1
elementtree 1.2.6

mozilla-1.7.12-1.4.2.centos4

Jorge Godoy

unread,
Apr 19, 2006, 6:49:12 PM4/19/06
to turbo...@googlegroups.com
Em Quarta 19 Abril 2006 19:36, Steve Bergman escreveu:

> Oh, and while the toolbox insists on bringing up mozilla, the browser I

If you don't want a browser started for you use the "-n" switch: "tg-admin
toolbox -n" will do the trick ;-)

> am using to try to view the quickstarted app is firefox 1.0.7.

Upgrading to 1.5.0.2 will make it very interesting for you. Specially
speedwise. ;-) (But don't stay with 1.5 - 1.5.0.1 since there appears to be
some kind of memory leak with those.)

--
Jorge Godoy <jgo...@gmail.com>

Alberto Valverde

unread,
Apr 19, 2006, 7:03:09 PM4/19/06
to turbo...@googlegroups.com

On 20/04/2006, at 0:36, Steve Bergman wrote:

>
> Well, I've added a comment to the ticket with my "tg-admin info"
> output
> and browser version (also included below.)
>
> But I don't have an app that 'works'. I have the toolbox, which gives
> the same message as Jorge sees and does not render the grid. And I
> have the quickstarted app that I described in message 11 of this
> thread, which does not give any error output, but also does not
> display
> the grid.
>
> Do the simple steps I've described in message 11 look like they should
> be adequate to get me a viewable grid? (It seems like there should be
> more to it, like doing something with mochikit or something.)

I'll try to take a look tomorrow, however, don't expect too much
because this seems a JS issue and I'm not a JS fan or guru or
anything I could politely post in a public ML...

FYI, I'm using 1.5.0.2 on Mac OS and it works flawlesly (Jorge, is
this problem still bugging you?)

Alberto

Jorge Godoy

unread,
Apr 19, 2006, 7:24:21 PM4/19/06
to turbo...@googlegroups.com
Em Quarta 19 Abril 2006 20:03, Alberto Valverde escreveu:

> FYI, I'm using 1.5.0.2 on Mac OS and it works flawlesly (Jorge, is
> this problem still bugging you?)

I can't answer right now. I was caught by the "error" you'll be fixing
tomorrow (the "for_widget" discussed on tg-trunk) -- at least this is what I
believe it is:

Traceback (most recent call last):
File
"/usr/lib/python2.4/site-packages/CherryPy-2.2.0-py2.4.egg/cherrypy/_cphttptools.py",
line 106, in _run
self.main()
File
"/usr/lib/python2.4/site-packages/CherryPy-2.2.0-py2.4.egg/cherrypy/_cphttptools.py",
line 255, in main
body = page_handler(*virtual_path, **self.params)
File "<string>", line 3, in index
File
"/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/controllers.py",
line 206, in expose
output = database.run_with_transaction(expose._expose,func, accept,
allow_json, allow_json_from_config,*args, **kw)
File
"/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/database.py",
line 216, in run_with_transaction
retval = func(*args, **kw)
File "<string>", line 5, in _expose
File
"/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/controllers.py",
line 227, in <lambda>
expose._expose.when(rule)(lambda _func, accept, allow_json,
allow_json_from_config,*args,**kw: _execute_func(
File
"/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/controllers.py",
line 248, in _execute_func
output = errorhandling.try_call(func, *args, **kw)
File
"/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/errorhandling.py",
line 71, in try_call
return func(self, *args, **kw)
File
"/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/toolbox/base.py",
line 47, in index
all_descs[wd.full_class_name.replace(".", "_")] = wd
File
"/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/widgets/forms.py",
line 420, in _get_full_class_name
cls = self.for_widget_class
File
"/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/widgets/base.py",
line 471, in _get_widget_class
return self.for_widget.__class__
AttributeError: __class__

--
Jorge Godoy <jgo...@gmail.com>

Alberto Valverde

unread,
Apr 19, 2006, 8:11:52 PM4/19/06
to turbo...@googlegroups.com

On 20/04/2006, at 1:24, Jorge Godoy wrote:

>
> Em Quarta 19 Abril 2006 20:03, Alberto Valverde escreveu:
>
>> FYI, I'm using 1.5.0.2 on Mac OS and it works flawlesly (Jorge, is
>> this problem still bugging you?)
>
> I can't answer right now. I was caught by the "error" you'll be
> fixing
> tomorrow (the "for_widget" discussed on tg-trunk) -- at least this
> is what I
> believe it is:

Already fixed at 1164 :)

Alberto

Jorge Godoy

unread,
Apr 19, 2006, 8:18:36 PM4/19/06
to turbo...@googlegroups.com

And the bug is gone for me as well. ;-) (Now that I saw the toolbox, I
remember seeing the AjaxGrid widget with a version of FF prior to 1.0.7 --
maybe 1.0.6 or 1.0.5...)

So, there's no bug with AjaxGrid -- it looks like a JS bug or a FF bug... --
and your fix worked for the widget problem ;-)

--
Jorge Godoy <jgo...@gmail.com>

Alberto Valverde

unread,
Apr 19, 2006, 8:24:48 PM4/19/06
to turbo...@googlegroups.com

On 20/04/2006, at 2:18, Jorge Godoy wrote:
> And the bug is gone for me as well. ;-) (Now that I saw the
> toolbox, I
> remember seeing the AjaxGrid widget with a version of FF prior to
> 1.0.7 --
> maybe 1.0.6 or 1.0.5...)
>
> So, there's no bug with AjaxGrid -- it looks like a JS bug or a FF
> bug... --
> and your fix worked for the widget problem ;-)

Great! then we might as well close the ticket... Any objections on this?

Alberto

Jorge Godoy

unread,
Apr 19, 2006, 8:37:27 PM4/19/06
to turbo...@googlegroups.com

Not on my part.

--
Jorge Godoy <jgo...@gmail.com>

Steve Bergman

unread,
Apr 19, 2006, 9:22:16 PM4/19/06
to TurboGears
OK. grid.render()'ing the widget without a template does not work
because the ajaxgrid_0_AjaxGrid() never gets defined on the page. It
needs a template.

Using ajaxgrid is really quite simple. For future first-timers like
me, here is an easy example which works with TG 0.9a4:

1. Quick start a project.
2. Edit controllers.py to look like the following:

==================================
import cherrypy
import turbogears
from turbogears import controllers, expose, redirect
from turbogears import identity
from turbogears.widgets import AjaxGrid

from datetime import datetime

grid = AjaxGrid(refresh_url="/search", defaults=dict(q='turbogears'))

class Root(controllers.RootController):

@expose(template=".templates.form")
def index(self):
return dict(form=grid)

@expose(format="json")
def search(self, q):

# Fake a row of results
date = datetime.today()
hour = date.strftime('%H')
minute = date.strftime('%M')
second = date.strftime('%S')

return dict(
headers = ["Hour", "Minute", "Second"],
rows = [[hour, minute, second]],
)
================================


3. Create the template "form.kid" and make it look like this:

================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://purl.org/kid/ns#"
py:extends="'master.kid'">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type"
py:replace="''"/>
<title>Ajaxgrid Example</title>
</head>
<body>
<span py:content="form.display()"></span>
</body>
</html>
=====================================

4. Start your project and try it out. You should get a single row with
the current hour, minute, and second. It should update when you click
'Update'.

That's it. Wow. AJAX can really be that simple!

gasolin

unread,
Apr 20, 2006, 4:20:11 AM4/20/06
to TurboGears
Steve:

Thanks it works!

Due to help more people touch your post, I'v added your post in
turbogears trac
http://trac.turbogears.org/turbogears/wiki/AjaxGrid

You can add more learning AjaxGrid infomation there:)

--
Fred
--
Fred

Alberto Valverde

unread,
Apr 20, 2006, 8:03:52 AM4/20/06
to turbo...@googlegroups.com

On 20/04/2006, at 3:22, Steve Bergman wrote:
> OK. grid.render()'ing the widget without a template does not work
> because the ajaxgrid_0_AjaxGrid() never gets defined on the page. It
> needs a template.

Ooops, didn't notice you were using render without a page template
which inherited from sitetemplate... A bit of theory because this
applies to all widgets which depend on external JS to work:

All widgets must have two methods called retrieve_css and
rettrieve_javascript so expose() can build a set of all links
required for widgets in the page and include them in their apropiate
places (top or bottom of head or body). These placemarks are defined
in sitetemplate which master.kid inherits from and, ultimately, your
page template. This frees the user from worrying about it, just make
sure your page templates inherit somehow from sitetemplate (should be
alright if always inheriting from master.kid) and Kid's "match"
directive will take care of the rest.

Thanks for the wiki page describing this :) Glad it works now...

Alberto

Reply all
Reply to author
Forward
0 new messages