Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to auto scroll GWT SuggestBox with max-height and overflow-y: scroll?

Tags:

scroll

widget

gwt

How can I auto scroll the GWT SuggestBox with max-height set on the PopupPanel holding the SuggestBox? Currently when the user presses keyboard up keys and down keys styles changes on the suggested items and pressing enter will select the currently selected item on the list.

When the item is located in lower than the max-height scroll bars doesn't scroll. I tried extending the SuggestBox and inner class DefaultSuggestionDisplay to override moveSelectionDown() and moveSelectionUp() to explicitly call popup.setScrollTop().

In order to do this I need access to the absolute top of the currently selected MenuItem therefore need access to SuggestionMenu which is also an inner class of SuggestBox which is private and declared as a private member within DefaultSuggestionDisplay without getter. Since GWT is a JavaScript we can't use reflection to access it.... Does anyone have a workaround for this issue?

Thanks.

like image 870
user_1357 Avatar asked Nov 21 '11 03:11

user_1357


2 Answers

I've been searching around and couldn't find a proper solution (apart from reimplementing SuggestBox). The following avoids reimplementing SuggestBox:

private static class ScrollableDefaultSuggestionDisplay extends SuggestBox.DefaultSuggestionDisplay {

    private Widget suggestionMenu;

    @Override
    protected Widget decorateSuggestionList(Widget suggestionList) {
        suggestionMenu = suggestionList;

        return suggestionList;
    }

    @Override
    protected void moveSelectionDown() {
         super.moveSelectionDown();
         scrollSelectedItemIntoView();
    }

    @Override
    protected void moveSelectionUp() {
         super.moveSelectionUp();
         scrollSelectedItemIntoView();
    }

    private void scrollSelectedItemIntoView() {
        //                                     DIV          TABLE       TBODY       TR's
        NodeList<Node> trList = suggestionMenu.getElement().getChild(1).getChild(0).getChildNodes();
        for (int trIndex = 0; trIndex < trList.getLength(); ++trIndex) {
            Element trElement = (Element)trList.getItem(trIndex);
            if (((Element)trElement.getChild(0)).getClassName().contains("selected")) {
                trElement.scrollIntoView();

                break;
        }
    }
}

}

like image 173
Perdi Estaquel Avatar answered Oct 08 '22 03:10

Perdi Estaquel


Following this discussion on Google groups, I implemented a similar solution which is a bit more concise due to the use of JSNI:

private class ScrollableDefaultSuggestionDisplay extends DefaultSuggestionDisplay {

    @Override
    protected void moveSelectionDown() {
        super.moveSelectionDown();
        scrollSelectedItemIntoView();
    }

    @Override
    protected void moveSelectionUp() {
        super.moveSelectionUp();
        scrollSelectedItemIntoView();
    }

    private void scrollSelectedItemIntoView() {
        getSelectedMenuItem().getElement().scrollIntoView();
    }

    private native MenuItem getSelectedMenuItem() /*-{
        var menu = this.@com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay::suggestionMenu;
        return [email protected]::selectedItem;
    }-*/;
}
like image 33
Jan Friedenstab Avatar answered Oct 08 '22 04:10

Jan Friedenstab