NexJ Logo

Working with pickers

Pickers provide a consistent user experience for selecting objects. Typically, you declare a Picker (.picker file) for a class or enumeration. This configures captions, icons, searching, filtering, and paging of the picker pop-up dialog to make picking the right items easy and consistent. Multipicker and single picker controls then reuse the Picker definition in portlet layouts.

For more information about Picker elements and the .picker files, see Picker.

Learning objectives
In this lesson, you will review examples to learn:

  • About the different pickers available.
  • The differences between pickers and picker control.
  • How and when to use the pickers.

Key concepts
In this lesson, we deal with three distinct MODL elements:

  • Picker element - declares the display and behaviour of a picker pop-up dialog. Lives in a .picker file.
  • Picker control - configures single item picking on a layout. Lives as an element within a layout.
  • Multipicker control - configures multi item picking on a layout. Lives as an element within a layout.

There are two main use cases pertaining to pickers:

  • Single-item pickers use a picker control. The control specifies the type ahead search, filter, chip caption, and icon.

    Single item pickers using a Picker control


  • Multi-item pickers use a multipicker control. The control specifies the type ahead search, filter, chip caption, icon, and intersection class to which items are written.

    Multi-item pickers use a MultiPicker control


9.X

Filter and picker configurations have been simplified in 9.X. You can now maintain one .picker configuration per class that supports single-item pickers and various modes for multi-item pickers all in one place.

Picker control - single-item selection

A Picker control is an enhanced combo box that provides type-ahead selection and a picker dialog as defined in a .picker file, returning a single value. It supports type-ahead and has a + button to bring up its picker dialog based on a reference to a picker (.picker file) declaration and a binding to a complex attribute, that is, not a primitive, date, string, or integer of the referenced .picker's type.

In this example, it is used in a case where there is a foreign key in one class that points to another class.

The important properties to note are:

  • caption - the caption to display on the picker dialog. This is the only property from the control that directly affects the pop-up dialog's display.
  • value - a complex attribute from the class to which the containing layout is bound. The attribute that we are picking, for example, employer which is an attribute on Contact, of type Company.
  • valueCaption - the caption for the type-ahead list (combo) and the displayed chip for the selected item. This is an attribute on the returned object as configured in the value property.
  • valueIcon - the icon for the type-ahead list (combo) and the displayed chip for the selected item. This is a set of image value pairs referring to image attributes on the returned object as configured in the value property. For example:

    (image . (company image))(data . mimeData)(type . mimeType)(icon . (company icon))(default . "icon:client")
  • ref - a reference to the .picker declaration. The type of the .picker must work with the type of the value property.

    <Layout...
        ...
        <Picker
               caption="idsf.AccountMappingProperties.Company"
               name="pickCompany"
               ref="mda:Company"
               value="company"
               valueCaption="lastName"
               valueIcon="(image . (company image))(data . mimeData)(type . mimeType)(icon . (company icon))(default . &quot;icon:&quot;)"/>
    ...   

If you type in the list, based on the configuration above, you get:

Typing in the list based on configuration above

and a selected item will appear as:

Selected item - company

Clicking the picker control's + button, displays the picker dialog as declared in the .picker file with the caption set by the picker control.

Picker dialog as declared in the .picker file with the caption set by the picker control

The drop-down list selects a single value and the pop-up picker dialog displays radio buttons rather than checkboxes (single selection vs multiple selection). The platform knows the cardinality of the association; many (employees) to one (employer).

To learn more about the various properties of a picker control, see Picker.

Picker (.picker file) declaration for single-item pickers

The picker declaration for single-item picking is straightforward. The declaration specifies the picker dialog's sorting, searching, and how rows are displayed. This is the simplest sort of declaration, where you specify:

  • Class - the class from which you pick instances.
  • Captions - the caption for each item in the list to display.
  • Icons - the icon to display in the list if the class has an icon or image attribute. This is a set of image value pairs referring to image attributes on the items in the list. For example:

    (image . (company image))(data . mimeData)(type . mimeType)(icon . (company icon))(default . "icon:client")
  • Order - the default sort order.
  • Search - the attribute to use for filtering the picker list.

The following example is for the Company class.

<Picker
   captions="lastName"
   class="Company"
   icons="(image . image)(data . mimeData)(type . mimeType)(icon . icon)(default . &quot;icon:&quot;)"
   order="((lastName . #t) ((@) . #t))"
   search="fullTextSearch"/>

and is rendered as follows when invoked by picking a company for a person.

Invoked when picking a company for a person


Additionally, for single-item pickers, Mode may be used to satisfy use cases that need a filtered list. Here, we simply create a number of modes in the Picker declaration with different where clauses that can be applied. For instance, a picker control may have mode="activeClients" to filter the list of companies to only active clients in a particular layout.

For more information about the Picker Configuration Mode, see Mode.

For more about the various properties of a .picker declaration, see Picker.

Enumeration pickers

Although enumerations can be rendered as pickers, designs usually dictate that they are rendered as combo controls. It is uncommon for enumerations to be rendered as pickers.

That said, declaring a picker for an enumeration is very simple. The following example is for the Country enumeration class.

<Picker captions="caption" class="Country" order="(displayOrder)" search="caption" values="value"/>

It is rendered as:

Country enumeration class rendered

Multipicker control - multiple-item selection

A multipicker control allows you to pick many items. It supports type-ahead and has a "+" button to bring up its picker dialog based on a reference to a picker (.picker file) declaration. It is bound to a collection attribute that points to an intersection class in a many-to-many relationship. It picks from a class through an intersection to create records in the intermediate intersection table.

This is essentially the structure of a many-to-many association.


A - Class to which the containing Layout is bound.

B - Class you are picking.

