Populate lookup field based on query

Hello,
I am using data grid component with inline editor. I have a column with a lookup field with some values which I passed dynamically.
Is there a way to populate the lookup field with some query so that I don’t have to pass those values dynamically?

browser XML:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://browseCaption"
        class="com.company.zeusv2.web.networkmapping.NetworkMappingBrowse"
        focusComponent="networkMappingsDataGrid"
        lookupComponent="networkMappingsDataGrid"
        messagesPack="com.company.zeusv2.web.networkmapping">
    <dsContext>
        <collectionDatasource id="networkMappingsDs"
                              class="com.company.zeusv2.entity.NetworkMapping"
                              view="_local">
            <query>
                <![CDATA[select e from zeusv2$NetworkMapping e]]>
                <filter>
                    <and>
                        <c>e.network = :custom$networkSearch</c>
                        <c>e.type = :custom$typeSearch</c>
                        <c>e.value = :custom$valueSearch</c>
                    </and>
                </filter>
            </query>
        </collectionDatasource>
    </dsContext>
    <dialogMode height="600"
                width="800"/>
    <layout expand="networkMappingsDataGrid"
            spacing="true">
        <label value="Network Mapping Table"/>
        <groupBox caption="Custom filter"
                  orientation="horizontal"
                  spacing="true">
            <lookupField id="networkLookup"
                         caption="Network Search"
                         inputPrompt="Select Network"/>
            <lookupField id="typeLookup"
                         caption="Type Search"
                         inputPrompt="Select Type"/>
            <lookupField id="valueLookup"
                         caption="Value Search"
                         inputPrompt="Select Value"/>
            <button id="applyCustomFilterBtn"
                    caption="Apply custom filter"
                    invoke="applyCustomFilter"/>
        </groupBox>
        <dataGrid id="networkMappingsDataGrid"
                  datasource="networkMappingsDs"
                  editorEnabled="true"
                  width="100%">
            <columns>
                <column property="network"/>
                <column property="type"/>
                <column property="keyValue"/>
                <column property="value"/>
                <column property="updated"/>
            </columns>
        </dataGrid>
    </layout>
</window>

Controller:


package com.company.zeusv2.web.networkmapping;

import com.company.zeusv2.entity.NetworkMapping;
import com.haulmont.cuba.core.entity.IdProxy;
import com.haulmont.cuba.gui.components.AbstractLookup;
import com.haulmont.cuba.gui.components.DataGrid;
import com.haulmont.cuba.gui.components.LookupField;
import com.company.zeusv2.entity.NetworkMapping;
import com.haulmont.cuba.gui.data.CollectionDatasource;
import com.haulmont.cuba.gui.xml.layout.ComponentsFactory;

import javax.inject.Inject;
import java.util.*;

public class NetworkMappingBrowse extends AbstractLookup {

    @Inject
    private DataGrid<NetworkMapping> networkMappingsDataGrid;
    @Inject
    private ComponentsFactory componentsFactory;
    @Inject
    private LookupField networkLookup;
    @Inject
    private LookupField typeLookup;
    @Inject
    private CollectionDatasource<NetworkMapping, IdProxy> networkMappingsDs;
    @Inject
    private LookupField valueLookup;


    @Override
    public void init(Map<String, Object> params) {

        List<String> networkList = Arrays.asList("AFFILINET", "ZANOX", "WEBGAINS", "NETAFFILIATION");
        List<String> typeList = Arrays.asList("COMMISSION_STATUS","COMMISSION_TYPE","RELATIONSHIP_STATUS", "COUNTRY");
        List<String> valueList = Arrays.asList("CONFIRMED","REJECTED","DELAYED", "SALE");


        networkMappingsDataGrid.getColumnNN("network")
                .setEditorFieldGenerator((datasource, property) -> {
                    LookupField networkLookupField = componentsFactory.createComponent(LookupField.class);
                    networkLookupField.setDatasource(datasource, property);
                    networkLookupField.setOptionsList(networkList);
                    return networkLookupField;
                });

        networkMappingsDataGrid.getColumnNN("type")
                .setEditorFieldGenerator((datasource, property) -> {
                    LookupField typeLookupField = componentsFactory.createComponent(LookupField.class);
                    typeLookupField.setDatasource(datasource, property);
                    typeLookupField.setOptionsList(typeList);
                    return typeLookupField;
                });

        networkMappingsDataGrid.getColumnNN("value")
                .setEditorFieldGenerator((datasource, property) -> {
                    LookupField valueLookupField = componentsFactory.createComponent(LookupField.class);
                    valueLookupField.setDatasource(datasource, property);
                    valueLookupField.setOptionsList(valueList);
                    return valueLookupField;
                });

        networkLookup.setOptionsList(networkList);
        typeLookup.setOptionsList(typeList);
        valueLookup.setOptionsList(valueList);
    }
    public void applyCustomFilter() {
        Map<String, Object> params = new HashMap<>();
        params.put("networkSearch", networkLookup.getValue());
        params.put("typeSearch", typeLookup.getValue());
        params.put("valueSearch", valueLookup.getValue());
        networkMappingsDs.refresh(params);
    }
}

Any suggestions will be appreciated.

Regards
Sanchit

Hello Sanchit,

Unfortunately, I’m not sure that I clearly understand what you want to achieve. I will really appreciate if you explain your goals in more detail. Also, I have assumptions about the data types of fields of your entity and according to this some suggestions how lookup fields can be populated with options, but without actual information, it’s only assumptions.

Generally speaking, we have several ways to populate LookupField with options:

  1. If LookupField corresponds to entity enum field i.e the datasource attribute is set, then LookupField will be automatically populated with enum values. See this sample.
  2. If LookupField is used to select an instance of a related entity, then the optionsDatasource attribute can be used to specify a datasource containing a list of related entity instances. See this sample.
  3. The list of LookupField options can be specified using setOptionsList(), setOptionsMap() and setOptionsEnum() methods (See this sample):
    • if you use setOptionsList() method, the drop-down list will display results of toString() transformation of each option value.
    • setOptionsMap() method allows you to specify a string caption for each option value explicitly.
    • setOptionsEnum() method 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.

Regards,

Gleb

Hi Gleb,

Sorry for the short explanation I should have been more precise.
What I meant is if you look at my controller code, I have list of strings for each column populating lookup field. what I want to achieve instead of passing list of strings the lookup field should populate itself with some datasource query.
for example:


select e.network from zeusv2$NetworkMapping e

then it should display all the available networks.

I hope you understand what I want to achieve.

Regards
Sanchit

For populating LookupFiled options using datasource you can use optionsDatasource attribute or setOptionsDatasoure() method. See this sample.

Regards,

Gleb

1 Like