What is a ParallelListField
The ParallelListField is a ERP5 widget used to split a huge MultiListField into multiple ListField, MultiListField.
Add a new ParallelListField
Usually, such widget is added in ERP5 Forms. 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
1 # Define a dictionary where we store the subfields to display.
2 sub_field_dict = {}
3 split_depth = 1
4 # Maximum size of the MultiListField
5 maximum_list_size = 5
6 # Try to assign each item to a sub field.
7 for item in item_list:
8 # Get value of the item
9 item_value = item[int(not is_right_display)]
10 # Hash key from item_value
11 item_split = item_value.split('/')
12 item_key = '/'.join(item_split[:split_depth])
13 base_category = item_split[0]
14 # Create a new subfield if necessary
15 if not sub_field_dict.has_key(item_key):
16 # Create property dict (key are field parameters)
17 sub_field_property_dict = default_sub_field_property_dict.copy()
18 sub_field_property_dict['key'] = item_key
19 sub_field_property_dict['title'] = context.portal_categories[base_category].getTitle()
20 sub_field_property_dict['required'] = 0
21 sub_field_property_dict['field_type'] = 'MultiListField'
22 sub_field_property_dict['size'] = 1
23 sub_field_property_dict['item_list'] = []
24 sub_field_property_dict['value'] = []
25 sub_field_dict[item_key] = sub_field_property_dict
26 # Put the value in the correct sub field.
27 sub_field_dict[item_key]['item_list'].append(item)
28 sub_field_property_dict['size'] = min(len(sub_field_dict[item_key]['item_list']) , maximum_list_size )
29 if item_value in value_list:
30 sub_field_dict[item_key]['value'].append(item_value)
31 # Return the list of subfield configuration.
32 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>