diff --git a/bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py b/bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
index 86f2b2b38aad7e3f1779e42b5c64ba14667d981b..433c7a63f4c3d3f9e1c3a1469e7e04839c7f98d3 100644
--- a/bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
+++ b/bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
@@ -78,6 +78,43 @@ def byteify(string):
   else:
     return string
 
+
+def ensureSerializable(obj):
+  """Ensure obj and all sub-objects are JSON serializable."""
+  if isinstance(obj, dict):
+    for key in obj:
+      obj[key] = ensureSerializable(obj[key])
+  # throw away date's type information and later reconstruct as Zope's DateTime
+  if isinstance(obj, DateTime):
+    return obj.ISO()
+  if isinstance(obj, (datetime.datetime, datetime.date, datetime.time)):
+    return obj.isoformat()
+  # let us believe that iterables don't contain other unserializable objects
+  return obj
+
+
+datetime_iso_re = re.compile(r'^\d{4}-\d{2}-\d{2} |T\d{2}:\d{2}:\d{2}.*$')
+time_iso_re = re.compile(r'^(\d{2}):(\d{2}):(\d{2}).*$')
+def ensureDeserialized(obj):
+  """Deserialize classes serialized by our own `ensureSerializable`.
+
+  Method `biteify` must not be called on the result because it would revert out
+  deserialization by calling __str__ on constructed classes.
+  """
+  if isinstance(obj, dict):
+    for key in obj:
+      obj[key] = ensureDeserialized(obj[key])
+  # seems that default __str__ method is good enough
+  if isinstance(obj, str):
+    # Zope's DateTime must be good enough for everyone
+    if datetime_iso_re.match(obj):
+      return DateTime(obj)
+    if time_iso_re.match(obj):
+      match_obj = time_iso_re.match(obj)
+      return datetime.time(*tuple(map(int, match_obj.groups())))
+  return obj
+
+
 def getProtectedProperty(document, select):
   """getProtectedProperty is a security-aware substitution for builtin `getattr`
 
@@ -324,7 +361,7 @@ def getRealRelativeUrl(document):
 
 def getFormRelativeUrl(form):
   return portal.portal_catalog(
-    portal_type="ERP5 Form",
+    portal_type=("ERP5 Form", "ERP5 Report"),
     uid=form.getUid(),
     id=form.getId(),
     limit=1,
@@ -359,6 +396,10 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
   if key is None:
     key = field.generate_field_key(key_prefix=key_prefix)
 
+  if meta_type == "ProxyField":
+    # resolve the base meta_type
+    meta_type = field.getRecursiveTemplateField().meta_type
+
   result = {
     "type": meta_type,
     "title": Base_translateString(field.get_value("title")),
@@ -376,12 +417,7 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
       "default": getFieldDefault(form, field, key, value),
     })
 
-  if meta_type == "ProxyField":
-    return renderField(traversed_document, field, form, value,
-                       meta_type=field.getRecursiveTemplateField().meta_type,
-                       key=key, key_prefix=key_prefix,
-                       selection_params=selection_params)
-
+  # start the actual "switch" on field's meta_type here
   if meta_type in ("ListField", "RadioField", "ParallelListField", "MultiListField"):
     result.update({
       # XXX Message can not be converted to json as is
@@ -427,6 +463,7 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
                              if v))
       if parameters:
         result["default"] = '%s?%s' % (result["default"], parameters)
+
     return result
 
   if meta_type == "DateTimeField":
@@ -474,7 +511,7 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
       except Unauthorized:
         jump_reference_list = []
         result.update({
-          "editable": False 
+          "editable": False
         })
     query = url_template_dict["jio_search_template"] % {
       "query": make_query({"query": sql_catalog.buildQuery(
@@ -528,7 +565,6 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
         if rel_cache[key] is not MARKER:
           REQUEST.set(key, rel_cache[key])
 
-
     result.update({
       "url": relative_url,
       "translated_portal_types": translated_portal_type,
@@ -569,12 +605,21 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
     return result
 
   if meta_type == "ListBox":
-    """Display list of objects with optional search/sort capabilities on columns from catalog."""
+    """Display list of objects with optional search/sort capabilities on columns from catalog.
+
+    We might be inside a ReportBox which is inside a parent form BUT we still have access to
+    the original REQUEST with sent POST values from the parent form. We can save those
+    values into our query method and reconstruct them meanwhile calling asynchronous jio.allDocs.
+    """
     _translate = Base_translateString
 
-    column_list = [(name, _translate(title)) for name, title in field.get_value("columns")]
+    # column definition in ListBox own value 'columns' is superseded by dynamic
+    # column definition from Selection for specific Report ListBoxes; the same for editable_columns
+    column_list = [(name, _translate(title)) for name, title in (selection_params.get('selection_columns', [])
+                                                                 or field.get_value("columns"))]
+    editable_column_list = [(name, _translate(title)) for name, title in (selection_params.get('editable_columns', [])
+                                                                          or field.get_value("editable_columns"))]
     all_column_list = [(name, _translate(title)) for name, title in field.get_value("all_columns")]
-    editable_column_list = [(name, _translate(title)) for name, title in field.get_value("editable_columns")]
     catalog_column_list = [(name, title)
                            for name, title in OrderedDict(column_list + all_column_list).items()
                            if sql_catalog.isValidColumn(name)]
@@ -586,25 +631,28 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
 
     # try to get specified sortable columns and fail back to searchable fields
     sort_column_list = [(name, _translate(title))
-                        for name, title in field.get_value("sort_columns")
+                        for name, title in (selection_params.get('selection_sort_order', [])
+                                            or field.get_value("sort_columns"))
                         if sql_catalog.isValidColumn(name)] or search_column_list
+    # portal_type list can be overriden by selection too
+    # since it can be intentionally empty we don't override with non-empty field value
+    portal_type_list = selection_params.get("portal_type", field.get_value('portal_types'))
 
     # requirement: get only sortable/searchable columns which are already displayed in listbox
     # see https://lab.nexedi.com/nexedi/erp5/blob/HEAD/product/ERP5Form/ListBox.py#L1004
     # implemented in javascript in the end
     # see https://lab.nexedi.com/nexedi/erp5/blob/master/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_js.js#L163
-
-    portal_types = field.get_value('portal_types')
-    default_params = dict(field.get_value('default_params'))
+    default_params = dict(field.get_value('default_params'))  # default_params is a list of tuples
     default_params['ignore_unknown_columns'] = True
-    if selection_params is not None:
-      default_params.update(selection_params)
-    # How to implement pagination?
-    # default_params.update(REQUEST.form)
-    lines = field.get_value('lines')
-    list_method_query_dict = dict(
-      portal_type=[x[1] for x in portal_types], **default_params
-    )
+    # we abandoned Selections in RJS thus we mix selection query parameters into
+    # listbox's default parameters
+    default_params.update(selection_params)
+
+    # ListBoxes in report view has portal_type defined already in default_params
+    # in that case we prefer non_empty version
+    list_method_query_dict = default_params.copy()
+    if not list_method_query_dict.get("portal_type", []):
+      list_method_query_dict["portal_type"] = [x for x, _ in portal_type_list]
     list_method_custom = None
 
     # Search for non-editable documents - all reports goes here
@@ -646,8 +694,11 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
         "relative_url": traversed_document.getRelativeUrl().replace("/", "%2F"),
         "form_relative_url": "%s/%s" % (getFormRelativeUrl(form), field.id),
         "list_method": list_method_name,
-        "default_param_json": urlsafe_b64encode(json.dumps(list_method_query_dict))
+        "default_param_json": urlsafe_b64encode(
+          json.dumps(ensureSerializable(list_method_query_dict)))
       }
+      # once we imprint `default_params` into query string of 'list method' we
+      # don't want them to propagate to the query as well
       list_method_query_dict = {}
     """
     # We commented out this part because of backward compatibility
