5

I've an combo box which is composed of a text field and a popup with a CellTable showing the suggestion items. The text field has a change handler that updates the CellTable's selection.

When typing a character and clicking an already selected suggestion, the first click is swallowed. The second click works and triggers the selection via the CellTable.addDomHandler(...).

Any idea why first click is swallowed?

Example code:

private static class SuggestFieldTextAndPopupSandbox extends SimplePanel {
        private final TextField mText;
        private CellTable<Handle<String>> mTable;
        private SingleSelectionModel<Handle<String>> mTableSelection;
        private SingleSelectionModel<Handle<String>> mSelection;
        private ProvidesKey<Handle<String>> mKeyProvider = new SimpleKeyProvider<Handle<String>>();
        private PopupPanel mPopup;
        private List<Handle<String>> mData;

        public SuggestFieldTextAndPopupSandbox() {
            mData = Lists.newArrayList(new Handle<String>("AAA"), new Handle<String>("AAB"), new Handle<String>("ABB"));
            mSelection = new SingleSelectionModel<Handle<String>>();

            mText = new TextField();
            mText.addKeyPressHandler(new KeyPressHandler() {
                @Override
                public void onKeyPress(KeyPressEvent pEvent) {
                    mPopup.showRelativeTo(mText);
                }
            });
            mText.addBlurHandler(new BlurHandler() {
                @Override
                public void onBlur(BlurEvent pEvent) {
                    mTableSelection.setSelected(startsWith(mText.getValue()), true);
                }
            });
            mText.addChangeHandler(new ChangeHandler() {

                @Override
                public void onChange(ChangeEvent pEvent) {
                    mText.setText(mText.getText().toUpperCase());
                }
            });

            mTable = new CellTable<Handle<String>>(0, GWT.<TableResources>create(TableResources.class));

            mTable.setTableLayoutFixed(false);
            mTableSelection = new SingleSelectionModel<Handle<String>>(mKeyProvider);
            mTable.setSelectionModel(mTableSelection);
            mTable.addDomHandler(new ClickHandler() {
                @Override
                public void onClick(final ClickEvent pEvent) {
                    Scheduler.get().scheduleFinally(new ScheduledCommand() {

                        @Override
                        public void execute() {
                            mSelection.setSelected(mTableSelection.getSelectedObject(), true);
                            mText.setFocus(true);
                            mPopup.hide();
                        }
                    });
                 }
            }, ClickEvent.getType());
            mTable.addColumn(new TextColumn<Handle<String>>() {
                @Override
                public String getValue(Handle<String> pObject) {
                    return pObject.get();
                }
            });
            mTable.setRowData(mData);

            mPopup = new PopupPanel();
            mPopup.setAutoHideEnabled(true);
            mPopup.setWidget(mTable);
            mPopup.setWidth("200px");
            mPopup.setHeight("200px");

            VerticalPanel p = new VerticalPanel();
            p.add(mText);
            setWidget(p);
        }

        private Handle<String> startsWith(final String pValue) {
            final String val = nullToEmpty(pValue).toLowerCase();
            int i = 0;
            for (Handle<String> item : mData) {
                String value = item.get();
                if (value != null && value.toLowerCase().startsWith(val)) {
                    return item;
                }
                i++;
            }
            return null;
        }

    }
Dan L.
  • 1,717
  • 1
  • 21
  • 41
  • Can you post example code? Is there a difference when you click on not selected suggestion? Why don't you use [GWT SuggestBox](http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/SuggestBox.html)? – Adam Feb 01 '16 at 09:22

2 Answers2

1

I reproduced your issue and here is the problem: when you click on the suggestions the following is happening:

  • The text field is loosing focus which causes the corresponding ChangeEvent to be dealt with followed by the BlurEvent.
  • The click causes the popup to get the focus now which is why it is swallowed.

If you remove the ChangeHandler and the BlurHandler of the text field the issue disappears. But I think I found another solution Try replacing the DOM handler of the mTable with a selection handler relative to the mTableSelection as follows:

mTableSelection.addSelectionChangeHandler(new Handler(){

            @Override
            public void onSelectionChange(SelectionChangeEvent event) {
                Scheduler.get().scheduleFinally(new ScheduledCommand() {

                    @Override
                    public void execute() {
                        mSelection.setSelected(mTableSelection.getSelectedObject(), true);
                        mText.setFocus(true);
                        mPopup.hide();
                    }
                });
            }

        });
Youssef Lahoud
  • 529
  • 3
  • 8
  • Thanks and it's a nice idea to solve the original issue just one side-effect is that the focus on the text is lost when user just hovers the table without clicking. This stops the editing and would be seen as a bug. But thanks for trying to run the example and help so I can assign the bounty to you if no other answer comes along the way. – Dan L. Feb 05 '16 at 10:33
0

Found a way how to properly solve this.

Skipping the blur handler when user hovers the suggestion list area seemed to fix that issue, at least from the tests that were done didn't see any more issues.

This was necessary because just before the user clicks a suggestion item, the text is blurred and it fires a selection change. This in turn cancels the selection made when user clicks an item.

Dan L.
  • 1,717
  • 1
  • 21
  • 41