diff --git a/fields/ref.py b/fields/ref.py
index 7dcb8b0..07ebfa6 100644
--- a/fields/ref.py
+++ b/fields/ref.py
@@ -241,7 +241,7 @@ class Ref(Field):
+ onclick=":'toggleAllCbs(%s)' % q(ajaxHookId)"/>
@@ -272,7 +272,7 @@ class Ref(Field):
+ value=":tiedUid" onclick="toggleCb(this)"/>
@@ -286,7 +286,7 @@ class Ref(Field):
''')
# 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
# class "Field"), it will be used instead of select (or sselect below).
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
# is different from the one produced by self.select, define an
# alternative method in field "sselect" below.
@@ -1145,7 +1148,7 @@ class Ref(Field):
and may hold "unchecked" (initial semantics) or "checked" (inverted
semantics). Inverting semantics allows to keep the array small even
when checking/unchecking all checkboxes.
-
+
The mentioned JS arrays and variables are stored as attributes of the
DOM node representing this field.'''
# The initial semantics depends on the checkboxes default value.
diff --git a/fields/search.py b/fields/search.py
index e602224..4a4f9f0 100644
--- a/fields/search.py
+++ b/fields/search.py
@@ -26,7 +26,8 @@ class Search:
'''Used for specifying a search for a given class.'''
def __init__(self, name, group=None, sortBy='', sortOrder='asc', limit=None,
default=False, colspan=1, translated=None, show=True,
- translatedDescr=None, **fields):
+ translatedDescr=None, checkboxes=False, checkboxesDefault=True,
+ **fields):
self.name = name
# Searches may be visually grouped in the portlet.
self.group = Group.get(group)
@@ -46,6 +47,10 @@ class Search:
# In the dict below, keys are indexed field names or names of standard
# indexes, and values are search values.
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
def getIndexName(fieldName, usage='search'):
@@ -140,6 +145,14 @@ class Search:
return gutils.callMethod(tool, self.show, klass=klass)
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:
'''Instances of this class are generated on-the-fly for manipulating a
Search from the User Interface.'''
diff --git a/gen/ui/appy.js b/gen/ui/appy.js
index f09abde..308d0bf 100644
--- a/gen/ui/appy.js
+++ b/gen/ui/appy.js
@@ -224,7 +224,8 @@ function askQueryResult(hookId, objectUrl, className, searchName, popup,
params['filterValue'] = filterWidget.value;
}
}
- askAjaxChunk(hookId, 'GET', objectUrl, 'pxQueryResult', params);
+ askAjaxChunk(hookId, 'GET', objectUrl, 'pxQueryResult', params, null,
+ evalInnerScripts);
}
function askObjectHistory(hookId, objectUrl, maxPerPage, startNumber) {
@@ -316,7 +317,7 @@ function _rsplit(s, delimiter, limit) {
}
// (Un)checks a checkbox corresponding to a linked object.
-function toggleRefCb(checkbox) {
+function toggleCb(checkbox) {
var name = checkbox.getAttribute('name');
var elems = _rsplit(name, '_', 3);
// Get the DOM node corresponding to the Ref field.
@@ -336,8 +337,8 @@ function toggleRefCb(checkbox) {
}
}
-// Initialise checkboxes of a Ref field.
-function initRefCbs(id) {
+// Initialise checkboxes of a Ref field or Search.
+function initCbs(id) {
var elems = _rsplit(id, '_', 3);
// Get the DOM node corresponding to the Ref field.
var node = document.getElementById(elems[0] + '_' + elems[1]);
@@ -354,8 +355,8 @@ function initRefCbs(id) {
}
}
-// Toggle all checkboxes of a Ref field.
-function toggleAllRefCbs(id) {
+// Toggle all checkboxes of a Ref field or Search.
+function toggleAllCbs(id) {
var elems = _rsplit(id, '_', 3);
// Get the DOM node corresponding to the Ref field.
var node = document.getElementById(elems[0] + '_' + elems[1]);
@@ -367,7 +368,7 @@ function toggleAllRefCbs(id) {
if (node[semAttr] == 'unchecked') node[semAttr] = 'checked';
else node[semAttr] = 'unchecked';
// Update the visible checkboxes
- initRefCbs(id);
+ initCbs(id);
}
// Shows/hides a dropdown menu
diff --git a/gen/wrappers/ToolWrapper.py b/gen/wrappers/ToolWrapper.py
index d888295..80a8077 100644
--- a/gen/wrappers/ToolWrapper.py
+++ b/gen/wrappers/ToolWrapper.py
@@ -361,30 +361,47 @@ class ToolWrapper(AbstractWrapper):
# Show query results as a list.
pxQueryResultList = Px('''
-
+
+ ''')
# Show query results as a grid.
pxQueryResultGrid = Px('''
@@ -405,9 +422,12 @@ class ToolWrapper(AbstractWrapper):
# Show paginated query results as a list or grid.
pxQueryResult = Px('''
-
+ target=ztool.getLinksTargetInfo(ztool.getAppyClass(className))"
+ id=":ajaxHookId">
@@ -492,10 +510,16 @@ class ToolWrapper(AbstractWrapper):