Виджет GWT Suggest TextArea

Кто-нибудь видел виджет предложения или автозаполнения TextArea GWT? Он не обязательно должен быть таким же, как SuggestBox. Мне просто интересно, что уже существует, прежде чем я сам погрузюсь в разработку.


person MatBanik    schedule 07.06.2011    source источник
comment
Не могли бы вы прояснить вопрос? Вы хотите что-то вроде com.google.gwt.user.client.ui.SuggestBox, но другое? В каком смысле?   -  person gatkin    schedule 07.06.2011


Ответы (7)


Вы также можете воспользоваться функцией автозаполнения с несколькими значениями в Spiffy UI. Это более новая версия автозаполнения, упомянутая z00bs, и часть этой многоразовой структуры.

person Zack Grossbart    schedule 09.06.2011

здесь есть библиотека GWT, также есть демонстрация здесь

person msb    schedule 07.06.2011
comment
Мне жаль, что есть статья, в которой обсуждается что-то вроде facebook one raibledesigns.com/rd/entry/ - person msb; 07.06.2011
comment
здесь также есть демонстрационное приложение demo.raibledesigns.com/gwt-autocomplete - person msb; 07.06.2011
comment
@Mat Banik, тогда вам нужно разработать один, не помню, чтобы я встречал такой компонент раньше - person msb; 07.06.2011

http://www.zackgrossbart.com/hackito/gwt-rest-auto/ может быть тем, что вы ищете.

person z00bs    schedule 09.06.2011

Давным-давно в далеком-далеком проекте я написал класс, который может быть полезен:

public class SuggestTextArea extends TextArea {

private SuggestingPopupPanel suggestingPanel;
private SuggestTextArea textArea = this;

public SuggestTextArea(List<String> keywords) {
    super();
    suggestingPanel = new SuggestingPopupPanel(keywords, "suggestion");
    this.getElement().setAttribute("spellcheck", "false");

    this.addKeyPressHandler(new KeyPressHandler() {
        public void onKeyPress(KeyPressEvent event) {

            int charCode = event.getNativeEvent().getKeyCode();
            if (suggestingPanel.suggestingNow) {
                if (charCode == KeyCodes.KEY_ENTER || charCode == KeyCodes.KEY_TAB || event.getCharCode() == ' ') {
                    event.preventDefault();
                    suggestingPanel.insertCurrentKeyword();
                    return;
                }
                if (charCode == KeyCodes.KEY_DOWN) {
                    event.preventDefault();
                    suggestingPanel.panel.next();
                    return;
                }
                if (charCode == KeyCodes.KEY_UP) {
                    event.preventDefault();
                    suggestingPanel.panel.prev();
                    return;
                }
            } else {
                // Позиции естественно посчитаны не совсем верно
                int posX = textArea.getAbsoluteLeft();
                int posY = textArea.getAbsoluteTop() + 20 * getCurrentLines();
                suggestingPanel.setPopupPosition(posX, posY);
            }
            // Не предполагаем при удалении или смещении курсора
            if (charCode == KeyCodes.KEY_BACKSPACE || charCode == KeyCodes.KEY_LEFT || charCode == KeyCodes.KEY_RIGHT) {
                suggestingPanel.stopSuggesting();
                return;
            }
            // События с нажатым Ctrl не обрабатываем (ну почти)
            if(event.isControlKeyDown()){
                if(event.getCharCode() == 'v' || event.getCharCode() == 'V'){
                    suggestingPanel.stopSuggesting();
                }
                return;
            }
            suggest(event.getCharCode());
        }
    });
}

private int getCurrentLines() {
    // считает неверно если изменить размеры text area
    return (this.getText().length() / this.getCharacterWidth()) + 1;
}

// Добавляет указаные символы после курсора
private void insertCharacters(String insertion) {
    String text = this.getText();
    int cursorPos = this.getCursorPos();
    String res = text.substring(0, cursorPos) + insertion + text.substring(cursorPos);

    setText(res);
    setCursorPos(cursorPos + insertion.length());
    suggestingPanel.stopSuggesting();
}

private void suggest(char c) {
    // Отсекаем текст за курсором
    int cursorPos = this.getCursorPos();
    String text;
    text = this.getText().substring(0, cursorPos) + (c == 0 ? "" : c);

    if (text.length() == 0) {
        this.suggestingPanel.setVisible(false);
        return;
    }

    // получем вводимые символы
    String keys = "";
    RegExp pattern = RegExp.compile("\\b(\\w+)$", "gmi");
    for (MatchResult result = pattern.exec(text); result != null; result = pattern.exec(text)) {
        keys = result.getGroup(1);
    }
    if (!keys.equals("")) {
        suggestingPanel.showMatches(keys);
    }
}

// Панель для отображения предположений
class SuggestingPopupPanel extends PopupPanel {

