[gen] Allow to show checkboxes for search results.

This commit is contained in:
Gaetan Delannay 2014-07-19 13:42:39 +02:00
parent b2a2aa5210
commit 792db32f27
4 changed files with 83 additions and 42 deletions

View file

@ -241,7 +241,7 @@ class Ref(Field):
<th if="checkboxes" class="cbCell"> <th if="checkboxes" class="cbCell">
<img src=":url('checkall')" class="clickable" <img src=":url('checkall')" class="clickable"
title=":_('check_uncheck')" title=":_('check_uncheck')"
onclick=":'toggleAllRefCbs(%s)' % q(ajaxHookId)"/> onclick=":'toggleAllCbs(%s)' % q(ajaxHookId)"/>
</th> </th>
</tr> </tr>
<!-- Loop on every (tied or selectable) object. --> <!-- Loop on every (tied or selectable) object. -->
@ -272,7 +272,7 @@ class Ref(Field):
</td> </td>
<td if="checkboxes" class="cbCell"> <td if="checkboxes" class="cbCell">
<input if="mayView" type="checkbox" name=":ajaxHookId" checked="checked" <input if="mayView" type="checkbox" name=":ajaxHookId" checked="checked"
value=":tiedUid" onclick="toggleRefCb(this)"/> value=":tiedUid" onclick="toggleCb(this)"/>
</td> </td>
</tr> </tr>
</table> </table>
@ -286,7 +286,7 @@ class Ref(Field):
<!-- Init checkboxes if present. --> <!-- Init checkboxes if present. -->
<script if="checkboxes" <script if="checkboxes"
type="text/javascript">:'initRefCbs(%s)' % q(ajaxHookId) type="text/javascript">:'initCbs(%s)' % q(ajaxHookId)
</script>''') </script>''')
# PX that displays the list of objects the user may select to insert into a # PX that displays the list of objects the user may select to insert into a
@ -608,7 +608,10 @@ class Ref(Field):
# NOTE that when a method is defined in field "masterValue" (see parent # NOTE that when a method is defined in field "masterValue" (see parent
# class "Field"), it will be used instead of select (or sselect below). # class "Field"), it will be used instead of select (or sselect below).
self.select = select self.select = select
if isinstance(select, Search): self.select.name = '_field_' if isinstance(select, Search):
select.name = '_field_'
select.checkboxes = True
select.checkboxesDefault = False
# If you want to specify, for the search screen, a list of objects that # If you want to specify, for the search screen, a list of objects that
# is different from the one produced by self.select, define an # is different from the one produced by self.select, define an
# alternative method in field "sselect" below. # alternative method in field "sselect" below.

View file

@ -26,7 +26,8 @@ class Search:
'''Used for specifying a search for a given class.''' '''Used for specifying a search for a given class.'''
def __init__(self, name, group=None, sortBy='', sortOrder='asc', limit=None, def __init__(self, name, group=None, sortBy='', sortOrder='asc', limit=None,
default=False, colspan=1, translated=None, show=True, default=False, colspan=1, translated=None, show=True,
translatedDescr=None, **fields): translatedDescr=None, checkboxes=False, checkboxesDefault=True,
**fields):
self.name = name self.name = name
# Searches may be visually grouped in the portlet. # Searches may be visually grouped in the portlet.
self.group = Group.get(group) self.group = Group.get(group)
@ -46,6 +47,10 @@ class Search:
# In the dict below, keys are indexed field names or names of standard # In the dict below, keys are indexed field names or names of standard
# indexes, and values are search values. # indexes, and values are search values.
self.fields = fields self.fields = fields
# Do we need to display checkboxes for every object of the query result?
self.checkboxes = checkboxes
# Default value for checkboxes
self.checkboxesDefault = checkboxesDefault
@staticmethod @staticmethod
def getIndexName(fieldName, usage='search'): def getIndexName(fieldName, usage='search'):
@ -140,6 +145,14 @@ class Search:
return gutils.callMethod(tool, self.show, klass=klass) return gutils.callMethod(tool, self.show, klass=klass)
return self.show return self.show
def getCbJsInit(self, hookId):
'''Returns the code that creates JS data structures for storing the
status of checkboxes for every result of this search.'''
default = self.checkboxesDefault and 'unchecked' or 'checked'
return '''var node=document.getElementById('%s');
node['_appy_objs_cbs'] = {};
node['_appy_objs_sem'] = '%s';''' % (hookId, default)
class UiSearch: class UiSearch:
'''Instances of this class are generated on-the-fly for manipulating a '''Instances of this class are generated on-the-fly for manipulating a
Search from the User Interface.''' Search from the User Interface.'''

