sorting by link on column header on reporting results
This commit is contained in:
		
							parent
							
								
									ef61a836a4
								
							
						
					
					
						commit
						d317612187
					
				
					 4 changed files with 93 additions and 18 deletions
				
			
		|  | @ -132,7 +132,55 @@ class EditForm(form.EditForm): | ||||||
|         return parentUrl + '/contents.html' |         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 = {} |     actions = {} | ||||||
|     portlet_actions = [] |     portlet_actions = [] | ||||||
|  |  | ||||||
|  | @ -192,6 +192,13 @@ class ResultsConceptView(ConceptView): | ||||||
|         ri = component.getAdapter(self.report, IReportInstance, |         ri = component.getAdapter(self.report, IReportInstance, | ||||||
|                                   name=reportType) |                                   name=reportType) | ||||||
|         ri.view = self |         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 |         return ri | ||||||
| 
 | 
 | ||||||
|     def results(self): |     def results(self): | ||||||
|  | @ -212,6 +219,12 @@ class ResultsConceptView(ConceptView): | ||||||
|         if opt: |         if opt: | ||||||
|             return opt[0] |             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): | class EmbeddedResultsConceptView(ResultsConceptView): | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -35,38 +35,50 @@ | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| <div metal:define-macro="results"> | <div metal:define-macro="results" | ||||||
|  |      tal:define="tableName string:results"> | ||||||
|   <br /> |   <br /> | ||||||
|   <tal:download condition="item/downloadLink"> |   <tal:download condition="item/downloadLink"> | ||||||
|     <div class="button"> |     <div class="button"> | ||||||
|       <a i18n:translate="" |       <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> |     </div> | ||||||
|     <br /> |     <br /> | ||||||
|   </tal:download> |   </tal:download> | ||||||
|   <table class="report" |   <table class="report" | ||||||
|          tal:define="results reportView/results"> |          tal:define="results reportView/results"> | ||||||
|     <tr> |     <tr> | ||||||
|         <th tal:repeat="col results/displayedColumns" |       <th style="white-space: nowrap" | ||||||
|             tal:content="col/title" |           tal:repeat="col results/displayedColumns"> | ||||||
|             tal:attributes="class col/cssClass" |         <a tal:define="colName col/name" | ||||||
|             i18n:translate="" /> |            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> | ||||||
|     <tr tal:repeat="row results" |     <tr tal:repeat="row results" | ||||||
|         tal:attributes="class python:(repeat['row'].index() % 2) and 'even' or 'odd'"> |         tal:attributes="class python:(repeat['row'].index() % 2) and 'even' or 'odd'"> | ||||||
|         <td tal:repeat="col results/displayedColumns" |       <td tal:repeat="col results/displayedColumns" | ||||||
|             tal:attributes="class col/cssClass"> |           tal:attributes="class col/cssClass"> | ||||||
|             <metal:column use-macro="python: |           <metal:column use-macro="python: | ||||||
|                             reportView.getColumnRenderer(col)" /> |                           reportView.getColumnRenderer(col)" /> | ||||||
|         </td> |       </td> | ||||||
|     </tr> |     </tr> | ||||||
|     <tr tal:define="row nocall:results/totals" |     <tr tal:define="row nocall:results/totals" | ||||||
|         tal:condition="nocall:row"> |         tal:condition="nocall:row"> | ||||||
|         <td tal:repeat="col results/displayedColumns" |       <td tal:repeat="col results/displayedColumns" | ||||||
|             tal:attributes="class col/cssClass"> |           tal:attributes="class col/cssClass"> | ||||||
|             <metal:column use-macro="python: |           <metal:column use-macro="python: | ||||||
|                             reportView.getColumnRenderer(col)" /> |                           reportView.getColumnRenderer(col)" /> | ||||||
|         </td> |       </td> | ||||||
|     </tr> |     </tr> | ||||||
|   </table> |   </table> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -120,7 +120,9 @@ class ReportInstance(BaseReport): | ||||||
|         result = list(self.selectObjects(parts))  # may modify parts |         result = list(self.selectObjects(parts))  # may modify parts | ||||||
|         qc = CompoundQueryCriteria(parts) |         qc = CompoundQueryCriteria(parts) | ||||||
|         return ResultSet(self, result, rowFactory=self.rowFactory, |         return ResultSet(self, result, rowFactory=self.rowFactory, | ||||||
|                          sortCriteria=self.getSortCriteria(), queryCriteria=qc, |                          sortCriteria=self.getSortCriteria(),  | ||||||
|  |                          sortDescending=self.sortDescending, | ||||||
|  |                          queryCriteria=qc, | ||||||
|                          limits=limits) |                          limits=limits) | ||||||
| 
 | 
 | ||||||
|     def selectObjects(self, parts): |     def selectObjects(self, parts): | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue