*UPDATE* This module is no longer maintained. Please use SQLFORM.grid instead.
Add the webgrid.py module to your modules folder (download at bottom)
In your model:
webgrid = local_import('webgrid')
In your controller:
def index():
grid = webgrid.WebGrid(crud)
grid.datasource = db(db.things.id>0)
grid.pagesize = 10
return dict(grid=grid()) #notice the ()
The datasource can be a Set, Rows, Table, or list of Table. Joins are also supported.
grid.datasource = db(db.things.id>0) #Set
grid.datasource = db(db.things.id>0).select() #Rows
grid.datasource = db.things #Table
grid.datasource = [db.things,db.others] #list of Table
grid.datasource = db(db.things.id==db.others.thing)# join
The main row components of the WebGrid are header, filter, datarow, pager, page_total, footer
You can link to crud functions using action_links. Just tell it where crud is exposed:
grid.crud_function = 'data'
You can turn rows on and off:
grid.enabled_rows = ['header','filter', 'pager','totals','footer','add_links']
You can control the fields and field headers:
grid.fields = ['things.name','things.location','things.amount']
grid.field_headers = ['Name','Location','Amount']
You can control the action links (links to crud actions) and action headers:
grid.action_links = ['view','edit','delete']
grid.action_headers = ['view','edit','delete']
You will want to modify crud.settings.[action]_next so that it redirects to your WebGrid page after completing:
if request.controller == 'default' and request.function == 'data':
if request.args:
crud.settings[request.args(0)+'_next'] = URL(r=request,f='index')
You can get page totals for numeric fields:
grid.totals = ['things.amount']
You can set filters on columns:
grid.filters = ['things.name','things.created']
You can modify the Query that filters use (not available if your datasource is a Rows object, use rows.find):
grid.filter_query = lambda f,v: f==v
You can control which request vars are allowed to override the grid settings:
grid.allowed_vars = ['pagesize','pagenum','sortby','ascending','groupby','totals']
The WebGrid will use a field's represent function if present when rendering the cell. If you need more control, you can completely override the way a row is rendered.
The functions that render each row can be replaced with your own lambda or function:
grid.view_link = lambda row: ...
grid.edit_link = lambda row: ...
grid.delete_link = lambda row: ...
grid.header = lambda fields: ...
grid.datarow = lambda row: ...
grid.footer = lambda fields: ...
grid.pager = lambda pagecount: ...
grid.page_total = lambda:
Here are some useful variables for building your own rows:
grid.joined # tells you if your datasource is a join
grid.css_prefix # used for css
grid.tablenames
grid.response # the datasource result
grid.colnames # column names of datasource result
grid.pagenum
grid.pagecount
grid.total # the count of datasource result
For example, let's customize the footer:
grid.footer = lambda fields : TFOOT(TD("This is my footer" ,
_colspan=len(grid.action_links)+len(fields),
_style="text-align:center;"),
_class=grid.css_prefix + '-webgrid footer')
You can also customize messages:
grid.messages.confirm_delete = 'Are you sure?'
grid.messages.no_records = 'No records'
grid.messages.add_link = '[add %s]'
grid.messages.page_total = "Total:"
You can also also use the row_created event to modify the row when it is created. Let's add a column to the header:
def on_row_created(row,rowtype,record):
if rowtype=='header':
row.components.append(TH(' '))
grid.row_created = on_row_created
Let's move the action links to the right side:
def links_right(tablerow,rowtype,rowdata):
if rowtype != 'pager':
links = tablerow.components[:3]
del tablerow.components[:3]
tablerow.components.extend(links)
grid.row_created = links_right
If you are using multiple grids on the same page, they must have unique names.
Comments (112)
- Login to post
order by: newest oldest upvoted downvoted
Thanks to Fran for recent improvements. The WebGrid is now datatables compliant (you must disable the add_link though).
Better, stronger, faster. It now supports multiple grids per page!
Very very nice, usefull and absolutelly reusable.
One thing, anyway to remove links?
grid.action_links = []
grid.action_headers = []
drops an error, and with an empty string, gets badly formated.
A thing I'd love in here would be a search, (server side) searching in all columns with "contains" or something like that. But I guess thats probably in the pipeline already.
Thanks for this great module.
You found a bug! It is fixed now. I'm working on the search feature as we speak :)
I have a problem when my page uses request.args. The links at the grid's header don't work.
So I used this workaround:
--------------------------
if request.args(0):
session.request_var = request.args(0)
..... your code
return(grid=grid())
else:
arg = request.function + '/' + session.request_var + '?'
vars = ''
for var in request.vars.keys():
vars= vars + var + '=' + request.vars[var] + '&'
vars = vars[:-1]
arg = arg + vars
redirect(arg)
-------------------
the important thing to change is the value of request.args(0) in session.your_request.var.
Would be good if Webgrid detects if has request.args and correct the link at header of table.
show more comments0
mrfreeze 15 years ago
0
mrfreeze 15 years ago
0
benigno 15 years ago
0
mrfreeze 15 years ago
0
alexandreandrade 15 years ago