Как автоматически прокрутить GWT SuggestBox с max-height и overflow-y: scroll

Как я могу автоматически прокрутить GWT SuggestBox с максимальной высотой, установленной на PopupPanel держа SuggestBox? В настоящее время, когда пользователь нажимает клавиши "вверх" и "вниз", стили изменяются в предложенных элементах, а нажатие клавиши "Ввод" выбирает текущий выбранный элемент в списке.

Когда элемент расположен ниже полосы прокрутки максимальной высоты, он не прокручивается. Я пытался расширить SuggestBox и внутренний класс DefaultSuggestionDisplay переопределить moveSelectionDown() а также moveSelectionUp() явно позвонить popup.setScrollTop(),

Для этого мне нужен доступ к абсолютной вершине текущего выбранного MenuItem поэтому нужен доступ к SuggestionMenu который также является внутренним классом SuggestBox, который является закрытым и объявлен как закрытый член в DefaultSuggestionDisplay без добытчика. Поскольку GWT - это JavaScript, мы не можем использовать отражение для доступа к нему.... У кого-нибудь есть обходной путь для этой проблемы?

Благодарю.

3 ответа

Я искал вокруг и не мог найти правильное решение (кроме переопределения SuggestBox). Следующее избегает переопределения 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;
        }
    }
}

}

После этого обсуждения групп Google я реализовал похожее решение, которое является более кратким из-за использования 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 menu.@com.google.gwt.user.client.ui.MenuBar::selectedItem;
    }-*/;
}

Хорошо, я наконец нашел решение. Мне пришлось создать свой собственный ящик для подсказок, основанный на реализациях GWT SuggestBox. Но следуйте ниже в пользовательской реализации: - Поместите ScrollPanel в PopupPanel, затем поместите MenuBar в ScrollPanel. - В moveSelectionUp() и moveSelectionDown() вашей новой внутренней реализации SuggestionDisplat добавьте код ниже:

 panel.ensureVisible( menu.getSelectedItem( ) );

Это не достижимо путем расширения SuggestBox, так как у нас не будет доступа к выбранному MenuItem, если только не будет переопределен защищенный метод getSelectionItem() как открытый метод.

Наконец добавьте CSS:

max-height: 250px;

Для popupPanel в ваших реализациях дисплея.

Другие вопросы по тегам