2

I have following code that needs something smart to deal with typed in chars and detection:

private final MultiWordSuggestOracle mySuggestions = new MultiWordSuggestOracle();
private final Set<String> mySuggestionsData = new HashSet<String>();

@UiHandler("suggestBox")
public void onKeyPress(KeyDownEvent event) {
    if (Character.isLetterOrDigit(event.getCharCode())) {
        char[] text = suggestBox.getText().trim().toCharArray();
        if (text.length != 1) return;

        for (char ch : text) {
            if (!Character.isLetterOrDigit(ch)) {
                return;
            }
        }
        //load data from server into mySuggestionsData
    }     
}

The question has 3 parts:

  1. How do you test pressed key against alphanumeric chars. Keep in mind this is GWT so I would rather not use regex ( but if there is no other option ...).

  2. What is the best way to detect the length of text typed into the SuggestBox?

  3. Is KeyDownEven the best choise? And why is it triggered twice when any key is pressed?

MatBanik
  • 24,206
  • 38
  • 107
  • 172

2 Answers2

1

1. I'd use KeyPressHandler instead of Up/Down handler.

As far as I understand, you are more interested to get what the user has typed but not the key that was actually pressed on the keyboard. Also, you can use Character.isDigit(c) and Character.isLetter(c) since KeyPressEvent.getCharCode() will return char (c).

2. Likely you want to check text length at some point (e.g. when user presses Enter), then

// handler block
if (c == KeyCodes.KEY_ENTER) {
    int length = ((SuggestBox) event.getSource()).getText().length();
    // take an action depending on length
}
// handler block continued

should fit.

3. See [1] and perhaps it's browser specific.

Edit: [1],[2] and [3] combined (using KeyUpHandler):

private static final int THREASHOLD = 2;
private String phrase = "";
...
    searchBox.addKeyUpHandler(new KeyUpHandler() {
        @Override
        public void onKeyUp(KeyUpEvent event) {
            String text = ((SuggestBox) event.getSource()).getText();
            if (!phrase.equals(text)) {
                if (text.length() >= THREASHOLD) {
                    boolean alphanum = true;
                    for (int i = 0; i < THREASHOLD; i++) {
                        char c = text.charAt(i);
                        if (!Character.isDigit(c) && !Character.isLetter(c)) {
                            alphanum = false;
                            break;
                        }
                    }
                    if (alphanum) {
                        //RPC (won't be called twice)
                    }
                }
                phrase = text;
            }
        }
    });
barti_ddu
  • 9,504
  • 1
  • 41
  • 49
  • @Mat Banik: uff, i totally missed the title. Then yes, i don't know of other way than attaching KeyUp handler; will update the answer in a minute.. – barti_ddu Jun 06 '11 at 18:52
  • @Mat Banik: `As far as browser specific GWT takes care of that` - i wouldn't be so sure (especially regarding keypress/keydown event handling); hope update is of some value to you anyway. – barti_ddu Jun 06 '11 at 19:36
  • @Mat Banik: this looks like your case: http://code.google.com/p/google-web-toolkit/issues/detail?id=3533 (also, it is known that some browsers on some platforms fire keyUp/Down event twice) – barti_ddu Jun 07 '11 at 13:37
1

Instead of handling events, you should make your own SuggestOracle (possible wrapping a MultiSuggestOracle used as an internal cache) and check the query's length and "pattern" there to decide whether to call the server or not (and then give an empty list of suggestions as the response, or maybe a single suggestion being the exact query).

As a side note, I don't understand why you don't want to use a regex; either using the java.lang.String methods taking a regex as a String, or the com.google.gwt.regexp.shared.RegExp class.

Thomas Broyer
  • 63,827
  • 7
  • 86
  • 161
  • Somewhere in your code: `static final RegExp AT_LEAST_TWO_ALPHANUMS = RegExp.compile("^[a-zA-Z0-9]{2,}$");` then when you need to check whether it matches: `if (AT_LEAST_TWO_ALPHANUMS.test(request.getQuery())) ...` – Thomas Broyer Jun 07 '11 at 13:11