I am looking for a good way to create an autocomplete. Searching the website did not provide a good example. I had to turn to the reposearch repo (using reposearch) to find this example:

form {
    <div class="ui-widget">
        input(query)[autocomplete="off", id="searchfield", onkeyup=updateResults()]
        submit action{return search(namespace,query);} {"search " output(namespace)}
    </div>    
}  

action updateResults(){
    if(query.length() > 0){  		  		
        searcher := toSearcher(query,namespace); //update with entered query	      
        replace(resultAndfacetArea, paginatedTemplate(searcher, 1, namespace));	    
        //HTML5 feature, replace url without causing page reload
        runscript("window.history.replaceState('','','" + navigate(doSearch(searcher, namespace, 1) ) + "');");
    } else {
        clear(resultAndfacetArea);
    }
}

placeholder resultAndfacetArea{
    if (query.length() > 0){
        paginatedTemplate(searcher, pageNum, namespace)
    }
}

Using this as inspiration, I created the following:

define editTags(conv : Conversation) {
    var tags: Set<Tag> := conv.tags
    list[class="tags"] {
        for(tag : Tag in tags) {
            if(!(tag.name in {"Inbox", "Sent mail", "Trash"})) {
                listitem[style:=getTagStyle(tag)]{output(tag.name) section[onclick=removeTag(tag)]{" [x]"}}
            }
        }
    }
    
    action removeTag(tag : Tag) {
        conv.tags.remove(tag);
        conv.save();
    }
}

However, clicking the [x](which should invoke the “removeTag” action) does not do anything. Further inspection of the console shows the following error:

missing ; before statement
http://localhost:8080/hmail/javascript/ajax.js
Line 281

This is probably caused by the ‘eval’ statement trying to parse “Error: server received POST request but was unable to dispatch to a proper action” as JSON - it would be safer to use jQuery.parseJSON here by the way.

Anyway, instead of removing the conversation from the list, it does nothing. How do I get this to work?

Submitted by Daan Wilmer on 3 April 2012 at 01:16

On 3 April 2012 at 12:31 Elmer van Chastelet commented:

You can use a submitlink for your removeTag action (see manual). You probably need to put the submitlink in a template to workaround a bug in for-loops (see issue 368).

Regarding autocompletions, there is currently no built-in template you can use to get an autocompletion input field like on reposearch (if that’s what you want).
I don’t recommend it, but you might reuse the code on reposearch. We use a jquery javascript ui element to display the completions in reposearch. Important elements are highlighted [here](http://webdsl.org/reposearch/showFile/ns=reposearch&op=AND&q=id+searchfield+setupcompletion+includejs+includecss+autocompleteService&lim=10&dff=repo_path%2Cfile_ext%2C&type=Entry&dfp=200%2C120%2C&allowlcn=false&/1789f76f-f3a9-47ea-8a8c-fdebe2e73545#15, and you need completion.js. But you also need to modify some variables regarding the url’s, which include a namespace parameter in reposearch.

I personally recommend to just use a section with an ajax placeholder, which you replace with autocompletions from a searcher object.
In your case, retrieval of completions will probably look like this:

var completions := Tag completions matching name: userInput limit 10; //returns List<String>

Be aware that the search field you use for autocompletion (name in this example) needs to have the (autocomplete) annotation in search mapping, or autocomplete keyword when using searchable annotations. (see here for info regarding search mapping). Be also aware that the terms as they appear in the index are used for autocompletion, thus if the name property of Tag is indexed using the default analyzer, the tag names will be splitted on whitespaces, and thus autocompletion will only return single words. To fix this, add an additional search field in your mapping solely for autocompletion which doesn’t use an analyzer (stores the tag names untokenized, i.e. name using none as nameAC in your search mapping).

Log in to post comments