[gen] Allow to show checkboxes for search results.
This commit is contained in:
parent
b2a2aa5210
commit
792db32f27
|
@ -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.
|
||||||
|
@ -1145,7 +1148,7 @@ class Ref(Field):
|
||||||
and may hold "unchecked" (initial semantics) or "checked" (inverted
|
and may hold "unchecked" (initial semantics) or "checked" (inverted
|
||||||
semantics). Inverting semantics allows to keep the array small even
|
semantics). Inverting semantics allows to keep the array small even
|
||||||
when checking/unchecking all checkboxes.
|
when checking/unchecking all checkboxes.
|
||||||
|
|
||||||
The mentioned JS arrays and variables are stored as attributes of the
|
The mentioned JS arrays and variables are stored as attributes of the
|
||||||
DOM node representing this field.'''
|
DOM node representing this field.'''
|
||||||
# The initial semantics depends on the checkboxes default value.
|
# The initial semantics depends on the checkboxes default value.
|
||||||
|
|
|
@ -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.'''
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -361,30 +361,47 @@ 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;
|
||||||
<!-- Headers, with filters and sort arrows -->
|
checkboxes=uiSearch.search.checkboxes;
|
||||||
<tr if="showHeaders">
|
checkboxesId=rootHookId + '_objs'">
|
||||||
<th for="column in columns"
|
<table class="list" width="100%">
|
||||||
var2="field=column.field;
|
<!-- Headers, with filters and sort arrows -->
|
||||||
sortable=ztool.isSortable(field.name, className, 'search');
|
<tr if="showHeaders">
|
||||||
filterable=field.filterable"
|
<th for="column in columns"
|
||||||
width=":column.width" align=":column.align">
|
var2="field=column.field;
|
||||||
<x>::ztool.truncateText(_(field.labelId))</x>
|
sortable=ztool.isSortable(field.name, className, 'search');
|
||||||
<x>:tool.pxSortAndFilter</x><x>:tool.pxShowDetails</x>
|
filterable=field.filterable"
|
||||||
</th>
|
width=":column.width" align=":column.align">
|
||||||
</tr>
|
<x>::ztool.truncateText(_(field.labelId))</x>
|
||||||
|
<x>:tool.pxSortAndFilter</x><x>:tool.pxShowDetails</x>
|
||||||
|
</th>
|
||||||
|
<th if="checkboxes" class="cbCell">
|
||||||
|
<img src=":url('checkall')" class="clickable"
|
||||||
|
title=":_('check_uncheck')"
|
||||||
|
onclick=":'toggleAllCbs(%s)' % q(checkboxesId)"/>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<!-- Results -->
|
<!-- Results -->
|
||||||
<tr for="zobj in zobjects" id="query_row" valign="top"
|
<tr for="zobj in zobjects" id="query_row" valign="top"
|
||||||
var2="@currentNumber=currentNumber + 1;
|
var2="@currentNumber=currentNumber + 1;
|
||||||
obj=zobj.appy(); mayView=zobj.mayView()"
|
obj=zobj.appy(); mayView=zobj.mayView()"
|
||||||
class=":loop.zobj.odd and 'even' or 'odd'">
|
class=":loop.zobj.odd and 'even' or 'odd'">
|
||||||
<td for="column in columns"
|
<td for="column in columns"
|
||||||
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>
|
||||||
</tr>
|
<!-- A checkbox if required -->
|
||||||
</table>''')
|
<td if="checkboxes" class="cbCell">
|
||||||
|
<input type="checkbox" name=":checkboxesId" checked="checked"
|
||||||
|
value=":zobj.id" onclick="toggleCb(this)"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</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'];
|
||||||
|
|
Loading…
Reference in a new issue