Unsure about Depending Picklists

Hi Guys,

I haven’t worked much mich cuba platform so far, therefore I am somewhat stuck on a simple proof of concept:

I’d like to have a form with three picklists to enter a new record for entitiy objectRelationship: Object1, object2 and objectRelationshipClassification (see attached ER Diagram)

image

as you can see object 1, object2 and objectRelationshipClassification all have a reference to ‘category’

Now, I’d like to create a dependency of sorts so that only objectRelationshipClassifications are listed which match the object1 and object2 categories.
Basically something like
select e from everything_ObjectRelationshipClassification e where e.object1Category= object1.category and e.object2Category= object2.category

Obviously I want the list of objectRelationshipClassifications to change in realtime if object1 or object2 are changed.

I am sure there is an easy way to do this, but maybe I am looking at the wrong part of the documentation. Maybe someone can help me out?

Hi Uwe,

what you probably need is a particular component, which is called dataLoadCoordinator. Here are the general docs on that: DataLoadCoordinator - CUBA Platform. Developer’s Manual
A while ago I created a example showing how to use it here: How to filter values of second lookup acordly of the selected value of first lookup - #15 от пользователя mario - CUBA.Platform

But as for your case, it is a little different, I have prepared a sample for you.

CUBA Example - Dependent Picker

cuba-example-dependent-picker.zip (109.3 KB)

2021-01-02 19.22.20

The main topic is to be done in the object-relationship-edit.xml, where the data load coordinator is initiated like this:

object-relationship-edit.xml

    <data>
        <instance id="objectRelationshipDc"
                  class="com.rtcab.cedp.entity.ObjectRelationship">
            <view extends="_local">
                <property name="object1" view="_minimal">
                    <property name="category" view="_minimal"/>
                </property>
                <property name="object2" view="_minimal">
                    <property name="category" view="_minimal"/>
                </property>
                <property name="objectRelationshipClassification" view="_minimal">
                    <property name="object1Category" view="_minimal"/>
                    <property name="object2Category" view="_minimal"/>
                </property>
            </view>
            <loader/>
        </instance>
        <collection id="object1sDc" class="com.rtcab.cedp.entity.Object" view="object-with-category">
            <loader id="object1sDl">
                <query>
                    <![CDATA[select e from cedp_Object e]]>
                </query>
            </loader>
        </collection>
        <collection id="object2sDc" class="com.rtcab.cedp.entity.Object" view="object-with-category">
            <loader id="object2sDl">
                <query>
                    <![CDATA[select e from cedp_Object e]]>
                </query>
            </loader>
        </collection>
        <collection id="objectRelationshipClassificationsDc"
                    class="com.rtcab.cedp.entity.ObjectRelationshipClassification" view="_minimal">
            <loader id="objectRelationshipClassificationsDl">
                <query>
                    <![CDATA[select e from cedp_ObjectRelationshipClassification e where e.object1Category = :object1Category and e.object2Category = :object2Category]]>
                </query>
            </loader>
        </collection>
    </data>
    
    <facets>
        <dataLoadCoordinator auto="true"/>
    </facets>

ObjectRelationshipEdit.java

In the controller, you have to manually set the parameters in the objectRelationshipClassificationsDl as you are not filtering for a direct attribute, but rather via the object.category association.


@UiController("cedp_ObjectRelationship.edit")
@UiDescriptor("object-relationship-edit.xml")
@EditedEntityContainer("objectRelationshipDc")
@LoadDataBeforeShow
public class ObjectRelationshipEdit extends StandardEditor<ObjectRelationship> {

    @Inject
    protected LookupField<ObjectRelationshipClassification> objectRelationshipClassificationField;
    @Inject
    private CollectionLoader<ObjectRelationshipClassification> objectRelationshipClassificationsDl;

    @Subscribe(id = "object1sDc", target = Target.DATA_CONTAINER)
    protected void onObject1sDcItemChange(InstanceContainer.ItemChangeEvent<Object> event) {
        addObjectCategoryParameter(event, "object1Category");
        refreshClassificationLookup();
    }

    @Subscribe(id = "object2sDc", target = Target.DATA_CONTAINER)
    public void onObject2sDcItemChange(InstanceContainer.ItemChangeEvent<Object> event) {
        addObjectCategoryParameter(event, "object2Category");
        refreshClassificationLookup();
    }

    private void addObjectCategoryParameter(InstanceContainer.ItemChangeEvent<Object> event, String parameterName) {
        objectRelationshipClassificationsDl.setParameter(parameterName, event.getItem().getCategory());
    }

    private void refreshClassificationLookup() {
        if (getEditedEntity().getObject1() != null && getEditedEntity().getObject2() != null) {
            objectRelationshipClassificationField.setValue(null);
            objectRelationshipClassificationsDl.load();
        }
    }
}

objectRelationshipClassificationsDl.setParameter(parameterName, event.getItem().getCategory()); sets the corresponding value in the data loader. You have to register for value change events of both fields and add the corresponding parameter to the data loader.

I hope this helps.

Cheers
Mario

Thank you David for all your effort - Haven’t expected that much! I’ll give this a try!

Dear David, it works flawlessly - Thank you!

1 Like