View file

@ -224,7 +224,8 @@ function askQueryResult(hookId, objectUrl, className, searchName, popup,
params['filterValue'] = filterWidget.value; params['filterValue'] = filterWidget.value;
} }
} }
askAjaxChunk(hookId, 'GET', objectUrl, 'pxQueryResult', params); askAjaxChunk(hookId, 'GET', objectUrl, 'pxQueryResult', params, null,
evalInnerScripts);
} }
function askObjectHistory(hookId, objectUrl, maxPerPage, startNumber) { function askObjectHistory(hookId, objectUrl, maxPerPage, startNumber) {
@ -316,7 +317,7 @@ function _rsplit(s, delimiter, limit) {
} }
// (Un)checks a checkbox corresponding to a linked object. // (Un)checks a checkbox corresponding to a linked object.
function toggleRefCb(checkbox) { function toggleCb(checkbox) {
var name = checkbox.getAttribute('name'); var name = checkbox.getAttribute('name');
var elems = _rsplit(name, '_', 3); var elems = _rsplit(name, '_', 3);
// Get the DOM node corresponding to the Ref field. // Get the DOM node corresponding to the Ref field.
@ -336,8 +337,8 @@ function toggleRefCb(checkbox) {
} }
} }
// Initialise checkboxes of a Ref field. // Initialise checkboxes of a Ref field or Search.
function initRefCbs(id) { function initCbs(id) {
var elems = _rsplit(id, '_', 3); var elems = _rsplit(id, '_', 3);
// Get the DOM node corresponding to the Ref field. // Get the DOM node corresponding to the Ref field.
var node = document.getElementById(elems[0] + '_' + elems[1]); var node = document.getElementById(elems[0] + '_' + elems[1]);
@ -354,8 +355,8 @@ function initRefCbs(id) {
} }
} }
// Toggle all checkboxes of a Ref field. // Toggle all checkboxes of a Ref field or Search.
function toggleAllRefCbs(id) { function toggleAllCbs(id) {
var elems = _rsplit(id, '_', 3); var elems = _rsplit(id, '_', 3);
// Get the DOM node corresponding to the Ref field. // Get the DOM node corresponding to the Ref field.
var node = document.getElementById(elems[0] + '_' + elems[1]); var node = document.getElementById(elems[0] + '_' + elems[1]);
@ -367,7 +368,7 @@ function toggleAllRefCbs(id) {
if (node[semAttr] == 'unchecked') node[semAttr] = 'checked'; if (node[semAttr] == 'unchecked') node[semAttr] = 'checked';
else node[semAttr] = 'unchecked'; else node[semAttr] = 'unchecked';
// Update the visible checkboxes // Update the visible checkboxes
initRefCbs(id); initCbs(id);
} }
// Shows/hides a dropdown menu // Shows/hides a dropdown menu

View file

@ -361,7 +361,10 @@ class ToolWrapper(AbstractWrapper):
# Show query results as a list. # Show query results as a list.
pxQueryResultList = Px(''' pxQueryResultList = Px('''
<table class="list" width="100%" var="showHeaders=showHeaders|True"> <x var="showHeaders=showHeaders|True;
checkboxes=uiSearch.search.checkboxes;
checkboxesId=rootHookId + '_objs'">
<table class="list" width="100%">
<!-- Headers, with filters and sort arrows --> <!-- Headers, with filters and sort arrows -->
<tr if="showHeaders"> <tr if="showHeaders">
<th for="column in columns" <th for="column in columns"
@ -372,6 +375,11 @@ class ToolWrapper(AbstractWrapper):
<x>::ztool.truncateText(_(field.labelId))</x> <x>::ztool.truncateText(_(field.labelId))</x>
<x>:tool.pxSortAndFilter</x><x>:tool.pxShowDetails</x> <x>:tool.pxSortAndFilter</x><x>:tool.pxShowDetails</x>
</th> </th>
<th if="checkboxes" class="cbCell">
<img src=":url('checkall')" class="clickable"
title=":_('check_uncheck')"
onclick=":'toggleAllCbs(%s)' % q(checkboxesId)"/>
</th>
</tr> </tr>
<!-- Results --> <!-- Results -->
@ -383,8 +391,17 @@ class ToolWrapper(AbstractWrapper):
var2="field=column.field" id=":'field_%s' % field.name" var2="field=column.field" id=":'field_%s' % field.name"
width=":column.width" width=":column.width"
align=":column.align">:tool.pxQueryField</td> align=":column.align">:tool.pxQueryField</td>
<!-- A checkbox if required -->
<td if="checkboxes" class="cbCell">
<input type="checkbox" name=":checkboxesId" checked="checked"
value=":zobj.id" onclick="toggleCb(this)"/>
</td>
</tr> </tr>
</table>''') </table>
<!-- Init checkboxes if present. -->
<script if="checkboxes"
type="text/javascript">:'initCbs(%s)' % q(checkboxesId)
</script></x>''')
# Show query results as a grid. # Show query results as a grid.
pxQueryResultGrid = Px(''' pxQueryResultGrid = Px('''
@ -405,9 +422,12 @@ class ToolWrapper(AbstractWrapper):
# Show paginated query results as a list or grid. # Show paginated query results as a list or grid.
pxQueryResult = Px(''' pxQueryResult = Px('''
<div id="queryResult" <div var="ajaxHookId='queryResult';
var="_=ztool.translate; _=ztool.translate;
className=req['className']; className=req['className'];
searchName=req.get('search', '');
rootHookId=rootHookId|'%s_search' % className;
uiSearch=uiSearch|ztool.getSearch(className,searchName,ui=True);
refInfo=ztool.getRefInfo(); refInfo=ztool.getRefInfo();
refObject=refInfo[0]; refObject=refInfo[0];
refField=refInfo[1]; refField=refInfo[1];
@ -415,8 +435,6 @@ class ToolWrapper(AbstractWrapper):
refField)) or ''; refField)) or '';
startNumber=req.get('startNumber', '0'); startNumber=req.get('startNumber', '0');
startNumber=int(startNumber); startNumber=int(startNumber);
searchName=req.get('search', '');
uiSearch=ztool.getSearch(className, searchName, ui=True);
sortKey=req.get('sortKey', ''); sortKey=req.get('sortKey', '');
sortOrder=req.get('sortOrder', 'asc'); sortOrder=req.get('sortOrder', 'asc');
filterKey=req.get('filterKey', ''); filterKey=req.get('filterKey', '');
@ -430,7 +448,6 @@ class ToolWrapper(AbstractWrapper):
totalNumber=queryResult.totalNumber; totalNumber=queryResult.totalNumber;
batchSize=queryResult.batchSize; batchSize=queryResult.batchSize;
batchNumber=len(zobjects); batchNumber=len(zobjects);
ajaxHookId='queryResult';
navBaseCall='askQueryResult(%s,%s,%s,%s,%s,**v**)' % \ navBaseCall='askQueryResult(%s,%s,%s,%s,%s,**v**)' % \
(q(ajaxHookId), q(ztool.absolute_url()), q(className), \ (q(ajaxHookId), q(ztool.absolute_url()), q(className), \
q(searchName),int(inPopup)); q(searchName),int(inPopup));
@ -440,7 +457,8 @@ class ToolWrapper(AbstractWrapper):
(ztool.absolute_url(), className, refUrlPart); (ztool.absolute_url(), className, refUrlPart);
showSubTitles=req.get('showSubTitles', 'true') == 'true'; showSubTitles=req.get('showSubTitles', 'true') == 'true';
resultMode=ztool.getResultMode(className); resultMode=ztool.getResultMode(className);
target=ztool.getLinksTargetInfo(ztool.getAppyClass(className))"> target=ztool.getLinksTargetInfo(ztool.getAppyClass(className))"
id=":ajaxHookId">
<x if="zobjects"> <x if="zobjects">
<!-- Display here POD templates if required. --> <!-- Display here POD templates if required. -->
@ -492,10 +510,16 @@ class ToolWrapper(AbstractWrapper):
</div>''') </div>''')
pxQuery = Px(''' pxQuery = Px('''
<x var="className=req['className']; searchName=req.get('search', ''); <div var="className=req['className'];
cssJs=None"> searchName=req.get('search', '');
<x>:tool.pxPagePrologue</x><x>:tool.pxQueryResult</x> uiSearch=ztool.getSearch(className, searchName, ui=True);
</x>''', template=AbstractWrapper.pxTemplate, hook='content') rootHookId='%s_search' % className;
cssJs=None"
id=":rootHookId">
<script type="text/javascript">:uiSearch.search.getCbJsInit(rootHookId)
</script>
<x if="not inPopup">:tool.pxPagePrologue</x><x>:tool.pxQueryResult</x>
</div>''', template=AbstractWrapper.pxTemplate, hook='content')
pxSearch = Px(''' pxSearch = Px('''
<x var="className=req['className']; <x var="className=req['className'];