    private boolean suggestingNow = false;
    private String suggestStyleName;
    private List<String> keywords;
    private Suggestions panel;
    private List<String> currentSuggestions;
    private String lastKeys;

    public SuggestingPopupPanel(List<String> keywords, String suggestStyleName) {
        super(true, false); // autohide, not modal
        this.keywords = keywords;
        this.suggestStyleName = suggestStyleName;

        setVisible(false);
    }

    public void insertCurrentKeyword() {
        insertCharacters(this.getKeywordEnd() + " ");
    }

    public String getKeywordEnd() {
        return currentSuggestions.get(panel.current).substring(lastKeys.length());
    }

    public String getKeywordEnd(int index) {
        return currentSuggestions.get(index).substring(lastKeys.length());
    }

    public void showMatches(String keys) {
        lastKeys = keys;
        // Получаем совпадения
        List<String> suggestions = new LinkedList<String>();
        RegExp pattern = RegExp.compile("\\b(" + keys + ")", "gmi");
        for (String keyword : keywords) {
            for (MatchResult result = pattern.exec(keyword); result != null; result = pattern.exec(keyword)) {
                suggestions.add(keyword);
            }
        }

        currentSuggestions = suggestions;

        if (suggestions.isEmpty()) {
            this.setVisible(false);
            suggestingNow = false;
        } else {
            suggestingNow = true;
            ArrayList<HTML> htmlList = new ArrayList<HTML>();
            for (String suggestion : suggestions) {
                String htmlText = HtmlHelper.getHtmlText(suggestion + "\n");
                htmlText = applyStyle(htmlText, keys);

                htmlList.add(new HTML(htmlText));
            }

            panel = new Suggestions(htmlList);
            this.setWidget(panel);

            this.setVisible(true);
            this.show();
        }
    }

    public void stopSuggesting(){
        suggestingNow = false;
        this.setVisible(false);
    }

    private String applyStyle(String text, String keys) {
        String regex = "\\b" + keys.toLowerCase();

        return text.replaceAll(regex, "<span class=\"" + suggestStyleName + "\">" + keys + "</span>");
    }

    // Отображает варианты
    class Suggestions extends VerticalPanel {

        String choosingName = "htmlFocus";
        List<HTML> variants;
        int current;

        public Suggestions(final ArrayList<HTML> variants) {
            if (variants.isEmpty()) {
                return;
            }

            this.variants = variants;
            current = 0;
            variants.get(current).addStyleName(choosingName);

            for (final HTML html : variants) {
                html.addStyleName("suggestVariant");

                // При нажатии дополняем соответсвующие символы
                html.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent event) {
                        textArea.insertCharacters(getKeywordEnd(variants.indexOf(html)) + " ");
                        stopSuggesting();
                    }
                });

                this.add(html);
            }
        }

        public void prev() {
            int prev = current - 1;
            if (prev < 0) {
                prev = variants.size() - 1;
            }
            variants.get(current).removeStyleName(choosingName);
            variants.get(prev).addStyleName(choosingName);
            current = prev;
        }

        public void next() {
            int next = current + 1;
            if (next == variants.size()) {
                next = 0;
            }
            variants.get(current).removeStyleName(choosingName);
            variants.get(next).addStyleName(choosingName);
            current = next;
        }
    }
}
}

Извините за плохое форматирование и русскоязычные комментарии, но вы должны уловить суть.

person SGP    schedule 23.10.2015

Вы пробовали передать TextArea конструктору SuggestBox? (учитывая, что TextArea расширяет TextBoxBase)

person Thomas Broyer    schedule 08.06.2011

На данный момент это мое любимое решение: http://jdramaix.github.com/gwtchosen/

person karlhungus    schedule 28.11.2012

Я думаю, вы можете использовать для этого "comboBox". скрыть стрелку и сделать поле доступным для редактирования.

person IbrahimAsad    schedule 28.11.2012