AB - Intersection class between A and B.

a b - Association path between A and B through the intersection class AB.

a - Collection attribute on class A of type AB. The picker's collection is bound to this attribute.

Example

Many-to-many association

The important properties are:

  • Caption - the caption to display on the picker dialog. This is the only property from the control that directly affects the pop-up dialog's display.
  • Items - the association path to the intersection class. For example, (@ userParticipants).
  • Captions - the association path or expression to the captions for the selected items, usually displayed as chips. The path to the attribute to display is from the perspective of the intersection class. For example, UserParticipations'entityFullName → entityFullName.
  • Icons - the association path or expression to the icons for the selected items, usually displayed as images in chips. The path to the attribute to display is from the perspective of the intersection class. For example, (UserParticipation'entity) image)  → (entity image).
  • Order - the orderby statement for the selected items. The path to the attributes to sort by is from the perspective of the intersection class. For example, (UserParticipation'entity) lastName) → ((@ entity lastName) . #t).
  • Ref - a reference to the .picker declaration. The type of the .picker must work with the type of the value property.
  • Mode - when used with a multipicker, the mode declares the association from the picker class back to the class to which the multipicker's containing layout is bound, as well as the factory for creating new intersection instances. For example, when picking UserPerson instances to associate with a Task through the UserParticipation intersection class, we specify the mode's association to userParticipations and the selection to Task userParticipants.

<Layout...
    ...
    <Multipicker
        caption="IDS_FOR"
        captions="entityFullName"
        icons="(image . (entity image))(data . mimeData)(type . mimeType)(icon . (entity icon))(default . "contact")"
        items="(@ userParticipants)"
        mode="Task userParticipants"
        name="lblParticipantsLink"
        order="(((@ entity lastName) . #t) ((@ entity firstName) . #t) ((@ entity) . #t))"
        ref="mda:BatchEmailCommandRecipientPickerMM"/>
...   

If you type in the list, based on the configuration above, you get:

Type in the list based on above configuration

and the selected items will look like:

Selected items

Clicking the picker control's + button displays the picker dialog as declared in the .picker file with the caption set by the picker control.

The drop-down list lets you select items over and over, and the pop-up picker dialog displays checkboxes rather than radio buttons (multiple selection vs. single selection). Learn more about the various properties of a multipicker control from the Model Description Language Reference.

Picker (.picker file) declaration for multi-item pickers

The picker declaration for multi-item picking is dependent on the modes. The approach for captions, icons, order, and search is the same as with single-item pickers.

<Picker 
   captions="fullNameFirstLast" 
   class="UserPerson" 
   icons="(image . image)(data . mimeData)(type . mimeType)(icon . icon)(default . "icon:person")" 
   order="(((@ firstName) . #t) ((@ lastName) . #t) ((@) . #t))" 
   search="fullTextSearch"">

The mode declares the association from the picker class back to the class and attribute for which the items are being picked. There may be many modes configured for multipicking; possibly as many modes as there are outgoing many-to-many associations from the picker class.

The properties for a mode used for multi picking are:

  • Association - the association path from the item being picked to the intersection class. For example, userParticipations.
  • Factory - the new item factory event for new intersection instances, <class> <event> or <event> if the event is on the picker class. The typical configuration is <class> <event>. For example, UserParticipation create.
  • Name - the picker mode name. It should be something meaningful from the other side of the association. It defaults to the selection, which should usually make sense. For example, Task userParticipants.
  • Selection - the class name and association attribute name from the other side of this many-to-many association. For example, Task userParticipants.

The following example is for the Task userParticipants mode of the UserPerson class picker.

<Mode
   assoc="userParticipations"
   factory="UserParticipation create"
   name="Task userParticipants"
   selection="Task userParticipants"/>

Note that for enumerations, there will often not be a "reverse" attribute to use in the "assoc" property. For most of these cases, you can simply not set the assoc property.



Learn more about the various properties of a .picker declaration in the Model Description Language Reference.

Tables as Pickers

You can also configure a table with the same configuration parameters as a Multipicker.  This will add a "+" button to the table's toolbar.  This is very convenient for simple table selection.

Advanced picker (.picker file) declaration

Picker declarations may also specify that they have a filter. The chips that appear for the filter may be limited by using the subject property.

In addition, you can override the generated picker table by specifying your own table columns and headings.

Using pickers in filters

In addition to being used in picker and multipicker controls, pickers may be referenced in Filter Fields to provide picker capabilities for filtering lists.


<Table ref="mda:ActStatusEnum" mode="ActivityPlanTemplate statuses" values="actStatus" caption="ids.Statuses" name="tblActTemplateStatuses" rows="(@ statuses)">


Using pickers in Script 

Pickers may also be used in Script. The openPickerDialog method on the controller API allows you to call a pre-defined picker from Script.

In the following code, we allow the user to pick a number of participants in a conversation and then continuing processing based on the selection.

(define conversation (@ model item : (parameter'index)))
(define participants
   (@ openPickerDialog :
      "mda:ConversationParticipantPicker"
      (: where `(not (in? (@) ,(map (lambda (p) (p'entity)) (conversation'activeParticipants)))))
      (: factory '(ConversationParticipant createConversationParticipant))
      (: values "entity")
      (: parameter (list (: conversation conversation)))
   )
)
(unless (null? participants)
  ...

openPickerDialog also supports generic pickers. This creates a default picker for a class without the use of a pre-defined .picker file. The method supports both single and multi-picker modes. This is an experimental feature and is accessed by setting the "ref" to either #t or #f.

Custom pickers

Custom pickers are used infrequently. If the picking requirements are very specialized, there are ways to build a custom control in AFL. This information is not covered here, but an example can be seen in the finance-ai service.