sorting by link on column header on reporting results

This commit is contained in:
Helmut Merz 2015-03-21 17:12:16 +01:00
parent ef61a836a4
commit d317612187
4 changed files with 93 additions and 18 deletions

View file

@ -132,7 +132,55 @@ class EditForm(form.EditForm):
return parentUrl + '/contents.html'
class BaseView(GenericView, I18NView):
class SortableMixin(object):
@Lazy
def sortInfo(self):
result = {}
for k, v in self.request.form.items():
if k.startswith('sortinfo_'):
tableName = k[len('sortinfo_'):]
if ',' in v:
fn, dir = v.split(',')
else:
fn = v
dir = 'asc'
result[tableName] = dict(colName=fn, ascending=(dir=='asc'))
return result
def isSortableColumn(self, tableName, colName):
return False # overwrite in subclass
def getSortUrl(self, tableName, colName):
url = str(self.request.URL)
paramChar = '?' in url and '&' or '?'
si = self.sortInfo.get(tableName)
if si is not None and si.get('colName') == colName:
dir = si['ascending'] and 'desc' or 'asc'
else:
dir = 'asc'
return '%s%ssortinfo_%s=%s,%s' % (url, paramChar, tableName, colName, dir)
def getSortParams(self, tableName):
url = str(self.request.URL)
paramChar = '?' in url and '&' or '?'
si = self.sortInfo.get(tableName)
if si is not None:
colName = si['colName']
dir = si['ascending'] and 'asc' or 'desc'
return '%ssortinfo_%s=%s,%s' % (paramChar, tableName, colName, dir)
return ''
def getSortImage(self, tableName, colName):
si = self.sortInfo.get(tableName)
if si is not None and si.get('colName') == colName:
if si['ascending']:
return '/@@/cybertools.icons/arrowdown.gif'
else:
return '/@@/cybertools.icons/arrowup.gif'
class BaseView(GenericView, I18NView, SortableMixin):
actions = {}
portlet_actions = []

View file

@ -192,6 +192,13 @@ class ResultsConceptView(ConceptView):
ri = component.getAdapter(self.report, IReportInstance,
name=reportType)
ri.view = self
if not ri.sortCriteria:
si = self.sortInfo.get('results')
if si is not None:
fnames = (si['colName'],)
ri.sortCriteria = [f for f in ri.getSortFields()
if f.name in fnames]
ri.sortDescending = not si['ascending']
return ri
def results(self):
@ -212,6 +219,12 @@ class ResultsConceptView(ConceptView):
if opt:
return opt[0]
def isSortableColumn(self, tableName, colName):
if tableName == 'results':
if colName in [f.name for f in self.reportInstance.getSortFields()]:
return True
return False
class EmbeddedResultsConceptView(ResultsConceptView):

View file

@ -35,38 +35,50 @@
</div>
<div metal:define-macro="results">
<div metal:define-macro="results"
tal:define="tableName string:results">
<br />
<tal:download condition="item/downloadLink">
<div class="button">
<a i18n:translate=""
tal:attributes="href item/downloadLink">Download Data</a>
tal:define="params python:item.getSortParams(tableName)"
tal:attributes="href string:${item/downloadLink}$params">Download Data</a>
</div>
<br />
</tal:download>
<table class="report"
tal:define="results reportView/results">
<tr>
<th tal:repeat="col results/displayedColumns"
tal:content="col/title"
tal:attributes="class col/cssClass"
i18n:translate="" />
<th style="white-space: nowrap"
tal:repeat="col results/displayedColumns">
<a tal:define="colName col/name"
tal:attributes="href python:
item.getSortUrl(tableName, colName)"
tal:omit-tag="python:not item.isSortableColumn(tableName, colName)">
<span tal:content="col/title"
tal:attributes="class col/cssClass"
i18n:translate="" />
<img tal:define="src python:item.getSortImage(tableName, colName)"
tal:condition="src"
tal:attributes="src src" />
</a>
</th>
</tr>
<tr tal:repeat="row results"
tal:attributes="class python:(repeat['row'].index() % 2) and 'even' or 'odd'">
<td tal:repeat="col results/displayedColumns"
tal:attributes="class col/cssClass">
<metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td>
<td tal:repeat="col results/displayedColumns"
tal:attributes="class col/cssClass">
<metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td>
</tr>
<tr tal:define="row nocall:results/totals"
tal:condition="nocall:row">
<td tal:repeat="col results/displayedColumns"
tal:attributes="class col/cssClass">
<metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td>
<td tal:repeat="col results/displayedColumns"
tal:attributes="class col/cssClass">
<metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td>
</tr>
</table>
</div>

View file

@ -120,7 +120,9 @@ class ReportInstance(BaseReport):
result = list(self.selectObjects(parts)) # may modify parts
qc = CompoundQueryCriteria(parts)
return ResultSet(self, result, rowFactory=self.rowFactory,
sortCriteria=self.getSortCriteria(), queryCriteria=qc,
sortCriteria=self.getSortCriteria(),
sortDescending=self.sortDescending,
queryCriteria=qc,
limits=limits)
def selectObjects(self, parts):