3.5.2.1.25. LookupField

This is a component to select a value from drop-down list. Drop-down list provides the filtering of values as the user inputs some text, and the pagination of available values.

gui lookupField

XML name of the component: lookupField.

  1. The simplest case of using LookupField is to select an enumeration value for an entity attribute. For example, a Role entity has a type attribute of the RoleType type, which is an enumeration. Then you can use LookupField to edit this attribute as follows:

    <data>
        <instance id="roleDc"
                  class="com.haulmont.cuba.security.entity.Role"
                  view="_local">
            <loader/>
        </instance>
    </data>
    <layout expand="editActions" spacing="true">
        <lookupField dataContainer="roleDc" property="type"/>
    </layout>

    In the example above, the screen defines roleDc data container for the Role entity. In the lookupField component, a link to a data container is specified in the dataContainer attribute, and a name of an entity attribute is specified in the property attribute. In this case, the entity attribute is an enumeration, and the drop-down list will display localized names of all enumeration values.

  2. Similarly, LookupField can be used to select an instance of a related entity. optionsContainer attribute is used to create a list of options:

    <data>
        <instance id="carDc" class="com.haulmont.sample.core.entity.Car" view="carEdit">
            <loader/>
        </instance>
        <collection id="colorsDc" class="com.haulmont.sample.core.entity.Color" view="_minimal">
            <loader id="colorsDl">
                <query>
                    <![CDATA[select e from sample$Color e]]>
                </query>
            </loader>
        </collection>
    </data>
    <layout>
        <lookupField dataContainer="carDc" property="color" optionsContainer="colorsDc"/>
    </layout>

    In this case, the component will display instance names of the Color entity located in the colorsDc data container, and the selected value will be set into the color attribute of the Car entity, which is located in the carDc data container.

    captionProperty attribute defines which entity attribute can be used instead of an instance name for string option names.

  3. The list of component options can be specified arbitrarily using the setOptionsList(), setOptionsMap() and setOptionsEnum() methods, or using the XML optionsContainer or optionsDatasource attribute.

    • setOptionsList() allows you to programmatically specify a list of component options. To do this, declare a component in the XML descriptor:

      <lookupField id="numberOfSeatsField" dataContainer="modelDc" property="numberOfSeats"/>

      Then inject the component into the controller and specify a list of options in the onInit() method:

      @Inject
      protected LookupField<Integer> numberOfSeatsField;
      
      @Subscribe
      public void onInit(InitEvent event) {
          List<Integer> list = new ArrayList<>();
          list.add(2);
          list.add(4);
          list.add(5);
          list.add(7);
          numberOfSeatsField.setOptionsList(list);
      }

      In the component’s drop-down list the values 2, 4, 5 and 7 will be displayed. Selected number will be put into the numberOfSeats attribute of an entity located in the modelDc data container.

    • setOptionsMap() allows you to specify string names and option values separately. For example, in the numberOfSeatsField component in the XML descriptor, specify an option map in onInit():

      @Inject
      protected LookupField<Integer> numberOfSeatsField;
      
      @Subscribe
      public void onInit(InitEvent event) {
          Map<String, Integer> map = new LinkedHashMap<>();
          map.put("two", 2);
          map.put("four", 4);
          map.put("five", 5);
          map.put("seven", 7);
          numberOfSeatsField.setOptionsMap(map);
      }

      In the component’s drop-down list, two, four, five, seven strings will be displayed. However, the value of the component will be a number that corresponds to the selected option. It will be put into the numberOfSeats attribute of an entity located in the modelDc data container.

    • setOptionsEnum() takes the class of an enumeration as a parameter. The drop-down list will show localized names of enum values, the value of the component will be an enum value.

  • setOptionStyleProvider() enables you to use separate style names for the the options displayed by the component:

    lookupField.setOptionStyleProvider(entity -> {
        User user = (User) entity;
        switch (user.getGroup().getName()) {
            case "Company":
                return "company";
            case "Premium":
                return "premium";
            default:
                return "company";
        }
    });
  • Each drop-down list component can have an icon on the left. Use the setOptionIconProvider() method in the screen controller:

    lookupField.setOptionIconProvider(entity -> {
        if (entity.getType() == LegalStatus.LEGAL)
            return "icons/icon-office.png";
        return "icons/icon-user.png";
    });
    gui lookupField 2

    If you use SVG icons, set the icon size explicitly to avoid icons overlay.

    <svg version="1.1"
         id="Capa_1"
         xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xml:space="preserve"
    
         style="enable-background:new 0 0 55 55;"
         viewBox="0 0 55 55"
    
         height="25px"
         width="25px">
  • If the LookupField component is not required and if the related entity attribute is not declared as required, the list of component options has an empty row. If this row is selected, the component returns null. The nullName attribute allows you to specify a row to be displayed in this case instead of an empty one. Below is an example:

    <lookupField dataContainer="carDc" property="colour" optionsContainer="colorsDs" nullName="(none)"/>

    In this case, instead of an empty row, (none) will be displayed. If this row is selected, null will be set to a related entity attribute.

    If you specify a list of options programmatically using setOptionsList(), you can pass one of the options into setNullOption() method. Then, if the user selects it, the component value will be null.

    LookupField filters:
    • Using the filterMode attribute, option filtering type can be defined for the user input:

      • NO − no filtering.

      • STARTS_WITH − by the beginning of a phrase.

      • CONTAINS − by any occurrence (is used by default).

    • The setFilterPredicate() method enables to setup how items should be filtered. The predicate tests whether an item with the given caption matches to the given search string. For example:

      BiFunction<String, String, Boolean> predicate = String::contains;
      lookupField.setFilterPredicate((itemCaption, searchString) ->
              predicate.apply(itemCaption.toLowerCase(), searchString));

      The functional interface FilterPredicate has the test method that enables implementing custom filtering logic, for example, to escape accents or special characters:

      lookupField.setFilterPredicate((itemCaption, searchString) ->
              StringUtils.replaceChars(itemCaption, "ÉÈËÏÎ", "EEEII")
                  .toLowerCase()
                  .contains(searchString));
  • The LookupField component is able to handle user input if there is no suitable option in the list. In this case, setNewOptionHandler() is used. For example:

    @Inject
    private Metadata metadata;
    @Inject
    private LookupField<Color> colorField;
    @Inject
    private CollectionContainer<Color> colorsDc;
    
    @Subscribe
    protected void onInit(InitEvent event) {
        colorField.setNewOptionHandler(caption -> {
            Color color = metadata.create(Color.class);
            color.setName(caption);
            colorsDc.getMutableItems()
                    .add(color);
            colorField.setValue(color);
        });
    }

    The new options handler is invoked if the user enters a value that does not coincide with any option and presses Enter. In this case, a new Color entity instance is created in the handler, its name attribute is set to the value entered by the user, this instance is added to the options data container and selected in the component.

    Instead of using setNewOptionHandler() method for processing user input, the controller method name can be specified in the newOptionHandler XML attribute. This method should have two parameters, one of LookupField type, and the other of String type. They will be set to the component instance and the value entered by the user, accordingly. The newOptionAllowed attribute is used to enable adding new options.

  • The nullOptionVisible XML attribute sets visibility for the null option in the drop-down list. It allows you to make LookupField not required but still without the null option.

  • The textInputAllowed XML attribute can be used to disable filtering options from keyboard. It can be convenient for short lists. The default value is true.

  • The pageLength XML attribute allows you to redefine the number of options on one page of the drop-down list, specified in the cuba.gui.lookupFieldPageLength application property.

  • In Web Client with a Halo-based theme, you can set predefined styles to the LookupField component using the stylename attribute either in the XML descriptor or in the screen controller:

    <lookupField id="lookupField"
                 stylename="borderless"/>

    When setting a style programmatically, select one of the HaloTheme class constants with the LOOKUPFIELD_ prefix:

    lookupField.setStyleName(HaloTheme.LOOKUPFIELD_BORDERLESS);

    LookupField styles:

    • align-center - align the text inside the field to center.

    • align-right - align the text inside the field to the right.

    • borderless - removes the border and background from the text field.