@@ -663,7 +714,7 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
         "script_id": script.id,
         "relative_url": traversed_document.getRelativeUrl().replace("/", "%2F"),
         "list_method": list_method_name,
-        "default_param_json": urlsafe_b64encode(json.dumps(list_method_query_dict))
+        "default_param_json": urlsafe_b64encode(json.dumps(ensureSerializable(list_method_query_dict)))
       }
       list_method_query_dict = {}
     """
@@ -696,9 +747,9 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
       "sort_column_list": sort_column_list,
       "editable_column_list": editable_column_list,
       "show_anchor": field.get_value("anchor"),
-      "portal_type": portal_types,
-      "lines": lines,
-      "default_params": default_params,
+      "portal_type": portal_type_list,
+      "lines": field.get_value('lines'),
+      "default_params": ensureSerializable(default_params),
       "list_method": list_method_name,
       "show_stat": field.get_value('stat_method') != "" or len(field.get_value('stat_columns')) > 0,
       "show_count": field.get_value('count_method') != "",
@@ -848,26 +899,84 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
   }
 
   if (form.pt == 'report_view'):
+    # reports are expected to return list of ReportSection which is a wrapper
+    # around a form - thus we will need to render those forms
     report_item_list = []
     report_result_list = []
     for field in form.get_fields():
       if field.getRecursiveTemplateField().meta_type == 'ReportBox':
+        # ReportBox.render returns a list of ReportSection classes which are
+        # just containers for FormId(s) usually containing one ListBox
+        # and its search/query parameters hidden in `selection_params`
+        # `path` contains relative_url of intended CONTEXT for underlaying ListBox
         report_item_list.extend(field.render())
-    j = 0
-    for report_item in report_item_list:
-      report_context = report_item.getObject(portal)
-      report_prefix = 'x%s' % j
-      j += 1
+    # ERP5 Report document differs from a ERP5 Form in only one thing: it has
+    # `report_method` attached to it - thus we call it right here
+    if hasattr(form, 'report_method') and getattr(form, 'report_method', ""):
+      report_method_name = getattr(form, 'report_method')
+      report_method = getattr(traversed_document, report_method_name)
+      report_item_list.extend(report_method())
+
+    for report_index, report_item in enumerate(report_item_list):
+      report_context = report_item.getObject(traversed_document)
+      report_prefix = 'x%s' % report_index
       report_title = report_item.getTitle()
       # report_class = "report_title_level_%s" % report_item.getLevel()
       report_form = report_item.getFormId()
       report_result = {'_links': {}}
-      renderForm(traversed_document, getattr(report_context, report_item.getFormId()),
-                 report_result, key_prefix=report_prefix,
-                 selection_params=report_item.selection_params)
+      # some reports save a lot of unserializable data (datetime.datetime) and
+      # key "portal_type" (don't confuse with "portal_types" in ListBox) into
+      # report_item.selection_params thus we need to take that into account in
+      # ListBox field
+      #
+      # Selection Params are parameters for embedded ListBox's List Method
+      # and it must be passed in `default_json_param` field (might contain
+      # unserializable data types thus we need to take care of that
+      # In order not to lose information we put all ReportSection attributes
+      # inside the report selection params
+      report_form_params = report_item.selection_params.copy() \
+                           if report_item.selection_params is not None \
+                           else {}
+
+      if report_item.selection_name:
+        selection_name = report_prefix + "_" + report_item.selection_name
+        report_form_params.update(selection_name=selection_name)
+        # this should load selections with correct values - since it is modifying
+        # global state in the backend we have nothing more to do here
+        # I could not find where the code stores params in selection with render
+        # prefix - maybe it in some `render` method where it should not be
+        # Of course it is ugly, terrible and should be removed!
+        selection_tool = context.getPortalObject().portal_selections
+        selection_tool.getSelectionFor(selection_name, REQUEST)
+        selection_tool.setSelectionParamsFor(selection_name, report_form_params)
+        selection_tool.setSelectionColumns(selection_name, report_item.selection_columns)
+
+      if report_item.selection_columns:
+        report_form_params.update(selection_columns=report_item.selection_columns)
+      if report_item.selection_sort_order:
+        report_form_params.update(selection_sort_order=report_item.selection_sort_order)
+
+      # Report section is just a wrapper around form thus we render it right
+      # we keep traversed_document because its Portal Type Class should be
+      # addressable by the user = have actions (object_view) attached to it
+      # BUT! when Report Section defines `path` that is the new context for
+      # form rendering and subsequent searches...
+      renderForm(traversed_document if not report_item.path else report_context,
+                 getattr(report_context, report_item.getFormId()),
+                 report_result,
+                 key_prefix=report_prefix,
+                 selection_params=report_form_params)  # used to be only report_item.selection_params
+      # Report Title is important since there are more section on report page
+      # but often they render the same form with different data so we need to
+      # distinguish by the title at least.
+      report_result['title'] = report_title
       report_result_list.append(report_result)
-
     response_dict['report_section_list'] = report_result_list
+  # end-if report_section
+
+  for key, value in previous_request_other.items():
+    if value is not None:
+      REQUEST.set(key, value)
 
 # XXX form action update, etc
 def renderRawField(field):
@@ -910,6 +1019,7 @@ def renderRawField(field):
 
 
 def renderFormDefinition(form, response_dict):
+  """Form "definition" is configurable in Zope admin: Form -> Order."""
   group_list = []
   for group in form.Form_getGroupTitleAndId():
 
@@ -1028,19 +1138,23 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
     action_dict = {}
   #   result_dict['_relative_url'] = traversed_document.getRelativeUrl()
     result_dict['title'] = traversed_document.getTitle()
-  
+
     # Add a link to the portal type if possible
     if not is_portal:
-      result_dict['_links']['type'] = {
-        "href": default_document_uri_template % {
-          "root_url": site_root.absolute_url(),
-          "relative_url": portal.portal_types[traversed_document.getPortalType()]\
-                            .getRelativeUrl(), 
-          "script_id": script.id
-        },
-        "name": Base_translateString(traversed_document.getPortalType())
-      }
-      
+      # traversed_document should always have its Portal Type in ERP5 Portal Types
+      # thus attached actions to it so it is viewable
+      document_type_name = traversed_document.getPortalType()
+      document_type = getattr(portal.portal_types, document_type_name, None)
+      if document_type is not None:
+        result_dict['_links']['type'] = {
+          "href": default_document_uri_template % {
+            "root_url": site_root.absolute_url(),
+            "relative_url": document_type.getRelativeUrl(),
+            "script_id": script.id
+          },
+          "name": Base_translateString(traversed_document.getPortalType())
+        }
+
     # Return info about container
     if not is_portal:
       container = traversed_document.getParentValue()
@@ -1060,6 +1174,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
       portal.portal_actions.listFilteredActionsFor(traversed_document))
   
     embedded_url = None
+
     # XXX See ERP5Type.getDefaultViewFor
     for erp5_action_key in erp5_action_dict.keys():
       erp5_action_list = []
@@ -1151,7 +1266,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
       # renderer_form = traversed_document.restrictedTraverse(form_id, None)
       # XXX Proxy field are not correctly handled in traversed_document of web site
       renderer_form = getattr(traversed_document, form_id)
-  #     traversed_document.log(form_id)
       if (renderer_form is not None):
         embedded_dict = {
           '_links': {
@@ -1161,19 +1275,31 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
           }
         }
         # Put all query parameters (?reset:int=1&workflow_action=start_action) in request to mimic usual form display
+        query_param_dict = {}
         query_split = embedded_url.split('?', 1)
         if len(query_split) == 2:
           for query_parameter in query_split[1].split("&"):
-            query_key, query_value = query_parameter.split("=")
-            REQUEST.set(query_key, query_value)
-  
+            query_key, query_value = query_parameter.split('=')
+            # often + is used instead of %20 so we replace for space here
+            query_param_dict[query_key] = query_value.replace("+", " ")
+
+        # set URL params into REQUEST (just like it was sent by form)
+        for query_key, query_value in query_param_dict.items():
+          REQUEST.set(query_key, query_value)
+
+        # unfortunatelly some people use Scripts as targets for Workflow
+        # transactions - thus we need to check and mitigate
+        if "Script" in renderer_form.meta_type:
+          # we suppose that the script takes only what is given in the URL params
+          return renderer_form(**query_param_dict)
+
         renderForm(traversed_document, renderer_form, embedded_dict)
         result_dict['_embedded'] = {
           '_view': embedded_dict
           # embedded_action_key: embedded_dict
         }
   #       result_dict['_links']["_view"] = {"href": embedded_url}
-  
+
         # Include properties in document JSON
         # XXX Extract from renderer form?
         """
