Search code examples
gwtgxtmulti-select

GXT ListField won't allow shift-select after scrolling


I have a page which uses GXT 2.2.5 with GWT 2.4.0 to generate a form including a multiple selection list. When the user selects an item, then shift + clicks on another item without scrolling it works as expected. However, when they select an item, scroll so the selected item is no longer visible, then shift+click on another item nothing is selected. It looks like the entire list is being selected then deselected.

I was able to reproduce this using the simplified code below in Chrome 36 and IE 9.

public class SimpleMultiSelectView implements WidgetFactory {

    public Widget buildWidget(String userName, Entry entry) {

        final Viewport viewport = new Viewport();
        final FormData formData = new FormData("-10");

        ListStore<ModelData> store = new ListStore();
        for (int i = 1; i< 50; i++) {
            ModelData modelData = new BaseModel();
            modelData.set("id", i);
            modelData.set("display", "Test " + i);
            store.add(modelData);
        }

        ListField<ModelData> selectionBox = new ListField<ModelData>();
        selectionBox.setStore(store);
        selectionBox.setDisplayField("display");
        selectionBox.setFieldLabel("display");
        selectionBox.setWidth(300);
        selectionBox.setHeight(300);

        LayoutContainer workFlowSearch = new LayoutContainer();    
        workFlowSearch.add(selectionBox, formData);

        viewport.add(workFlowSearch);

        return viewport;
    }
}

To reproduce the problem:

  1. Select any item in the list
  2. Scroll so that the selected item is no longer visible
  3. Hold the SHIFT key and select any item
  4. See that nothing is selected

Has anyone seen this before? What can I do to change the behavior?

Notes

I did try updating the project to GXT 3.1.0 and GWT 2.6.1 but it didn't seem to make a difference.

I also put together this HTML to sanity check myself

<html>
    <body>    
        <form action="">
            <select name="selection" multiple style="height: 200px; width: 125px">
                <option value="Option 1">Option 1</option>
                <option value="Option 2">Option 2</option>
                <option value="Option 3">Option 3</option>
                <option value="Option 4">Option 4</option>
                <option value="Option 5">Option 5</option>
                <option value="Option 6">Option 6</option>
                <option value="Option 7">Option 7</option>
                <option value="Option 8">Option 8</option>
                <option value="Option 9">Option 9</option>
                <option value="Option 10">Option 10</option>
                <option value="Option 11">Option 11</option>
                <option value="Option 12">Option 12</option>
                <option value="Option 13">Option 13</option>
                <option value="Option 14">Option 14</option>
                <option value="Option 15">Option 15</option>
                <option value="Option 16">Option 16</option>
                <option value="Option 17">Option 17</option>
                <option value="Option 18">Option 18</option>
                <option value="Option 19">Option 19</option>
            </select>
            <input type="submit">
        </form>    
    </body>
</html>

If you follow the reproduction steps above you will see that everything between your two selections is selected (inclusive), as expected.

Thanks


Solution

  • The ListField class in GXT 3 (since you tested with 3 as well, and I don't have a 2.x project open just yet...) is designed for single selections - the class declaration marks it as being generic on some T, so it is assignable to HasValue<T> and wraps a ListView that renders T items. From that alone, I predict (and confirmed) that the ListView is wired for single select:

    public ListField(ListView<M, T> view) {
      super(view);
      this.listView = view;
      this.listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
    

    Of course, you can modify this setting, but it won't change the generics so that getValue() suddenly returns List<T> instead of just T.

    This means that what is happening isn't that select is broken, but that you are trying to multi-select in a list set up for single select.


    If you don't actually need a ListField, but want to get the multi-select data out, consider just creating a ListView. This should more or less be the same in either GXT 2 or 3 - create the ListView as you are presently doing, and this time set the selection model to be MULTI or SIMPLE (reviewing the JavaDoc to decide which is applicable).

    To verify that this should work in both GXT 2/3: