I have a editable table which has all my sale items in my sales editor page, in my scenario the item has a position which I have loaded using a datasource, what I want is to filter this for every item added so it only shows the position available for the selected item.
As seen in the image above I want to be able to change the query for every facility detail (position) to match only where the item selected is located please bear in mind in the designer the datasource used is the same for all of them so I can’t change the datasource directly as that would affect all the fields. Please advise on the best way to deal with this.
You probably have to abandon the common options datasource for the column and define a custom column with LookupField for which you can provide options via setOptionsList() method.
I tried however my issue is that I can’t edit the field directly to reset the option list for when the item changes how can I access the field from the selected row so I can call setOptionList. Also the row is generated with null value for item field so the option list is empty.
Imagine that in the Customer-Order-OrderLines model, the Customer entity should store some “special” order and order line. So the Customer browser should look as follows:
Here when user selects an Order, the list of available OrderLines changes. Selected Order and OrderLine are saved to specialOrder and specialOrderLine attributes of the Customer.
Let’s go through the changes.
Customer entity contains attributes specialOrder and specialOrderLine:
CustomerBrowse class contains methods generating columns. These methods get lookup fields from the cache which saves mappings of Customer instances to corresponding lookup fields. See comments in the code.
@UiController("sales_Customer.browse")
@UiDescriptor("customer-browse.xml")
@LookupComponent("customersTable")
@LoadDataBeforeShow
public class CustomerBrowse extends StandardLookup<Customer> {
@Inject
private UiComponents uiComponents;
@Inject
private DataManager dataManager;
@Inject
private DataComponents dataComponents;
@Inject
private DataContext dataContext;
private Map<Customer, Lookups> customerLookups = new HashMap<>();
private class Lookups {
LookupField<Order> orderLookup;
LookupField<OrderLine> orderLineLookup;
Lookups(Customer customer) {
// create master lookup and load options for it
orderLookup = uiComponents.create(LookupField.of(Order.class));
List<Order> orders = dataManager.load(Order.class)
.query("select e from sales_Order e where e.customer = :customer")
.parameter("customer", customer)
.view(View.MINIMAL)
.list();
orderLookup.setOptionsList(orders);
// create slave lookup
orderLineLookup = uiComponents.create(LookupField.of(OrderLine.class));
// reload slave lookup options on each change of the master value
orderLookup.addValueChangeListener(event -> {
if (event.getValue() != null) {
List<OrderLine> orderLines = dataManager.load(OrderLine.class)
.query("select e from sales_OrderLine e where e.order = :order")
.parameter("order", event.getValue())
.view(View.MINIMAL)
.list();
orderLineLookup.setOptionsList(orderLines);
} else {
orderLineLookup.setOptionsList(Collections.emptyList());
}
if (!Objects.equals(event.getValue(), event.getPrevValue())) {
orderLineLookup.setValue(null);
}
});
// data binding to save selected lookup values to Customer entity
InstanceContainer<Customer> customerDc = dataComponents.createInstanceContainer(Customer.class);
customerDc.setItem(customer);
orderLookup.setValueSource(new ContainerValueSource<>(customerDc, "specialOrder"));
orderLineLookup.setValueSource(new ContainerValueSource<>(customerDc, "specialOrderLine"));
}
}
// generate column with master lookup
public Component generateOrderCell(Customer entity) {
return customerLookups.computeIfAbsent(entity, customer -> new Lookups(entity)).orderLookup;
}
// generate column with slave lookup
public Component generateOrderLineCell(Customer entity) {
return customerLookups.computeIfAbsent(entity, customer -> new Lookups(entity)).orderLineLookup;
}
// clear cache on data refresh
@Subscribe(id = "customersDc", target = Target.DATA_CONTAINER)
private void onCustomersDcCollectionChange(CollectionContainer.CollectionChangeEvent<Customer> event) {
if (event.getChangeType() == CollectionChangeType.REFRESH) {
customerLookups.clear();
}
}
@Subscribe("commitBtn")
private void onCommitBtnClick(Button.ClickEvent event) {
dataContext.commit();
}
}