@@ -1255,7 +1381,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
   
     else:
       traversed_document_portal_type = traversed_document.getPortalType()
-      if traversed_document_portal_type == "ERP5 Form":
+      if traversed_document_portal_type in ("ERP5 Form", "ERP5 Report"):
         renderFormDefinition(traversed_document, result_dict)
         response.setHeader("Cache-Control", "private, max-age=1800")
         response.setHeader("Vary", "Cookie,Authorization,Accept-Encoding")
@@ -1278,19 +1404,18 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
               "template": True
             }
           }
-  
+
     # Define document action
     if action_dict:
       result_dict['_actions'] = action_dict
-  
-  
+
   elif mode == 'search':
     #################################################
     # Portal catalog search
     #
     # Possible call arguments example:
     #  form_relative_url: portal_skins/erp5_web/WebSite_view/listbox
-    #  list_method: objectValues                      (Script providing listing)
+    #  list_method: "objectValues"                    (Script providing items)
     #  default_param_json: <base64 encoded JSON>      (Additional search params)
     #  query: <str>                                   (term for fulltext search)
     #  select_list: ['int_index', 'id', 'title', ...] (column names to select)
@@ -1337,9 +1462,13 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
         "sort_on": ()  # default is an empty tuple
       }
       if default_param_json is not None:
