2011-06-07 69 views
3

有沒有人看到建議或自動完成TextArea GWT Widget?它不必與SuggestBox完全相同。在我開始自己開發之前,我只是在想那些東西已經存在了。GWT建議文本區域小部件

+0

你能澄清這個問題嗎?你想要的東西有點像com.google.gwt.user.client.ui.SuggestBox,但不同?以什麼方式? – gatkin 2011-06-07 14:15:35

回答

1

您也可能想查看Spiffy UI的多值自動完成程序。這是z00bs提到的自動完成器的更新版本,也是這個可重用框架的一部分。

2

有一個GWT庫here還有一個演示here

+0

我很抱歉有一篇文章討論像Facebook一樣http://raibledesigns.com/rd/entry/creating_a_facebook_style_autocomplete – msb 2011-06-07 14:59:59

+0

這裏還有一個演示應用程序http://demo.raibledesigns.com/gwt-autocomplete/ – msb 2011-06-07 15:01:51

+0

我更新了答案,我把正確的鏈接 – msb 2011-06-07 15:05:53

0

你試過傳遞TextAreaSuggestBox的構造? (鑑於TextArea延伸TextBoxBase

0

我覺得你可以使用「組合框」來表示。與隱藏箭頭,使該字段編輯..

0

在項目很久以前遙遠的地方,我寫的類,可能會有所幫助:

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

請原諒我糟糕的格式和俄語評論,但你應該明白主意。