The ListBox allows to display information for a list of objects. The listbox is used everywhere in ERP5. In erp5, when you see the full list of objects from a module, you have a listbox in front of your eyes.
Table of Contents
Add a new ListBox¶
Usually, a listbox 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 'ListBox'. You must set the 'listbox' as id or you will get errors with ERP5.
Minimum configuration¶
Here we will define only a few fields, the strict necessary to get a working listbox with required parameters.
Title¶
It will be displayed on the top of the listbox. You can put any string, it is intended to explain to the user what is the content of your listbox.
Lines¶
It is simply the list of lines you want to display, 30 is usually quite nice.
Columns¶
This describes what are the columns of your listBox. It should be entered like this:
id | Number
title | Title
description | Description
getTotalQuantity | Quantity
This is of the form : [property or method] | [Label displayed to the user]. You can put as many columns as you want. The column name can be either a property name or a method/script which would be evaluated.
List method¶
This is the method used in order to get displayed objects. This can be a script, a method or a specific keyword. An example of method could be : objectValues, this method will return all objects in the current folder. You can also write a script and then specify this script id.
We usually use the keyword : 'portal_catalog'. Indeed, with this keyword, the ListBox will use the portal_catalog tool to find objects. We use this one as much as we can because it is the fastest one.
In case you need to use a custom list method you should make sure that it returns a list of newTempBase instances. For example:
from Products.ERP5Type.Document import newTempBase
list_of_dictionaries = [{'title': '...'},]
portal = context.getPortalObject()
return [newTempBase(portal,
x['title'],
**x) for x in list_of_dictionaries]
Selection Name¶
This is the name used in order to retrieve all parameters of the listbox. Indeed, in ERP5, when you set some parameters (like a research in a column), then if you go to another listbox, and come back, you will still have the same research selected. A good name for the selection is like this: /p>
[Form Name]_selection
For example:
person_module_view_person_list_selection
The selection name is very important and required. Thanks to that, the Selection Tool will create a new object for each user and for each selection_name in order to store all parameters of the listbox.
Portal Types¶
This will be a parameter given to the method (or script) used with List Method. So you can write a script with parameters like this:
portal_type=[], **kw
Then you will receive the list of Portal Types that you have entered in your listbox. Also, if you have used 'portal_catalog', then it will return automatically all objects with the given portal types. You have to specify Portal types like this:
Person | Person
Organisation | Organisation
You don't need to specify the second part here, it has no meaning. So you can let it empty, enter it like this:
Person
Organisation
Then the second part will be added automatically.
List Action¶
This is the form used when you click on the title of the listbox. There is already an existing default one often used with ERP5. You can put:
Folder_viewContentList
Well, that's it. You have now the minimum required in order to get a working listbox. There are a lot more parameters, hence we will see all them right now.
Please note that List Action's default value 'list' is not good, because its behaviour is somehow unexpectable (i.e. if no action whose id is 'list' found, one of available action is used as list action). So if you need a list action, please configure appropriately, and if you don't need a list action, please make it empty that means the list title becomes just a string instead of a link.
Full configuration¶
We will now see the non required part.
More Columns¶
More Columns¶ is used in the same way as Columns. All additional entries listed in More Columns are listbox columns that can be added by users of the system by clicking on the wrench icon in ERP5. Since r29829, you don't need to add same entries in More Columns field that already exist in Columns field, i.e. you can just specify 'More' Columns.
Editable Columns¶
Listbox cells may be directly editable, so that you don't have to enter an object every time you want to change a single value. If you have, for example, a 'price' column and want it to be editable, enter 'price' in 'Editable Columns' box; then create a Float Field in the same ERP5 Form and name it 'listbox_price'. That's all. You can use other types of fields the same way. The form now displays 'listbox_price' field next to your listbox - to hide it, create a group named 'hidden' in the Order tab and move the field there.
Url Columns¶
By default, every cell in a listbox is a link to default view of the object which forms a listbox row. Sometimes you may want to change it, for example, if you have a column:
subordination | Current employer
in your person list and you want it to link directly to the person's employer, not to the person.
To do this, you must write a simple script that will accept a 'brain' object and a 'selection' instance. If you use portal_catalog or searchFolder as list method, the 'brain' is an SQL brain and you have to do:
ob=kw['brain'].getObject()
if you want an ERP5 object. Otherwise the 'brain' argument is the ERP5 object. Your script should return a valid URL. Then in the URL box in listbox configuration enter:
subordination | yourScript
The 'Current employer' column will then become a link to the person's employer. If you don't want any link for this column, set the URL Column configuration to an empty string or None (if using a TALES expression):
subordination |
or in TALES:
python: [('subordination', None) ]
URL Columns for RenderJS UI¶
The format of the returned dict for renderJS UI should must have a specific format:
{
'command': "name of the command for generating URL at renderJS side, ex: `raw` for absolute url, `index` for normal link, `push_history` for link with history saved"
'options': {
'url': "abosulute_url which we want to display using the command `raw`"
'jio_key': "relative url of the object on which we want to run an action"
}
# `view_kw` are the params used to create view which is used in renderJS UI to
# create URL.
# NOTE: There is no need to add `view_kw` if we are only sending `absolute_url`
'view_kw': {
'view': "id of the action"
'jio_key': "relative url of the object on which we want to run an action"
'extra_param_json': "extra parameters to generate view URL"
}
}
Different cases where we need URL columns for both XHTML as well as renderJS UI¶
For customizing URL columns in renderJS UI, the script which we use for url columns can be modified to return a dictionary in specific format.
URL columns for absolute URL¶
For example, for downloading a document in document module, we currently have a script which return the Downloadable URL of the document.
return '%s/Base_download' % brain.absolute_url()
To have the similar result in renderJS UI, we have to modify the script. We need to add another named parameter 'url_dict=False
' (default is False because this way it indicates that we can still use this script to directly return url for XHTML style case)
if brain is None:
brain = context
# If `url_dict` is false, the script will still return the absoulte_url of the context(brain)
url = '%s/Base_download' % brain.absolute_url()
# If `url_dict` is True, the script will return a dictionary which will be used to create URL for RenderJS UI
if url_dict:
return {
'command': 'raw',
'options': {
'url': url
}
}
return url
URL columns for objects¶
If we want to create a URL, where we want to take the object to specific view action, we use slightly changed format.
if brain is None:
brain = context
# Just for example, we assume that the brain object has a getImage function which
# we will use for getting different object
image = brain.getImage()
# If `url_dict` is false, the script will still return the absoulte_url of the context(brain)
url = '%s/Base_metadata' % image.absolute_url()
# If `url_dict` is True, the script will return a dictionary which will be used to create URL for RenderJS UI
if url_dict:
jio_key = image.getRelativeUrl()
return {
'command': 'push_history', # Other commands can be 'view', 'index', etc.
'options': {
'jio_key': jio_key,
}
'view_kw': {
'jio_key': jio_key,
'view': 'metdata', # Reference of the view_action
}
}
return url
Default Parameters¶
List of parameters, which will be passed to List Method. For example, if list method is portal_catalog, portal type is Sale Order to show only confirmed you might use:
simulation_state | confirmed
To pass many parameters for one key you might use script:
return [
('simulation_state', ['planned','confirmed']),
]
which might be understood as:
simulation_state | planned , confirmed
but it is not possible to do it directly without TALES script.
Page navigation mode¶
One may configure type of listbox page navigation. At present moment (r38322) following page navigation modes are available:
- slider (default current ERP5 one) : buttons for first /previous / next / last pages
- text : direct page selection with buttons from first /previous / next / last pages
Global search column¶
Using this listbox configuration field one can show an additional global search input at bottom of a listbox. This global search usually represents a full text search. Value of this field is usually the name of the respective catalog scriptable key. For example KM uses 'SearchableText' to have a global full text system search.
Listbox List Styles¶
After r38321 a new concept of listbox styles have been added to listbox configuration. These concept allows a listbox to be visually represented in different styles like:
- table (current default one)
- search (i.e. with highlighted search text)
- thumbnail (image representation of current object)
Configuration of these styles can be done on listbox using:
- Display style: describe all possible list styles each on a new line
- Default display style: the default one
If a listbox has define more than one style in ERP5 mode a style selection will be show at top left corner. In ERP5 web mode this selection will be show in bottom left corner instead. As different styles require different columns (i.e. thumbnail style usually has only one column) it's possible to define columns for a listbox styles (XXX: to be defined).
Searchable / sortable columns¶
If you use portal_catalog or searchFolder as list method, you can safely leave these fields blank. ERP5 will figure out automatically which columns are sortable, and the column headers will become links allowing you to toggle between ascending/descending sort. If you check the "search row" option, these fields will also become searchable.
ERP5 will let you search and sort on the same columns on which you can search portal_catalog - which are the columns that exists in the 'catalog' table in MySQL. You can reduce the number of searchable or sortable columns by listing their names or simply entering "None". If you want to have more sortable/searchable columns then the stock portal_catalog allows you to do so, you must either:
- Write your own script and use it as list method
Then you can make any column searchable or sortable, the rest is up to your script
- create a releated key named after the column you want to search on.
Related keys are not auto-detected, so in this scenario you have to explicitly declare which column is searchable/sortable.
- Add a table with the respective field to the database, and some methods to portal_catalog.
The column referring to the field will become searchable/sortable by default. See How to add table with custom fields to SQL catalog
Date type columns issues¶
If you want to search/sort on columns like start_date or stop_date write those columns as delivery.start_date for documents like orders and movement.start_date for documents like order lines, etc.
Sorting and formatted / calculated columns¶
Another problem you may encounter is that you can sort on a column only if it is a "raw" property name - e.g. you can sort on this column:
creation_date | Created on
but not on this:
Object_formatCreationDate | Created on
You can achieve this by using editable fields - leave the column name "creation_date", make this column editable and add a field listbox_creation_date (make it uneditable). This can be either a StringField with default value like:
cell/Object_formatCreationDate
or, more simply, a DateField.
- Tip: If the field name, as entered in Columns box, contains a dot (e.g. "delivery.start_date"), the entry in Editable Columns box, should be the same, but in the name of the field replace dot with underscore (your DateTime field will be named listbox_delivery_start_date)
- Tip: if you want to get rid of this stupid label just above our listbox, go to the "Order" tab in the form definition and move the listbox_xxx field to the group "hidden"
Domain Tree¶
If object which are listed in the listbox belong to some base categories (which is nearly always the case), you can activate Domain Tree mode - this displays a Domain Tree icon on the top left of the listbox (next to the Flat View icon); then enter some base categories that the objects belong to into "Domain Root" box, and you'll be able to browse the listbox' contents by these category trees.
Refer to:
PersonModule_viewPersonList
form for the most basic (and working) example.
Combining two category trees¶
You can combine base categories to create virtual structures, like
role/region
to browse by two category structures at the same time. Note that the for the first structure (role, in this example), browsing depth is equal to the number of times you repeated the category name; so if you do:
role/region
you will have only first level of "role" classification, and then the whole "region" structure inside it. Consequently, if you do:
role/role/role/region
you will have three-level "role" and then region.
Tips and Tricks¶
HowToMakeLabelledUrlColumn
Experiments¶
Marked up ListBox lines (colouring)¶
To colour (or mark up in some other css-friendly way) specific lines on the listbox 3 things have to be done:
- The css class has to be defined and added (preferably dynamicaly) to the erp5.css style sheet. How to do it will be described in HowToUseCustomCss.
- There has to exist a script that recieves as an argument an object (from the listbox line). It should return a string which can be a css class name or many names separated by spaces. Those classes have to be defined as described above.
- The above script name should be entered in the 'Marking Method' field of the listbox formulator.
Now all the special listbox lines will be colorful or emboldened or with a nice background, whatever's your heart desire :)
Boxover¶
To show additional information about an object - much more then a line can reasonably contain - without having to click there and back. Can be configured in two ways:
- By defining Boxover Columns - the first one will be used as box title, the rest will be displayed like: "label: value " separated by line breaks.
- By writing a custom script and setting it as Boxover Method - the script receives one argument (the object behind a listbox line) and should return a dictionary containing "header", "body", and optionally many other things - styling, fade, delay etc.
When configured, it shows a nice floating box when you mouse over a listbox line.
The Boxover Method can also return a parameter "url" - this url will be used to get data from the server in a "lazy" (or AJAX) way (in standard configuration all the data for the box is contained in the page's html). See HowToUseExperimentalXhtmlStyle for details.
/!\ If you use that, it is highly recommended that you set some "delay", otherwise just moving a mouse over the listbox would trigger twenty requests.
This uses a library from http://boxover.swazz.org/, for which they deserve any amount of credits and praise, this thing is really awesome.
Related Articles¶