Most Powerful Open Source ERP

How To Configure Parallellist Field

How To showing how to split a large Multi ListField into separate parallel fields.
  • Last Update:2016-02-11
  • Version:001
  • Language:en

The ParallelListField is a ERP5 widget used to split a huge MultiListField into multiple ListField, MultiListField.

Table of Contents

Add a new ParallelListField

Usually, such widget is added in ERP5 Form. You have to select one ERP5 Form in the Zope Management Interface (ZMI). Then you have on the top right a list of widget that you might add. Please, select a ParallelListField.

Configuration

The configuration is almost the same as a MultiListField, except that you can also define a hash script.

Hash script

In this field, you have to enter a python script name, which we have to define (example: DeliveryLine_hashVariationCategoryItemList).

Items

You need to get a list of items (i.e. a list of pairs of a title and a path). Usually, you can simply use a TALES Expression like this one : python: here.getVariationRangeCategoryItemList().

Write a valid python hash script

Parameters list

Python script must accept those parameters: item_list, value_list, default_sub_field_property_dict={}, is_right_display=0

  • item_list is the list of possibilities displayed by the field.
  • value_list is the list of selected values.
  • default_sub_field_property_dict is a template automatically given to make the configuration easier.

The script will hash the item_list into a list of dictionnaries, each dictionnary containing information to create a new ListField.

Content

# Define a dictionary where we store the subfields to display.
sub_field_dict = {}
split_depth = 1
# Maximum size of the MultiListField
maximum_list_size = 5
# Try to assign each item to a sub field.
for item in item_list:
  # Get value of the item
  item_value = item[int(not is_right_display)]
  # Hash key from item_value
  item_split = item_value.split('/')
  item_key = '/'.join(item_split[:split_depth])
  base_category = item_split[0]
  # Create a new subfield if necessary
  if not sub_field_dict.has_key(item_key):
    # Create property dict (key are field parameters)
    sub_field_property_dict = default_sub_field_property_dict.copy()
    sub_field_property_dict['key'] = item_key
    sub_field_property_dict['title'] = context.portal_categories[base_category].getTitle()
    sub_field_property_dict['required'] = 0
    sub_field_property_dict['field_type'] = 'MultiListField'
    sub_field_property_dict['size'] = 1
    sub_field_property_dict['item_list'] = []
    sub_field_property_dict['value'] = []
    sub_field_dict[item_key] = sub_field_property_dict
  # Put the value in the correct sub field.
  sub_field_dict[item_key]['item_list'].append(item)
  sub_field_property_dict['size'] = min(len(sub_field_dict[item_key]['item_list']) , maximum_list_size )
  if item_value in value_list:
    sub_field_dict[item_key]['value'].append(item_value)
# Return the list of subfield configuration.
return sub_field_dict.values()

Improve the rendering

By default, ERP5 html templates use the method 'render' define in Formulator, which only generate the field by himself, without any title. Then, the page template field_render give a title to this field. As our ParallelListField can contain for example 25 subfields, having only one title shared for all of them is a bit poor from a GUI point of view.

In order to improve this issue, we will use the method render_htmlgrid, which return a list of field associated to their title (1 title per subfield in our case).

field_render

<tal:block metal:define-macro="field_render">
  <tal:block tal:define="value python:request.get(field.id, None)">
    <tal:block tal:define="html_render python: field.render_htmlgrid(value, request)">

      <tal:block tal:condition="python:field.meta_type != 'HiddenStringField'">
        <tal:repeat repeat="html_tuple html_render">
          <tr>
            <td tal:content="structure python: html_tuple[0]"
                tal:attributes="class python: 
                             {0: {0: None, 1: 'required'},
                              1: {0: 'error', 1: 'reqerror'}}[field_errors.has_key(field.id)][field.is_required()]"
                i18n:translate="" i18n:domain="ui" />
            <td>
              <tal:block tal:replace="structure python: html_tuple[1]" />
            </td>
          </tr>
        
        </tal:repeat>
      </tal:block>

      <tr tal:condition="python: field_errors.has_key(field.id)">
        <td />
        <td tal:content="python:field_errors[field.id].error_text"
            i18n:translate="" i18n:domain="ui"
            class="error" />
      </tr>

    </tal:block>
  </tal:block>

</tal:block>

Related Articles