-        catalog_kw.update(byteify(json.loads(urlsafe_b64decode(default_param_json))))
+        catalog_kw.update(
+          ensureDeserialized(
+            byteify(
+              json.loads(urlsafe_b64decode(default_param_json)))))
       if query:
         catalog_kw["full_text"] = query
+
       if sort_on is not None:
         def parseSortOn(raw_string):
           """Turn JSON serialized array into a tuple (col_name, order)."""
@@ -1452,6 +1581,10 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
       contents_uid, contents_relative_url, property_getter = \
         getUidAndAccessorForAnything(search_result, result_index, traversed_document)
 
+      # Check if this object provides a specific URL method.
+      # if getattr(search_result, 'getListItemUrl', None) is not None:
+      #  search_result.getListItemUrl(contents_uid, result_index, selection_name)
+
       # _links.self.href is mandatory for JIO so it can create reference to the
       # (listbox) item alone
       contents_item['_links'] = {
@@ -1503,7 +1636,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
       # endfor select
       REQUEST.other.pop('cell', None)
       contents_list.append(contents_item)
-    result_dict['_embedded']['contents'] = contents_list
+    result_dict['_embedded']['contents'] = ensureSerializable(contents_list)
 
     # Compute statistics if the search issuer was ListBox
     # or in future if the stats (SUM) are required by JIO call
@@ -1562,7 +1695,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
               traversed_document, editable_field_dict[key], listbox_form, value, key=editable_field_dict[key].id + '__sum')
 
       if len(contents_stat_list) > 0:
-        result_dict['_embedded']['sum'] = contents_stat_list
+        result_dict['_embedded']['sum'] = ensureSerializable(contents_stat_list)
 
     # We should cleanup the selection if it exists in catalog params BUT
     # we cannot because it requires escalated Permission.'modifyPortal' so
diff --git a/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py b/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py
index c208b4a89ec85f56c31e53294795477277ada374..93a89c365432efae65c8d8465bada53ab75a11e2 100644
--- a/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py
+++ b/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py
@@ -9,8 +9,11 @@ from functools import wraps
 from ZPublisher.HTTPRequest import HTTPRequest
 from ZPublisher.HTTPResponse import HTTPResponse
 
+import base64
+import DateTime
 import StringIO
 import json
+import re
 import urllib
 
 def changeSkin(skin_name):
@@ -639,6 +642,42 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
     self.assertEqual(result_dict['_embedded']['_view']['_actions']['put']['method'], 'POST')
 
 
