Skip to content

Commit c20e2e9

Browse files
TatuLundAnsku
authored andcommitted
Fixing issue with TwinColSelect not correctly retaining visible selection (#11799)
There is a bug in TwinColSelect loging, it retains selection by indexes not by values after being sorted when new item has been added. This is a fixed by changing updateListBox method to retain the selection as it is being called after selection is being done. Fixes: #11287
1 parent 9baf4a9 commit c20e2e9

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

client/src/main/java/com/vaadin/client/ui/VTwinColSelect.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.function.BiConsumer;
2626
import java.util.stream.Collectors;
2727

28+
import com.google.gwt.core.client.Scheduler;
2829
import com.google.gwt.dom.client.Style.Overflow;
2930
import com.google.gwt.dom.client.Style.Position;
3031
import com.google.gwt.event.dom.client.ClickEvent;
@@ -37,6 +38,7 @@
3738
import com.google.gwt.event.dom.client.MouseDownEvent;
3839
import com.google.gwt.event.dom.client.MouseDownHandler;
3940
import com.google.gwt.event.shared.HandlerRegistration;
41+
import com.google.gwt.user.client.Element;
4042
import com.google.gwt.user.client.ui.Composite;
4143
import com.google.gwt.user.client.ui.FlowPanel;
4244
import com.google.gwt.user.client.ui.HTML;
@@ -80,6 +82,7 @@ public class VTwinColSelect extends Composite implements MultiSelectWidget,
8082
private static final int VISIBLE_COUNT = 10;
8183

8284
private static final int DEFAULT_COLUMN_COUNT = 10;
85+
private static int scheduledScrollToItem = -1;
8386

8487
private final DoubleClickListBox optionsListBox;
8588

@@ -327,15 +330,28 @@ public void setItems(List<JsonObject> items) {
327330

328331
private static void updateListBox(ListBox listBox,
329332
List<JsonObject> options) {
333+
List<String> selected = new ArrayList<String>();
334+
// Retain right visible selection, see #11287
335+
for (int i = 0; i < listBox.getItemCount(); ++i) {
336+
if (listBox.isItemSelected(i)) {
337+
selected.add(listBox.getItemText(i));
338+
}
339+
}
330340
for (int i = 0; i < options.size(); i++) {
331341
final JsonObject item = options.get(i);
332342
// reuse existing option if possible
343+
String caption = MultiSelectWidget.getCaption(item);
333344
if (i < listBox.getItemCount()) {
334-
listBox.setItemText(i, MultiSelectWidget.getCaption(item));
345+
listBox.setItemText(i, caption);
335346
listBox.setValue(i, MultiSelectWidget.getKey(item));
336347
} else {
337-
listBox.addItem(MultiSelectWidget.getCaption(item),
338-
MultiSelectWidget.getKey(item));
348+
listBox.addItem(caption, MultiSelectWidget.getKey(item));
349+
}
350+
boolean isSelected = selected.contains(caption);
351+
listBox.setItemSelected(i, isSelected);
352+
if (isSelected) {
353+
// Ensure that last selected item is visible
354+
scrollToView(listBox,i);
339355
}
340356
}
341357
// remove extra
@@ -344,6 +360,19 @@ private static void updateListBox(ListBox listBox,
344360
}
345361
}
346362

363+
private static void scrollToView(ListBox listBox, int i) {
364+
if (scheduledScrollToItem == -1) {
365+
scheduledScrollToItem = i;
366+
Scheduler.get().scheduleDeferred(() -> {
367+
Element el = (Element) listBox.getElement().getChild(scheduledScrollToItem);
368+
el.scrollIntoView();
369+
scheduledScrollToItem = -1;
370+
});
371+
} else {
372+
scheduledScrollToItem = i;
373+
}
374+
}
375+
347376
private static boolean[] getSelectionBitmap(ListBox listBox) {
348377
final boolean[] selectedIndexes = new boolean[listBox.getItemCount()];
349378
for (int i = 0; i < listBox.getItemCount(); i++) {

0 commit comments

Comments
 (0)