Commit de972081 authored by Julien Muchembled's avatar Julien Muchembled

listbox: sorting by CAST type (float)

Only 'float' supported for the moment. This should cover the case of integers.

Example of 'Sortable Columns' value in a ListBox:

  id | float
  title |

Since there's a fallback to 'Searchable Columns' when 'Sortable Columns' is
empty, the cast type can also be specified there, in order to avoid duplication.
parent d22b6502
......@@ -237,13 +237,9 @@
<string>Default</string>
<string>default</string>
</tuple>
<tuple>
<string>Alphabetical</string>
<string>CHAR</string>
</tuple>
<tuple>
<string>Numerical</string>
<string>SIGNED</string>
<string>float</string>
</tuple>
</list>
</value>
......@@ -276,19 +272,13 @@
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<tuple>
<string>Products.Formulator.TALESField</string>
<string>TALESMethod</string>
</tuple>
<none/>
</tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [(here.Base_translateString(\'Default Sort\'), \'\'),(here.Base_translateString(\'Alphabetical\'), \'CHAR\'), (here.Base_translateString(\'Numerical\'), \'SIGNED\')]</string> </value>
<value> <string>python: [(here.Base_translateString(k), v) for k,v in field.get_orig_value("sort_columns")]</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -956,23 +956,37 @@ class ListBoxRenderer:
getPageNavigationMode = getPageNavigationTemplate
@lazyMethod
def getSearchColumnIdSet(self):
"""Return the set of the ids of the search columns. Fall back to the catalog schema, if not defined.
def getSearchColumnDict(self):
"""Return search columns
The dict values are useful when getSortColumnDict falls back on this value.
Fall back to the catalog schema, if not defined.
"""
search_columns = self.field.get_value('search_columns')
if search_columns:
return {c[0] for c in search_columns}
return dict(search_columns)
isValidColumn = self.getCatalogTool().getSQLCatalog().isValidColumn
return {id for id, title in self.getAllColumnList() if isValidColumn(id)}
return {id: '' for id, _ in self.getAllColumnList() if isValidColumn(id)}
@lazyMethod
def getSortColumnIdSet(self):
"""Return the set of the ids of the sort columns. Fall back to search column ids, if not defined.
def getSortColumnDict(self):
"""Return sort columns with their cast types as dict values
Cast types are prefixed by ':' for convenience.
Fall back to search columns, if not defined.
"""
sort_columns = self.field.get_value('sort_columns')
if sort_columns:
return {c[0] for c in sort_columns}
return self.getSearchColumnIdSet()
sort_dict = {}
for c, cast in (self.field.get_value('sort_columns') or
self.getSearchColumnDict().iteritems()):
if cast == 'float':
sort_dict[c] = ':' + cast
else:
if cast:
warn('Each line of the "Sortable Columns" field property must be'
' in the form "<column_id> | <cast_type>", where <cast_type>'
" is one of ('', 'float').", DeprecationWarning)
sort_dict[c] = ''
return sort_dict
@lazyMethod
def getEditableColumnIdSet(self):
......@@ -1034,8 +1048,8 @@ class ListBoxRenderer:
selection.edit(default_sort_on = self.getDefaultSortColumnList())
# Filter out non-sortable items.
sort_column_id_set = self.getSortColumnIdSet()
sort_list = [c for c in selection.sort_on if c[0] in sort_column_id_set]
sort_column_dict = self.getSortColumnDict()
sort_list = [c for c in selection.sort_on if c[0] in sort_column_dict]
if len(selection.sort_on) != len(sort_list):
selection.sort_on = sort_list
......@@ -1557,17 +1571,18 @@ class ListBoxRenderer:
set to None, otherwise to a string.
"""
sort_list = self.getSelectionTool().getSelectionSortOrder(self.getSelectionName())
sort_dict = {}
for sort_item in sort_list:
sort_dict[sort_item[0]] = sort_item[1] # sort_item can be couple or a triplet
sort_column_id_set = self.getSortColumnIdSet()
# sort_item can be couple or a triplet
sort_dict = {sort_item[0]: sort_item[1] for sort_item in sort_list}
sort_column_dict = self.getSortColumnDict()
value_list = []
for c in self.getSelectedColumnList():
if c[0] in sort_column_id_set:
value_list.append((c[0], c[1], sort_dict.get(c[0])))
else:
column_id = c[0]
as_type = sort_column_dict.get(column_id)
if as_type is None:
value_list.append((None, c[1], None))
else:
value_list.append((column_id + as_type, c[1], sort_dict.get(column_id)))
return value_list
......@@ -1576,7 +1591,7 @@ class ListBoxRenderer:
If a column is not searchable, the alias is set to None, otherwise to a string. If a search field is not present,
it is set to None.
"""
search_column_id_set = self.getSearchColumnIdSet()
search_column_id_set = self.getSearchColumnDict()
if param_dict is None:
param_dict = self.getParamDict()
......@@ -2575,8 +2590,8 @@ class ListBoxHTMLRenderer(ListBoxRenderer):
for original_listbox_argument in listbox_arguments_list:
listbox_argument = original_listbox_argument.replace('%s_' %field_id, '', 1)
listbox_argument_value = form_dict.get(original_listbox_argument, None)
if listbox_argument in list(self.getSearchColumnIdSet()) and \
listbox_argument_value not in (None,):
if listbox_argument in self.getSearchColumnDict() and \
listbox_argument_value is not None:
update_selection = True
listbox_kw[listbox_argument] = listbox_argument_value
if update_selection:
......
......@@ -553,17 +553,26 @@ class SelectionTool( BaseTool, SimpleItem ):
listbox_id, sort_on = form["setSelectionQuickSortOrder"].split(".", 1)
# Sort order can be specified in sort_on.
forced_sort_order = None
if sort_on is not None:
if sort_on.endswith(':asc'):
forced_sort_order = 'ascending'
sort_on = sort_on[:-4]
elif sort_on.endswith(':desc'):
forced_sort_order = 'descending'
sort_on = sort_on[:-5]
elif sort_on.endswith(':none'):
forced_sort_order = 'none'
sort_on = sort_on[:-5]
if sort_on.endswith(':asc'):
order = 'ascending'
sort_on = sort_on[:-4]
elif sort_on.endswith(':desc'):
order = 'descending'
sort_on = sort_on[:-5]
elif sort_on.endswith(':none'):
order = 'none'
sort_on = sort_on[:-5]
else:
order = None
# ... as well as cast type
i = sort_on.find(':')
if i < 0:
as_type = None
else:
as_type = sort_on[i+1:]
if as_type != 'float':
return
sort_on = sort_on[:i]
if REQUEST is not None:
if listbox_id is not None:
......@@ -574,33 +583,23 @@ class SelectionTool( BaseTool, SimpleItem ):
selection = self.getSelectionFor(selection_name, REQUEST=REQUEST)
if selection is not None:
if forced_sort_order is not None:
if forced_sort_order == 'none':
temporary_new_sort_on = []
else:
temporary_new_sort_on = [(sort_on, forced_sort_order)]
if order is not None:
# Allow user to sort by multiple columns
new_sort_on = [s
for s in self.getSelectionSortOrder(selection_name)
if s[0]!=sort_on]
new_sort_on.extend(temporary_new_sort_on)
new_sort_on = [s for s in selection.sort_on if s[0] != sort_on]
if order != 'none':
new_sort_on.append((sort_on, order, as_type) if as_type else
(sort_on, order))
else:
current_sort_on = self.getSelectionSortOrder(selection_name)
# We must first switch from asc to desc and vice-versa if sort_order exists
# in selection
n = 0
for current in current_sort_on:
order = 'ascending'
for current in selection.sort_on:
if current[0] == sort_on:
n = 1
if current[1] == 'ascending':
new_sort_on = [(sort_on, 'descending')]
break
else:
new_sort_on = [(sort_on,'ascending')]
break
# And if no one exists, we just set sort
if n == 0:
new_sort_on = [(sort_on, 'ascending')]
if current[1] == order:
order = 'descending'
break
new_sort_on = ((sort_on, order, as_type) if as_type else
(sort_on, order),)
selection.edit(sort_on=new_sort_on)
if REQUEST is not None:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment