gwtcelltablegwt-celltable

CellTable click swallowed


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;
        }

    }

Solution

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

    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();
                        }
                    });
                }
    
            });