+  @simulate('Base_getRequestUrl', '*args, **kwargs',
+      'return "http://example.org/bar"')
+  @simulate('Base_getRequestHeader', '*args, **kwargs',
+            'return "application/hal+json"')
+  @changeSkin('Hal')
+  def test_getHateoasDocument_listbox_vs_relation_inconsistency(self):
+    """Purpose of this test is to point to inconsistencies in search-enabled field rendering.
+
+    ListBox gets its Portal Types in `portal_type` as list of tuples whether
+    Relation Input receives `portal_types` and `translated_portal_types`
+    """
+    document = self._makeDocument()
+    # Drop editable permission
+    document.manage_permission('Modify portal content', [], 0)
+    document.Foo_view.listbox.ListBox_setPropertyList(
+      field_title = 'Foo Lines',
+      field_list_method = 'objectValues',
+      field_portal_types = 'Foo Line | Foo Line',
+    )
+    fake_request = do_fake_request("GET")
+    result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
+      REQUEST=fake_request,
+      mode="traverse",
+      relative_url=document.getRelativeUrl(),
+      view="view")
+    self.assertEquals(fake_request.RESPONSE.status, 200)
+    self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
+      "application/hal+json"
+    )
+    result_dict = json.loads(result)
+    # ListBox rendering of allowed Portal Types
+    self.assertEqual(result_dict['_embedded']['_view']['listbox']['portal_type'], [['Foo Line', 'Foo Line']])
+    # Relation Input rendering of allowed Portal Types
+    self.assertEqual(result_dict['_embedded']['_view']['my_foo_category_title']['portal_types'], ['Category'])
+    self.assertEqual(result_dict['_embedded']['_view']['my_foo_category_title']['translated_portal_types'], ['Category'])
+
   @simulate('Base_getRequestUrl', '*args, **kwargs',
       'return "http://example.org/bar"')
   @simulate('Base_getRequestHeader', '*args, **kwargs',
@@ -712,6 +751,71 @@ class TestERP5Document_getHateoas_mode_traverse(ERP5HALJSONStyleSkinsMixin):
     self.assertFalse(result_dict['_embedded']['_view'].has_key('_actions'))
 
 
+  @simulate('Base_getRequestUrl', '*args, **kwargs',
+      'return "http://example.org/bar"')
+  @simulate('Base_getRequestHeader', '*args, **kwargs',
+            'return "application/hal+json"')
+  @changeSkin('Hal')
+  def test_getHateoasDocument_listbox_list_method_params(self):
+    """Ensure that `list_method` of ListBox receives specified parameters."""
+    document = self._makeDocument()
+    document.manage_permission('Modify portal content', [], 0)
+    # pass custom list method which expect input arguments
+    document.Foo_view.listbox.ListBox_setPropertyList(
+      field_title = 'Foo Lines',
+      field_list_method = 'Foo_listWithInputParams',
+      field_portal_types = 'Foo Line | Foo Line',
+      field_columns = 'id|ID\ntitle|Title\nquantity|Quantity\nstart_date|Date\ncatalog.uid|Uid')
+
+    now = DateTime.DateTime()
+    tomorrow = now + 1
+
+    fake_request = do_fake_request("GET", data=(
+      ('start_date', now.ISO()),
+      ('stop_date', tomorrow.ISO()))
+    )
+    # I tried to implement the standard way (see `data` param in do_fake_request)
+    # but for some reason it does not work...so we hack our way around
+    fake_request.set('start_date', now.ISO())
+    fake_request.set('stop_date', tomorrow.ISO())
+    result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
+      REQUEST=fake_request,
+      mode="traverse",
+      relative_url=document.getRelativeUrl(),
+      form=document.restrictedTraverse('portal_skins/erp5_ui_test/Foo_view'),
+      view="view"
+      )
+
+    self.assertEquals(fake_request.RESPONSE.status, 200)
+    self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
+      "application/hal+json"
+    )
+    result_dict = json.loads(result)
+    list_method_template = \
+      result_dict['_embedded']['_view']['listbox']['list_method_template']
+    # default_param_json must not be empty because our custom list method
+    # specifies input parameters - they need to be filled from REQUEST
+    self.assertIn('default_param_json', list_method_template)
+    default_param_json = json.loads(
+      base64.b64decode(
+        re.search(r'default_param_json=([^\{&]+)',
+                  list_method_template).group(1)))
+    self.assertIn("start_date", default_param_json)
+    self.assertEqual(default_param_json["start_date"], now.ISO())
+    self.assertIn("stop_date", default_param_json)
+    self.assertEqual(default_param_json["stop_date"], tomorrow.ISO())
+    # reset listbox properties to defaults
+    document.Foo_view.listbox.ListBox_setPropertyList(
+      field_title = 'Foo Lines',
+      field_list_method = 'objectValues',
+      field_portal_types = 'Foo Line | Foo Line',
+      field_stat_method = 'portal_catalog',
+      field_stat_columns = 'quantity | Foo_statQuantity',
+      field_editable = 1,
+      field_columns = 'id|ID\ntitle|Title\nquantity|Quantity\nstart_date|Date\ncatalog.uid|Uid',
+      field_editable_columns = 'id|ID\ntitle|Title\nquantity|quantity\nstart_date|Date',
+      field_search_columns = 'id|ID\ntitle|Title\nquantity|Quantity\nstart_date|Date',)
+
   @simulate('Base_getRequestUrl', '*args, **kwargs',
       'return "http://example.org/bar"')
   @simulate('Base_getRequestHeader', '*args, **kwargs',
@@ -1208,7 +1312,6 @@ class TestERP5Document_getHateoas_mode_bulk(ERP5HALJSONStyleSkinsMixin):
     self.assertEquals(fake_request.RESPONSE.status, 405)
     self.assertEquals(result, "")
 
-
   @simulate('Base_getRequestUrl', '*args, **kwargs',
       'return "http://example.org/bar"')
   @simulate('Base_getRequestHeader', '*args, **kwargs',
@@ -1347,6 +1450,7 @@ class TestERP5Document_getHateoas_mode_worklist(ERP5HALJSONStyleSkinsMixin):
 
     self.assertEqual(result_dict['_debug'], "worklist")
 
+
 class TestERP5Document_getHateoas_translation(ERP5HALJSONStyleSkinsMixin):
   code_string = "\
 from Products.CMFCore.utils import getToolByName\n\
@@ -1428,8 +1532,7 @@ return msg"
   code_string)
   @createIndexedDocument()
   @changeSkin('Hal')
-  def test_getHateoasWorklist_default_view_translation(self, **kw):
-    # self._makeDocument()
+  def test_getHateoasWorklist_default_view_translation(self, document):
     fake_request = do_fake_request("GET")
     result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
       REQUEST=fake_request,
@@ -1476,7 +1579,7 @@ class TestERP5Action_getHateoas(ERP5HALJSONStyleSkinsMixin):
   @changeSkin('Hal')
   def test_getHateoasDialog_dialog_failure(self, document):
     """Test an dialog on Foo object with empty required for a failure.
-    
+
     Expected behaviour is response Http 400 with field errors.
     """
     fake_request = do_fake_request("POST")
diff --git a/bt5/erp5_ui_test/ActionTemplateItem/portal_types/Foo/view_hidden_positive_only_quantity.xml b/bt5/erp5_ui_test/ActionTemplateItem/portal_types/Foo/view_hidden_positive_only_quantity.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b217ce7577b29b4609e4bf50504bc9874cd59c84
--- /dev/null
+++ b/bt5/erp5_ui_test/ActionTemplateItem/portal_types/Foo/view_hidden_positive_only_quantity.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/object_view</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>category</string> </key>
+            <value> <string>object_view</string> </value>
+        </item>
+        <item>
+            <key> <string>condition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Form with hidden quantity field with external validator asserting positiveness of the value. Used to test behaviour of errors on hidden fields.</string> </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>view_hidden_positive_only_quantity</string> </value>
+        </item>
+        <item>
+            <key> <string>permissions</string> </key>
+            <value>
+              <tuple>
+                <string>View</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Action Information</string> </value>
+        </item>
+        <item>
+            <key> <string>priority</string> </key>
+            <value> <float>10.0</float> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>View Hidden Positive-Only Quantity</string> </value>
+        </item>
+        <item>
+            <key> <string>visible</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="Expression" module="Products.CMFCore.Expression"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>text</string> </key>
+            <value> <string>string: ${object_url}/Foo_viewHiddenErrorneousField</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_listWithInputParams.py b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_listWithInputParams.py
new file mode 100644
index 0000000000000000000000000000000000000000..c26098bd1cda09003781622dde126ea68df9d29b
--- /dev/null
+++ b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_listWithInputParams.py
@@ -0,0 +1,11 @@
+"""Foo_listWithInputParams is here only to test passing parameters from REQUEST via introspection in RenderJS UI.
+
+We expect DateTime parameters thus they have to undergo a serialization/deserialization process.
+"""
+
+from DateTime import DateTime
+
+assert isinstance(start_date, DateTime), "start_date is instance of {!s} instead of DateTime!".format(type(start_date))
+assert isinstance(stop_date, DateTime), "stop_date is instance of {!s} instead of DateTime!".format(type(stop_date))
+
+return context.listFolder(portal_type='Foo Line')
diff --git a/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_listWithInputParams.xml b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_listWithInputParams.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d00f94c94c8e3bdcd8b77044913240471e082348
--- /dev/null
+++ b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_listWithInputParams.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Python Script" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>start_date, stop_date=None, **kwargs</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>Foo_listWithInputParams</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Python Script</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField.xml b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField.xml
new file mode 100644
index 0000000000000000000000000000000000000000..38b65a388e0dc85e5a3dfee0356350d39833176d
--- /dev/null
+++ b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ERP5 Form" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary/>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action</string> </key>
+            <value> <string>Base_edit</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Display some integers field for selenium tests</string> </value>
+        </item>
+        <item>
+            <key> <string>edit_order</string> </key>
+            <value>
+              <list/>
+            </value>
+        </item>
+        <item>
+            <key> <string>encoding</string> </key>
+            <value> <string>UTF-8</string> </value>
+        </item>
+        <item>
+            <key> <string>enctype</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>group_list</string> </key>
+            <value>
+              <list>
+                <string>left</string>
+                <string>right</string>
+                <string>center</string>
+                <string>bottom</string>
+                <string>hidden</string>
+              </list>
+            </value>
+        </item>
+        <item>
+            <key> <string>groups</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>bottom</string> </key>
+                    <value>
+                      <list/>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>center</string> </key>
+                    <value>
+                      <list/>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>hidden</string> </key>
+                    <value>
+                      <list/>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>left</string> </key>
+                    <value>
+                      <list>
+                        <string>my_quantity</string>
+                        <string>read_only_quantity</string>
+                      </list>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>right</string> </key>
+                    <value>
+                      <list/>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>Foo_viewHiddenErrorneousField</string> </value>
+        </item>
+        <item>
+            <key> <string>method</string> </key>
+            <value> <string>POST</string> </value>
+        </item>
+        <item>
+            <key> <string>name</string> </key>
+            <value> <string>Foo_view</string> </value>
+        </item>
+        <item>
+            <key> <string>pt</string> </key>
+            <value> <string>form_view</string> </value>
+        </item>
+        <item>
+            <key> <string>row_length</string> </key>
+            <value> <int>4</int> </value>
+        </item>
+        <item>
+            <key> <string>stored_encoding</string> </key>
+            <value> <string>UTF-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Foo</string> </value>
+        </item>
+        <item>
+            <key> <string>unicode_mode</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>update_action</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField/my_quantity.xml b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField/my_quantity.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ff762c7317833b1074d7f68baa51aba9a59581ba
--- /dev/null
+++ b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField/my_quantity.xml
@@ -0,0 +1,271 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="IntegerField" module="Products.Formulator.StandardFields"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>my_quantity</string> </value>
+        </item>
+        <item>
+            <key> <string>message_values</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>external_validator_failed</string> </key>
+                    <value> <string>The input failed the external validator.</string> </value>
+                </item>
+                <item>
+                    <key> <string>integer_out_of_range</string> </key>
+                    <value> <string>The integer you entered was out of range.</string> </value>
+                </item>
+                <item>
+                    <key> <string>not_integer</string> </key>
+                    <value> <string>You did not enter an integer.</string> </value>
+                </item>
+                <item>
+                    <key> <string>required_not_found</string> </key>
+                    <value> <string>Input is required but no input given.</string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>overrides</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>alternate_name</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>css_class</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>default</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>description</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_maxwidth</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_width</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>editable</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>enabled</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>end</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>external_validator</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>extra</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>hidden</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>required</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>start</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>title</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>whitespace_preserve</string> </key>
+                    <value> <string></string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>tales</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>alternate_name</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>css_class</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>default</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>description</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_maxwidth</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_width</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>editable</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>enabled</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>end</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>external_validator</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>extra</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>hidden</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>required</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>start</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>title</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>whitespace_preserve</string> </key>
+                    <value> <string></string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>values</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>alternate_name</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>css_class</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>default</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>description</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_maxwidth</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_width</string> </key>
+                    <value> <int>20</int> </value>
+                </item>
+                <item>
+                    <key> <string>editable</string> </key>
+                    <value> <int>1</int> </value>
+                </item>
+                <item>
+                    <key> <string>enabled</string> </key>
+                    <value> <int>1</int> </value>
+                </item>
+                <item>
+                    <key> <string>end</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>external_validator</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>extra</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>hidden</string> </key>
+                    <value> <int>1</int> </value>
+                </item>
+                <item>
+                    <key> <string>input_type</string> </key>
+                    <value> <string>text</string> </value>
+                </item>
+                <item>
+                    <key> <string>required</string> </key>
+                    <value> <int>1</int> </value>
+                </item>
+                <item>
+                    <key> <string>start</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>title</string> </key>
+                    <value> <string>Quantity</string> </value>
+                </item>
+                <item>
+                    <key> <string>whitespace_preserve</string> </key>
+                    <value> <int>0</int> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="Method" module="Products.Formulator.MethodField"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>method_name</string> </key>
+            <value> <string>Validator_positiveNumber</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField/read_only_quantity.xml b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField/read_only_quantity.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2b39b4c8abf1b88871ba94038578f9786dee514
--- /dev/null
+++ b/bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/Foo_viewHiddenErrorneousField/read_only_quantity.xml
@@ -0,0 +1,277 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="IntegerField" module="Products.Formulator.StandardFields"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>read_only_quantity</string> </value>
+        </item>
+        <item>
+            <key> <string>message_values</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>external_validator_failed</string> </key>
+                    <value> <string>The input failed the external validator.</string> </value>
+                </item>
+                <item>
+                    <key> <string>integer_out_of_range</string> </key>
+                    <value> <string>The integer you entered was out of range.</string> </value>
+                </item>
+                <item>
+                    <key> <string>not_integer</string> </key>
+                    <value> <string>You did not enter an integer.</string> </value>
+                </item>
+                <item>
+                    <key> <string>required_not_found</string> </key>
+                    <value> <string>Input is required but no input given.</string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>overrides</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>alternate_name</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>css_class</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>default</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>description</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_maxwidth</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_width</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>editable</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>enabled</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>end</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>external_validator</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>extra</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>hidden</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>required</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>start</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>title</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>whitespace_preserve</string> </key>
+                    <value> <string></string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>tales</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>alternate_name</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>css_class</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>default</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>description</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_maxwidth</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_width</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>editable</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>enabled</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>end</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>external_validator</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>extra</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>hidden</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>required</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>start</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>title</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>whitespace_preserve</string> </key>
+                    <value> <string></string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>values</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>alternate_name</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>css_class</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>default</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>description</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_maxwidth</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>display_width</string> </key>
+                    <value> <int>20</int> </value>
+                </item>
+                <item>
+                    <key> <string>editable</string> </key>
+                    <value> <int>0</int> </value>
+                </item>
+                <item>
+                    <key> <string>enabled</string> </key>
+                    <value> <int>1</int> </value>
+                </item>
+                <item>
+                    <key> <string>end</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>external_validator</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>extra</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>hidden</string> </key>
+                    <value> <int>0</int> </value>
+                </item>
+                <item>
+                    <key> <string>input_type</string> </key>
+                    <value> <string>text</string> </value>
+                </item>
+                <item>
+                    <key> <string>required</string> </key>
+                    <value> <int>0</int> </value>
+                </item>
+                <item>
+                    <key> <string>start</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>title</string> </key>
+                    <value> <string>Read-Only Quantity</string> </value>
+                </item>
+                <item>
+                    <key> <string>whitespace_preserve</string> </key>
+                    <value> <int>0</int> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <tuple>
+        <tuple>
+          <string>Products.Formulator.TALESField</string>
+          <string>TALESMethod</string>
+        </tuple>
+        <none/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_text</string> </key>
+            <value> <string>python: here.getQuantity()</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_ui_test/bt/template_action_path_list b/bt5/erp5_ui_test/bt/template_action_path_list
index ab3a5738406368a4fd069d3857eba657b6c263ea..b5da64f9515b3e76ad564ea04f9857bd3f65b95c 100644
--- a/bt5/erp5_ui_test/bt/template_action_path_list
+++ b/bt5/erp5_ui_test/bt/template_action_path_list
@@ -30,6 +30,7 @@ Foo | view_duration_field
 Foo | view_formbox
 Foo | view_formbox_dialog
 Foo | view_formbox_fooline
+Foo | view_hidden_positive_only_quantity
 Foo | view_listbox
 Foo | view_multiple_listbox
 Foo | view_planning
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.js b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.js
index 3439ba5aa9a53cf7a929709f6e4957521fcde367..e3ef5f7501440f5a8d104523cb341ab50ea26308 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.js
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.js
@@ -171,12 +171,29 @@
         form_definition = this.state.form_definition,
         rendered_document = erp5_document._embedded._view,
         group_list = form_definition.group_list,
-        form_gadget = this;
+        form_gadget = this,
+        tmp;
 
       if (modification_dict.hasOwnProperty('hash')) {
         form_gadget.props.gadget_list = [];
       }
-
+      /* Update or remove h3 element based on value of `title` */
+      if (modification_dict.hasOwnProperty('title')) {
+        tmp = this.element.querySelector("h3");
+        if (modification_dict.title) {
+          if (tmp === null) {
+            // create new title element for existing title
+            tmp = document.createElement("h3");
+            this.element.insertBefore(tmp, this.element.firstChild);
+          }
+          tmp.textContent = modification_dict.title;
+        }
+        if (modification_dict.title === null || modification_dict.title === "") {
+          // user tends to remove the title
+          if (tmp !== null) {tmp.remove(); }
+        }
+        tmp = undefined;
+      }
       return new RSVP.Queue()
         .push(function () {
           return RSVP.all(group_list.map(function (group) {
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.xml
index d69449eb580f739bbbc8295fca57736cb739a294..08a8d321921a26d2908b897d70597e2395052934 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.xml
@@ -230,7 +230,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>963.11788.48702.26146</string> </value>
+                <value> <string>964.25533.41108.47530</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -248,7 +248,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1514393621.04</float>
+                        <float>1515496577.67</float>
                         <string>UTC</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_js.js b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_js.js
index ae07bd2cf7865316da8ac546234b4d300c0d417e..666ce8b3091b5f9edb17680188d5baa6eacead2f 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_js.js
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_js.js
@@ -5,6 +5,7 @@
 
   /** Return true if `field` resembles non-empty and non-editable field. */
   function isGoodNonEditableField(field) {
+    if (field === undefined || field === null) {return false; }
     // ListBox and FormBox should always get a chance to render because they
     // can contain editable fields
     if (field.type === "ListBox") {return true; }
@@ -47,6 +48,7 @@
     .declareMethod('render', function (options) {
       var state_dict = {
         jio_key: options.jio_key,
+        title: options.title,
         view: options.view,
         editable: options.editable,
         erp5_document: options.erp5_document,
@@ -80,6 +82,7 @@
           form_options.erp5_document = gadget.state.erp5_document;
           form_options.form_definition = gadget.state.form_definition;
           form_options.view = gadget.state.view;
+          form_options.title = gadget.state.title;
           form_options.jio_key = gadget.state.jio_key;
           form_options.editable = 0; // because for editable=1 there is a special
                                      // page template 'pt_form_editable'. Once it is
@@ -96,7 +99,7 @@
             gadget.getUrlFor({command: 'selection_previous'}),
             gadget.getUrlFor({command: 'selection_next'}),
             gadget.getUrlFor({command: 'change', options: {page: "tab"}}),
-            gadget.state.erp5_document._links.action_object_jio_report ?
+            gadget.state.erp5_document._links.action_object_jio_report || gadget.state.erp5_document._links.action_object_print ?
               gadget.getUrlFor({command: 'change', options: {page: "export"}}) :
               "",
             calculatePageTitle(gadget, gadget.state.erp5_document)
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_js.xml
index 6faaffb918e176c16e67182068ba87a7747769a2..f071236f7e5e6b9011ca014dc05455b4356dfa65 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_js.xml
@@ -230,7 +230,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>964.44232.19748.18107</string> </value>
+                <value> <string>964.45882.29366.36147</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -248,7 +248,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1515406785.95</float>
+                        <float>1515593717.52</float>
                         <string>UTC</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_report_view_js.js b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_report_view_js.js
index 20ebf6c4892f11c62de7529af4ab52addd9e3185..9d574c365f860e32c468e489117527ad07eb281f 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_report_view_js.js
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_report_view_js.js
@@ -33,7 +33,7 @@
         };
         return form_gadget.render({erp5_document: erp5_document,
                                    form_definition: form_definition,
-                                   editable: 0});
+                                   editable: 0, title: report_section.title});
       });
   }
 
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_report_view_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_report_view_js.xml
index 24108d8631828d5fbd784ed6d9060d546c16b902..c6ef7ce655d6e1b044ef8efc1ffabd51ae06189f 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_report_view_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_report_view_js.xml
@@ -230,7 +230,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>961.16421.12334.2201</string> </value>
+                <value> <string>962.56167.53905.31470</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -248,7 +248,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1502116518.17</float>
+                        <float>1508400391.84</float>
                         <string>UTC</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_notification_zuite/testHiddenFieldError.xml b/bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_notification_zuite/testHiddenFieldError.xml
new file mode 100644
index 0000000000000000000000000000000000000000..301f6b3fbd163db60db701f45562e0f4aae23c25
--- /dev/null
+++ b/bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_notification_zuite/testHiddenFieldError.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>expand</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>testHiddenFieldError</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <unicode></unicode> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_notification_zuite/testHiddenFieldError.zpt b/bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_notification_zuite/testHiddenFieldError.zpt
new file mode 100644
index 0000000000000000000000000000000000000000..32685a7e4d5df752d528d241f76311e5fb45c3fb
--- /dev/null
+++ b/bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_notification_zuite/testHiddenFieldError.zpt
@@ -0,0 +1,51 @@
+<html>
+<head><title>Test Invoices Report Skin Allowance</title></head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><th rowspan="1" colspan="4">
+Check that user gets notified if there is an error on a hidden field.
+</th></tr>
+</thead>
+
+<tbody>
+<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
+<tr><td>store</td>
+    <td>${base_url}/web_site_module/renderjs_runner</td>
+    <td>renderjs_url</td></tr>
+
+<tr><td>open</td>
+    <td>${renderjs_url}/#/foo_module/1/?editable=1</td><td></td></tr>
+
+<!-- Originaly the field was required and we tested here an empty value. Problem is that Firefox
+     evaluates numerical rule before required value wheras Chrome does it in the opposite direction -->
+
+<!-- Put negative quantity so the external validator will not pass external test in the next view -->
+<tr><td>waitForElementPresent</td>
+    <td>//input[@name="field_my_quantity"]</td><td></td></tr>
+<tr><td>type</td>
+    <td>//input[@name="field_my_quantity"]</td>
+    <td>-20</td></tr>
+<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
+
+<!-- Let the external validator throw an error - this time we test explicitely
+     for a notification with the error -->
+<tr><td>waitForElementPresent</td>
+    <td>//a[@data-i18n="Views"]</td><td></td></tr>
+<tr><td>click</td>
+    <td>//a[@data-i18n="Views"]</td><td></td></tr>
+<tr><td>waitForElementPresent</td>
+    <td>//a[@data-i18n="View Hidden Positive-Only Quantity"]</td><td></td></tr>
+<tr><td>click</td>
+    <td>//a[@data-i18n="View Hidden Positive-Only Quantity"]</td><td></td></tr>
+<tr><td>waitForElementPresent</td>
+    <td>//button[@data-i18n='Save']</td><td></td></tr>
+<tr><td>click</td>
+    <td>//button[@data-i18n='Save']</td><td></td></tr>
+<tr><td>waitForTextPresent</td>
+    <td>The input failed the external validator.</td><td></td></tr>
+
+</tbody>
+</table>
+</body>
+</html>
\ No newline at end of file