From 38f073f4dc4ba4a81c10cd2b82dbc69f7299643f Mon Sep 17 00:00:00 2001
From: Vincent Pelletier <vincent@nexedi.com>
Date: Thu, 19 Apr 2007 13:37:48 +0000
Subject: [PATCH] Add support for advanced date search in listbox: ">2007",
 "<=2007/01/01" and the like are now possible to input in the search field.
 Add a new optionnal method to Formulator API which returns a dict containing
 details about the way the field value is supposed to be formated (so that a
 valid input can be directly parsed by code).

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@14127 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Form/FormulatorPatch.py | 32 +++++++++++++++++++++++++++++
 product/ERP5Form/ListBox.py         | 22 ++++++++++++++++++--
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/product/ERP5Form/FormulatorPatch.py b/product/ERP5Form/FormulatorPatch.py
index 3a0f4d4dcd..e767ea9f02 100644
--- a/product/ERP5Form/FormulatorPatch.py
+++ b/product/ERP5Form/FormulatorPatch.py
@@ -726,6 +726,18 @@ class PatchedDateTimeWidget(DateTimeWidget):
     """
       Added support for key in every call to render_sub_field
     """
+
+    sql_format_year  = '%Y'
+    sql_format_month = '%m'
+    sql_format_day   = '%d'
+    format_to_sql_format_dict = {'dmy': (sql_format_day  , sql_format_month, sql_format_year),
+                                 'ymd': (sql_format_year , sql_format_month, sql_format_day ),
+                                 'mdy': (sql_format_month, sql_format_day  , sql_format_year),
+                                 'my' : (sql_format_month, sql_format_year ),
+                                 'ym' : (sql_format_year , sql_format_month)
+                                }
+    sql_format_default = format_to_sql_format_dict['ymd']
+
     hide_day = fields.CheckBoxField('hide_day',
                                   title="Hide Day",
                                   description=(
@@ -752,6 +764,26 @@ class PatchedDateTimeWidget(DateTimeWidget):
           input_order = 'my'
       return input_order
 
+    def render_dict(self, field, value):
+      """
+        This is yet another field rendering. It is designed to allow code to
+        understand field's value data by providing its type and format when
+        applicable.
+
+        It returns a dict with 3 keys:
+          type  : Text representation of value's type.
+          format: Type-dependant-formated formating information.
+                  This only describes the field format settings, not the actual
+                  format of provided value.
+          query : Passthrough of given value.
+      """
+      format_dict = self.format_to_sql_format_dict
+      input_order = format_dict.get(self.getInputOrder(field),
+                                    self.sql_format_default)
+      return {'query': value,
+              'format': field.get_value('date_separator').join(input_order),
+              'type': 'date'}
+
     def render(self, field, key, value, REQUEST):
         use_ampm = field.get_value('ampm_time_style')
         # FIXME: backwards compatibility hack:
diff --git a/product/ERP5Form/ListBox.py b/product/ERP5Form/ListBox.py
index c66de63da4..f909b5d0b6 100644
--- a/product/ERP5Form/ListBox.py
+++ b/product/ERP5Form/ListBox.py
@@ -925,6 +925,21 @@ class ListBoxRenderer:
         if k.startswith(search_prefix):
           params[k[len(search_prefix):]] = v
 
+      search_value_list = [x for x in self.getSearchValueList(param_dict=params) if isinstance(x[1], basestring)]
+      listbox_form = self.getForm()
+      listbox_id = self.getId()
+      for search_id, search_value, search_field in search_value_list:
+        if search_field is None:
+          # If the search field could not be found, try to get an "editable" field on current form.
+          editable_field_id = '%s_%s' % (listbox_id, search_id)
+          if listbox_form.has_field(editable_field_id):
+            search_field = listbox_form.get_field(editable_field_id)
+          else:
+            continue
+        render_dict = getattr(search_field.widget, 'render_dict', None)
+        if render_dict is not None:
+          params[search_id] = render_dict(search_field, search_value)
+
       # Set parameters, depending on the list method.
       list_method_name = self.getListMethodName()
       meta_type_list = self.getMetaTypeList()
@@ -1312,18 +1327,21 @@ class ListBoxRenderer:
 
     return value_list
 
-  def getSearchValueList(self):
+  def getSearchValueList(self, param_dict=None):
     """Return a list of values, where each value is a tuple consisting of an alias, a current value and a search field.
     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()
-    param_dict = self.getParamDict()
+    if param_dict is None:
+      param_dict = self.getParamDict()
     value_list = []
     for (sql, title), alias in zip(self.getSelectedColumnList(), self.getColumnAliasList()):
       if sql in search_column_id_set:
         # Get the current value and encode it in unicode.
         param = param_dict.get(alias, param_dict.get(sql, u''))
+        if isinstance(param, dict):
+          param = param.get('query', u'')
         if isinstance(param, str):
           param = unicode(param, self.getEncoding())
 
-- 
2.30.9