Strange behavior of lookup form

I have a simple hierarchical entity Location with locName, locLevel, locParent and locChildren attributes. I created a lookup form with hierarchcal data source and TreeTable and I want to select locations with locLevel=3 only. I added this code in form controller:

public class LocationLookup extends AbstractLookup {
    @Inject
    private HierarchicalDatasource<Location, UUID> locationsDs;
    private Action lookupSelectAction;
    private Button selectButton;

    @Override
    public void ready() {
        super.ready();
        selectButton = (Button) getComponent("selectButton");
        lookupSelectAction = getAction("lookupSelectAction");
        locationsDs.addItemChangeListener(e -> {
            Location location = e.getItem();
            selectButton.setEnabled(location != null && location.getLocLevel() == 3);
            lookupSelectAction.setEnabled(selectButton.isEnabled());
        });
    }
}

But the selectButton remains enabled always and any item can be selected by the lookup form.
When I comment the line
//lookupSelectAction.setEnabled(selectButton.isEnabled());
the selectButton becomes enabled only when locLevel=3 (it is right), but despite that I can select any location item by mouse doubleclick.
How can I restrict lookup selection?

Hi,

If an Action instance is defined for a Button, the button will take the following properties from it: caption, description, icon, enable, visible. So, instead of disabling the button, you need to disable the action.

I tried this too, no results.
Platform version 6.7.9

Then I would recommend you to remove the default LookupValueChangeListener from a lookupComponent and add a custom handler, for instance:

@Override
public void setLookupComponent(Component lookupComponent) {
    super.setLookupComponent(lookupComponent);

    Frame frame = getFrame();
    if (lookupComponent instanceof LookupSelectionChangeNotifier
            && frame instanceof WebWindow.Lookup) {
        LookupSelectionChangeNotifier lvChangeNotifier = (LookupSelectionChangeNotifier) lookupComponent;
        WebWindow.Lookup lookup = (WebWindow.Lookup) frame;

        lvChangeNotifier.removeLookupValueChangeListener(lookup);
        lvChangeNotifier.addLookupValueChangeListener(event -> {
            Action selectAction = getAction(WindowDelegate.LOOKUP_SELECT_ACTION_ID);
            if (selectAction != null) {
                // Provide custom logic instead of the default one
                // selectAction.setEnabled(!event.getSource().getLookupSelectedItems().isEmpty());
            }
        });
    }
}

I inserted in you code this line:
selectAction.setEnabled(locationsTable.getSingleSelected() != null && locationsTable.getSingleSelected().getLocLevel() == 3);

Yes, with this code the selectButton becomes enabled only with level==3, but I still can select any item with mouse doubleclick. How to intercept the doubleclick event?

Add the following to the setLookupComponent method:

if (lookupComponent instanceof LookupComponent) {
    ((LookupComponent) lookupComponent).setLookupSelectHandler(() -> {
        // do nothing
    });
}

Thanks, this works well, I inserted the same validation “level==3” and actionPerform instead of “do nothing”:
Is there a possibility to replace inner event handlers without such undocumented kludges?

You can rewrite the code above using particular table component, so you won’t need any casts. I just used the most generic code. Alternatively, you can completely rewrite the initLookupLayout and setLookupComponent methods.