Reputation: 25862
I'm trying to implement my first Vaadin ComboBox with autocomplete feature. This is what I have so far:
ComboBox<CompositeEntityResult> companyComboBox = new ComboBox<>("Company");
companyComboBox.setRequired(true);
companyComboBox.setItems(new CompanyBackEndDataProvider(companyService));
companyComboBox.setPageSize(20);
companyComboBox.setAllowCustomValue(true);
companyComboBox.setItemLabelGenerator(e -> TranslationUtils.getTranslatedName(e.getNode()));
As you may see, I added CompanyBackEndDataProvider which looks like:
public class CompanyBackEndDataProvider extends AbstractBackEndDataProvider<CompositeEntityResult, String> {
private final CompanyService companyService;
public CompanyBackEndDataProvider(CompanyService companyService) {
this.companyService = companyService;
}
@Override
protected Stream<CompositeEntityResult> fetchFromBackEnd(Query<CompositeEntityResult, String> query) {
Stream<CompositeEntityResult> stream = Stream.empty();
Optional filter = query.getFilter();
if (filter.isPresent()) {
int page = query.getPage();
int pageSize = query.getPageSize();
String namePattern = (String) filter.get();
if (StringUtils.isNoneBlank(namePattern)) {
List<CompositeEntityResult> compositeEntityResults = companyService.findByNamePattern(namePattern, VaadinUtils.getCurrentLocaleIso6391(), page, pageSize);
stream = compositeEntityResults.stream();
}
}
return stream;
}
@Override
protected int sizeInBackEnd(Query<CompositeEntityResult, String> query) {
int size = 0;
Optional filter = query.getFilter();
if (filter.isPresent()) {
String namePattern = (String) filter.get();
if (StringUtils.isNoneBlank(namePattern)) {
size = (int) companyService.findByNamePatternCount(namePattern);
}
}
return size;
}
}
At first glance everything works fine, but when I have a lot of items for the query term returned, I see the following message in the console when I scroll items a little down:
WARN 2992 --- [nio-8080-exec-7] c.v.flow.data.provider.DataCommunicator : Attempted to fetch more items from server than allowed in one go: number of items requested '220', maximum items allowed '200'.
Also, I may see a lot of empty space reserved in the ComboBox popup window with a scroll bar:
What am I doing wrong and how to fix it?
UPDATED
The same issue I may see, when I change the code to simply:
companyComboBox.setItems(query ->
companyService.findByNamePattern(query.getFilter().get(), VaadinUtils.getCurrentLocaleIso6391(), query.getOffset(), query.getLimit()).stream()
);
Also, when I remove the following line:
companyComboBox.setPageSize(20);
everything starts working fine.. Strange.. still don't understand the correlation between companyComboBox.setPageSize(20);
and the mentioned issue
Upvotes: 0
Views: 428
Reputation: 81
Sounds like a bug. If you check https://vaadin.com/api/platform/23.1.4/com/vaadin/flow/component/combobox/ComboBox.html:
ComboBox supports lazy loading. This means that when using large data sets, items are requested from the server one "page" at a time when the user scrolls down the overlay. The number of items in one page is by default 50, and can be changed with setPageSize(int).
but that's not true and can be reproduced with
ComboBox<Integer> comboBox = new ComboBox<>();;
comboBox.setItems((item, filterText) -> true, IntStream.range(0, 250).boxed().collect(Collectors.toList()));
comboBox.setPageSize(20);
On the other hand, the javadoc of setPageSize():
This does not guarantee a maximum query size to the backend; when the overlay has room to render more new items than the page size, multiple "pages" will be requested at once.
https://vaadin.com/api/platform/23.1.4/com/vaadin/flow/component/combobox/ComboBox.html#setPageSize(int). But seems to contradict the previous?
The reason this works without changing the page size:
public class DataCommunicator<T> implements Serializable {
private static final int MAXIMUM_ALLOWED_PAGES = 10;
...
private int getMaximumAllowedItems() {
return MAXIMUM_ALLOWED_PAGES * pageSize;
}
...
so by changing the pageSize (defaults to 50) we change also the limit (which I'd not expect, or at least expect that to be documented)
Upvotes: 1