TextboxList meets Autocompletion

In my previous blogpost I explained how to extend TextboxList to add closing functionality via a link added to each box. But it was missing an important ingredient: autocompletion!
Again, all we have to do is extend the TextboxList class, override some methods, some events, and create some new ones (all prefixed by auto)
Click here to see Javascript code
var FacebookList = new Class({Extends: TextboxList,data: [],options: {onInputFocus: function() { this.autoShow(); },onInputBlur: function(el) {el.value = '';this.autoHide();},onBoxDispose: function(item) {this.autoFeed(item.$attributes.$text);},autocomplete: {'opacity': 0.8,'maxresults': 10,'minchars': 1}},initialize: function(element, autoholder, options) {arguments.callee.parent(element, options);this.autoholder = $(autoholder).set('opacity', this.options.autocomplete.opacity);this.autoresults = this.autoholder.getElement('ul');var children = this.autoresults.getElements('li');children.each(function(el) { this.add(el.innerHTML); }, this);},autoShow: function(search) {this.autoholder.setStyle('display', 'block');this.autoholder.getElements('*').setStyle('display', 'none');if(! search || ! search.trim() || (! search.length || search.length < this.options.autocomplete.minchars )){this.autoholder.getElement('.default').setStyle('display', 'block');this.resultsshown = false;} else {this.resultsshown = true;this.autoresults.setStyle('display', 'block').empty();this.data.filter(function(str) { return str ? str.test(search, 'i') : false; }).each(function(result, ti) {if(ti >= this.options.autocomplete.maxresults) return;var el = new Element('li').set('html', this.autoHighlight(result, search)).inject(this.autoresults);el.$attributes.$result = result;if(ti == 0) this.autoFocus(el);}, this);}},autoHighlight: function(html, highlight) {return html.replace(new RegExp(highlight, 'gi'), function(match) {return '<em>' + match + '</em>';});},autoHide: function() {this.resultsshown = false;this.autoholder.setStyle('display', 'none');},autoFocus: function(el) {if(! el) return;if(this.autocurrent) this.autocurrent.removeClass('auto-focus');this.autocurrent = el.addClass('auto-focus');},autoMove: function(direction) {if(!this.resultsshown) return;this.autoFocus(this.autocurrent['get' + (direction == 'up' ? 'Previous' : 'Next')]());},autoFeed: function(text) {if(this.data.indexOf(text) == -1)this.data.push(text);},autoAdd: function(el) {if(!el || ! el.$attributes.$result) return;this.add(el.$attributes.$result);delete this.data[this.data.indexOf(el.$attributes.$result)];this.autoHide();this.current.$attributes.$input.value = '';},createInput: function(options) {var li = arguments.callee.parent(options);var input = li.$attributes.$input;input.addEvents({'keydown': function(e) {e = new Event(e);this.dosearch = false;switch(e.code) {case Event.Keys.up: return this.autoMove('up');case Event.Keys.down: return this.autoMove('down');case Event.Keys.enter:this.autoAdd(this.autocurrent);this.autocurrent = false;this.autoenter = true;break;default: this.dosearch = true;}}.bind(this),'keyup': function() {if(this.dosearch) this.autoShow(input.value);}.bind(this)});input.addEvent(Browser.Engine.trident ? 'keydown' : 'keypress', function(e) {if(this.autoenter) new Event(e).stop();this.autoenter = false;}.bind(this));return li;},createBox: function(text, options) {var li = arguments.callee.parent(text, options);li.addEvents({'mouseenter': function() { this.addClass('bit-hover') },'mouseleave': function() { this.removeClass('bit-hover') }});li.adopt(new Element('a', {'href': '#','class': 'closebutton','events': {'click': function(e) {new Event(e).stop();if(! this.current) this.focus(this.maininput);this.dispose(li);}.bind(this)}}));li.$attributes.$text = text;return li;}});window.addEvent('domready', function() {// initvar tlist2 = new FacebookList('facebook-demo', 'facebook-auto');// fetch and feednew Request.JSON({'url': 'json.html', 'onComplete': function(j) {j.each(tlist2.autoFeed, tlist2);}}).send();});
It works by caching all the results from a JSON Request and feeding them to the autocompleter object. When a item is added as a box, it’ removed from the feed array, and when the box is disposed it’s added back, so that it becomes available in the list when the user types.
Another new feature is that you’ll be able to let it add boxes from the HTML directly:
<label>FacebookList input</label><input type="text" value="" id="facebook-demo" /><div id="facebook-auto"><div class="default">Type the name of an argentine writer you like</div><ul class="feed"><li>Jorge Luis Borges</li><li>Julio Cortazar</li></ul></div>
The constructor now takes new parameters to configure the autocompletion, like the minimum number of characters to trigger the dropdown, and more.
Changelog
- 0.1: initial release
- 0.2: added click support, removed $attributes use, code cleanup
Download
Click here to download the zip with code and examples
Tags: on January 12th, 2008
March 6th, 2008 at 1:53 pm
Great script, I will for shure use it in my future projects.
March 3rd, 2008 at 1:40 pm
[...] an input that resembles the famous Apple Mail to: textfield? It would be something similar to Facebook List Input. Basically, it’s a group of pieces or bits, that can be either a box or an input. The user is [...]
March 1st, 2008 at 4:25 pm
[...] Facebook benzeri otomatik tamamlama scripti. Bağlantı [...]
February 29th, 2008 at 9:50 am
Hi I am very much interested in this work . I am from a java background and we use DWR not JSON(and I am not familiar with JSON ). I need to understand this piece of code that I have pasted here.
new Request.JSON({’url’: ‘json.html’, ‘onComplete’:
I have also downloaded the sample demo and found that it contained a file named “json.html’ which contained a string array. How can I integrate this with DWR? or else If I am going to use jason wuts the step that I need to take to integrate it with my code . CURRENTLY i AM GETTING THE DB DATA VIA DWR TO MY CLIENT SIDE AND I AM ABLE TO PRINT THE RELEVANT DATA USING “alerts”"”
February 29th, 2008 at 8:06 am
[...] Facebook Style Input BoxThe approach to re-create the autocomplete method of adding multiple recipients to messages used on Facebook. “I’d seen it in Facebook before, which has a really decent implementation of this concept (it work well, but it doesn’t respect any modern programming principles; basically, it’s a big tag soup with lots of inline Javascript)” [...]
February 29th, 2008 at 8:06 am
[...] Facebook Style Input BoxThe approach to re-create the autocomplete method of adding multiple recipients to messages used on Facebook. “I’d seen it in Facebook before, which has a really decent implementation of this concept (it work well, but it doesn’t respect any modern programming principles; basically, it’s a big tag soup with lots of inline Javascript)” [...]
February 27th, 2008 at 4:08 pm
[...] TextboxList meets Autocompletion [...]
February 25th, 2008 at 4:14 pm
Hey All,
Love the script. Yet, I have a problem. I am new to Java and I have no idea how to ‘call the update()’ function, does anyone have an example of how this is done? Sure I can figure it out if I just can see how it’s done.
Thanks!
February 25th, 2008 at 4:12 pm
Does anyone have an example of how to use update function (new to java…). Any example will do, I’m sure I can figure it out, just don’t know where to start on this one.
Thanks!
February 24th, 2008 at 11:04 pm
nevermind i got update to work.
February 24th, 2008 at 10:42 pm
i tired using the update function, it works for default values, but after trying to input something, list2.bits gets whatever was in the autocomplete list, instead of what is in the textboxlist. Any solution?
February 23rd, 2008 at 4:20 pm
I have the same issue like Brian. However, it seems there is no support or advice here. If someone of you knows the answer could you please help us. I believe many people here have the same problem.
February 22nd, 2008 at 6:27 am
The autocomplete is a very wonderful tool. However, the problem is adding a value that does not exist in the autocomplete list to the input box. if for example Im using it for a intramail whereby users can send mails to each other within a site and the autocomplete lists out users who are already in the member’s friend list, what happens if he also wants to send to a member who is not in his friend’s list? I was thinnking thst typing in the value and pressing enter will do the trick but it doesnt. Tested on IE7 and Opera9
February 18th, 2008 at 6:32 pm
I still can’t figure out how to pull values using the update function.
I set the onsubmit=”tlist2.update()” for a button in my form, but it doesn’t do anything. It seems to be something simple that I’m missing. Could anybody please shed some light?
February 17th, 2008 at 3:13 pm
very nice script.
However, I am trying to insert the selected options into the DB and can’t get it work. What do I need to do?
working with php/mysql
thanks in advance