[wiki:Haiti] == Server-Side Pagination == Currently we do all pagination client-side which won't be possible to keep doing as we accumulate more data This will be needed for: * [wiki:HaitiRMSToDo Request Management System] * [wiki:HaitiOrgsToDo Organisation Registry] * [wiki:HaitiVolToDo Volunteer Registry] === Status === * The Back-end is now done for HTML representation * The Back-end was already done for JSON representation, now done in the dataTables way * The Front-end is done: 50 records at a time :) * !ToDo: * ~~Push from Dev to Live~~ * ~~Render as .represent~~ * ~~Render the ID as View/Edit button depending on perms~~ * ~~Done via a .represent for RMS~~ * ~~Return RMS to Live (1 line in Controller functions: response.s3.pagination = True)~~ * Handle Component Views (use list_fields instead of all readable) * ~~Sort Columns (orderby)~~ need to enhance sorting for reference columns: it is expected to be alphabetic, and now it is per foreign ids * ~~Search (filtering)~~ need to include reference columns (lookup tables at least) which are being ignored currently * XSLT to generate dataTables-compliant JSON? (update: was not needed for the current functionality) === Front-end implementation === * http://datatables.net/examples/data_sources/server_side.html * http://datatables.net/usage/server-side * We'll also need to hand-off the Searching & Sorting! Client-side, we need to add these options to {{{views/dataTables.html}}} [make them Optional per-REST Controller?]: {{{ "bProcessing": true, "bServerSide": true, "sAjaxSource": "{{=URL(r=request, c='module', r='resource', vars={'...':'...'})}}" }}} Server-side, we need to understand these vars: {{{ # Pagination iDisplayStart - maps to 'start' iDisplayLength - maps to 'limit' # Ordering iSortCol_0 iSortingCols iSortCol_x iSortDir_x <<<<--------- now sSortDir_x since jquery.dataTables.fixed.js 1.6.1 need to watch out for the future upgrades compatibility! # Filtering (Search) - across all fields! sSearch }}} response should be sent in this format: {{{ { "sEcho": 1, "aaData": [ [row1.id, row1.field2, ...], [row2.id, row2.field2, ...], [row3.id, row3.field2, ...] ], "iTotalRecords": 3, "iTotalDisplayRecords": 3 } }}} e.g. using a function like (although we've integarted into {{{models/01_RESTlike_controller.py}}}): {{{ def callback(): iDisplayStart = int(request.vars.iDisplayStart) iDisplayLength = int(request.vars.iDisplayLength) from gluon.serializers import json _table = '%s_%s' % (request.controller, request.function) table = db[_table] query = (table.id > 0) rows = db(query).select(limitby = (iDisplayStart, iDisplayStart + iDisplayLength)) r = dict(sEcho = 1, iTotalRecords = len(rows), iTotalDisplayRecords = len(rows), aaData = [[row[f] for f in table.fields if table[f].readable] for row in rows]) return json(r) }}} Problems: * ~~http://datatables.net/forums/comments.php?DiscussionID=1156&page=1#Item_1~~ * ~~No .represent rendered~~ * ~~Represent doesn't handle ID, so can't pledge Aid for Requests in RMS (or see record details in OR)~~ * ~~Represent doesn't handle the marker_id, so gis_location has the big image for each marker visible~~ === JSON Back-end implementation === * Support already present in {{{modules\s3xrc.py}}} * {{{http://S3_PUBLIC_URL/module/resource.json?limit=x&start=y}}} * needs patching for dataTables-expectations: {{{ if "start" in self.request.vars: start = int(self.request.vars["start"]) elif "iDisplayStart" in self.request.vars: # dataTables start = int(self.request.vars["iDisplayStart"]) else: start = None if "limit" in self.request.vars: limit = int(self.request.vars["limit"]) elif "iDisplayLength" in self.request.vars: # dataTables limit = int(self.request.vars["iDisplayLength"]) else: limit = None }}} * actually needs a complete new representation unless this could be done via XSLT!? * still needs extension adding to shn_xml_export_formats in {{{models\01_RESTlike_controller.py}}} === HTML Back-end implementation === Patched the {{{models\01_RESTlike_Controller}}} to support {{{http://S3_PUBLIC_URL/module/resource?limit=x&start=y}}} {{{ shn_list() ... if request.vars.limit: limit = int(request.vars.limit) if request.vars.start: start = int(request.vars.start) limitby = (start, start + limit) else: limitby = (0, limit) else: limitby = None ... items = crud.select(table, query=query, ... limitby=limitby, ... ) }}} === Other Options === * ExtJS * Maybe look at the currently-unused {{{modules/webgrid.py}}}: http://www.web2pyslices.com/main/slices/take_slice/39 * pagenav in {{{models\01_RESTlike_Controller}}} was an older implementation of a webgrid...has been removed. ---- [wiki:Haiti]