Search code examples
javascriptjavawebsocketspark-java

Websocket autocompletion shows weird behaviour


I have a text input with an eventlistener that will send the current value to a server via websocket. The server then answers with a json array of matches. The matches will be appended to a div below the input and event listeners will be added to them, so that they change the input's value when clicked. However what I am getting is: typing a single letter completes the text without clicking any a element in the div. Additionally I become unable to change the text (e.g. remove characters).

Following is my code:

var webSocket = new WebSocket('ws://' + location.hostname + ':' + location.port + '/autoComplete');
var searchbox = document.getElementById('searchbox');
var suggestions = document.getElementById('suggestions');

webSocket.onmessage = function (event) {
    var results = JSON.parse(event.data);

    var html = '';
    for(var result of results) {
        html += '<a href="#" class="completer">' + result + '</a> ';
    }

    suggestions.innerHTML = html;
    updateCompleterActions();
};

webSocket.onopen = function(event) {
    searchbox.addEventListener('input', function() {
        webSocket.send(searchbox.value);
    });
};

webSocket.onclose = function(event) {
    clearInterval(window.refresher);
};

var updateCompleterActions = function() {
    var elems = document.getElementsByClassName('completer');

    for(var elem of elems) {
        elem.addEventListener('click', setSearchboxText(elem.innerHTML));
    }
}

var setSearchboxText = function(value) {
    searchbox.value = value;
    for(var elem of elems) {
        elem.removeEventListener('click');
    }
}

Following is the serverside code:

@OnWebSocketMessage
public void message(Session s, String message) throws IOException {
    // TODO: implement DB access here
    List<String> words = Arrays.asList("Auto", "Baumhaus", "Peter", "fahren");
    List<String> matches = new ArrayList<>();

    for(String word : words) {
        if(word.contains(message)) {
            matches.add(word);
        }
    }

    s.getRemote().sendString(gson.toJson(matches));
}

How can I achieve that only a click will change the text of the input and fix the inability to change text afterwards (without using jQuery)?


Solution

  • You are calling the setSearchboxText function, not setting it as a callback.

    change your

    elem.addEventListener('click', setSearchboxText(elem.innerHTML));
    

    to

    elem.addEventListener('click', function(e) {
        setSearchboxText(this.innerHTML);
    });