TextboxList meets Autocompletion
This post discusses a project which has its own page. Please refer to TextboxList for the most up-to-date information.

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)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | 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() { // init var tlist2 = new FacebookList('facebook-demo', 'facebook-auto'); // fetch and feed new 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:
1 2 3 4 5 6 7 8 9 | <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
-
dsfsdfs67877 test test
-
How can I get the Values from that textbox?
-
Hi, could someone help to add top image-base imaged pointer to the drop-down menu like Mootool Autosuggest has.
http://www.alainalemany.com/wp-content/uploads/2008/09/autosuggest2.jpg -
Great work but I can’t get it work with mootools 1.2
-
Hey, is there a possibility to just allow the objects in the json array to be intyped (and maybe email-addresses)?
-
Great script,
Is there a sample to put 2 input controls in one page, but the drop down values are different?
-
What you are trying to accomplish would be possible with 2 auto complete boxes… Think about it. If you are making calls to your database script to pull out some data, there is no other way to tell the script to change sql flags and pull something else while typing in the same box.
-
good
-
-
to make it compatible whit mootools 1.2, some change required
see http://forum.free.fr/autocomplete/ -
wow….great job, thanks a lot,
mantap abissss…….top markotop……….
-
Hi…
Great script, but i gone crazy…..
I need to place automatically the cursor inside the text field when u open page….
anyone know the way to do this?
tnx -
It’s really awesome script. I was really very much impressed with this code.
Is it possible to take the values from database instead of the html file…
-
You can do it by retrieving from you database the data you need, creating a php variable for example in this form ["var1","var2",...,"varn"] and then writing that in a HTML file. PHP example:
$fp=fopen(”json.html”,”w+”);
$i=0;
$contenido = “[";
while ($i<$veces){
$nombre = $listaMiembros[$i]['nombre'];
$contenido .= “\”$nombre”;
$apellido = $listaMiembros[$i]['apellido'];
$contenido .= ” $apellido”;
$id = $listaMiembros[$i]['id_miembro'];
$contenido .= ” $id\”";
if ($i != $veces -1 ){
$contenido .= “, “;
}
$i++;
}
$contenido .= “]”;
fwrite($fp,$contenido);
-
-
There are some serious problems with this component: first and foremost, hitting Backspace will first select and highlight the previous tag (this is good), but hitting backspace again will (instead of removing the selected tag as expected), perform a browser Back command, leaving the page and potentially losing all the information entered into the form!
Secondly, you should really accept auto-complete entries with the Tab key. This is my expected way auto-complete should be performed.
-
How do to put nothing in input field at starting ?
-
It pass ! sorry my question was untils
-
-
Great tool! Is it possible to connect it to a DB to take the values instead of the html? Thx
-
Hello, i am testing in Windows Server 2003 and not working but in Debian Linux this work. Request config special?
Thank you, great script.
-
I have tried to get a sql querry to work but I just cant make it work. Cant anyone who got it working please post a example .php file or text?
-
Hi!
Nice component, thanks. I have a small problem with it: How can I post values which are not in the autocomplete list?
Many thanks,
Atish -
Nice component
-
this is the error im am getting
j has no properties
[Break on this error] j.each(tlist2.autoFeed, tlist2); -
Hi,
I downloaded this code and when i execute the page i get javascript error
// fetch and feed
new Request.JSON({’url’: ‘json.html’, ‘onComplete’: function(j) {
j.each(tlist2.autoFeed, tlist2);
}}).send();So i am not able to run the code.. even the demo page URL given also gives thie error message..
Could you please help..
-
@Guillermo,
One small change I would love to see if you decide to commit the time to an update -
Immediately after the first item is entered, jump the cursor up 50px or so. This would be to prevent the first item from being a different color from the second (because the first item is normally being hovered over, given that the user just clicked on the input)
Hamy
-
@myself
lol - by some of the code listed here - I mean some of the code listed above my post
-
To correctly post / get the data using update
Note: some of the code listed here is not correct - it has a syntax error causing it to fail.
Here is what you need to edit -
Your form needs to have an ID and a NAME. I chose files_form
Your input also needs and id and a name. I used files.
If you are not to familiar with JavaScript, then you will need to add a submit button to the form like this:
Note that there is no need for an onClick
Now open the file originally titled test.js
Do a search for tlist2You will notice a line something like var tlist2 = new FacebookList(’files’, ‘facebook-auto’);
That first parameter needs to be the ID/name of your input divAfter you set that accordingly, place the cursor after the send();
Hit enter a few times to give yourself some roomPaste in this code
$(’files_form’).addEvent(’submit’, function () { tlist2.update(); } );The $(…) needs to contain the ID/NAME of your form. Note that the line I just pasted ends in a semicolon. The previous examples left that out, resulting in a syntax error and their code not working correctly.
If you are planning on submitting large amounts of data, then perhaps you should use post instead of get, by changing form method=”post”
Your data will be stored using the ID/NAME of the input tag. In my case, I can access my data using
$data = $_POST['files']The data is (by default) separated by ###. If you would like to change that, look for this in the textboxlist.js (or the compressed version): separator: ‘###’,
Hope that helps, and thanks for this awesome resource!
Hamy
-
Vey good works but very breakable with mootools 1.2.
I was using your js with mootools 1.2 with the fix indicated but still with the fix there are some problems.
When do you think you’ll update your js for mootools 1.2?
regards, Dario
-
Hello again,
i fixed the problem.
i saved as “json.asp” with encoding utf-8 and i changed all iso-8859-9 to utf-8 back in test.html =) -
Hello everyone,
i want use this, in my turkish project.
how can i use this with charset=”iso-8859-9″.i changed all “utf-8″ to “iso-8859-9″ in test.html but im still seing bad characters.
Thanks before.
-
I’m sorry I can’t spell. I meant to say:
I can’t get the input field data to post anywhere (using PHP or Javascript).
-
Hello there–
When I submit the form, where does the information go? I can’t get it to input field data to post anywhere (using PHP and Javascript). I’d like to use this awesome autocomplete feature on a messaging system.
-
Hi,
I have a question. i have 3 names picked from autocomplete. John, Audrey and Barret. I close Audrey. When i type A, the autocomplete doesn’t show Audrey anylonger. It seems that every name which has been picked and closed won’t display anymore in the autocomplete.
Instead of reupdate the json file, is there any function to recall what has been closed ?
Thanks before.
-
@ninja
Thanks for telling how to use update().I prefer to use return this.bits.getValues().join(this.options.separator). So the textboxlist.js not bounded to hidden element ($(’MESSAGEToNames’)) unless we put it as function parameter.
Simply var data = vlist.update(); this will return text with separator defined.
@itsik
Thanks for the fix for Mootools 1.2. It works
-
Hi.
Great script, like it alot!
But all the options are allready selected, I want to have a empty field and first when you select a “name” it will show up under the searchfield. Can anyone help me with this?
If do, please do send a mail to me ogkproduction @ gmail . com
-
@T.Mailrajan
@ulasJust upload the files to a webserver to empty the input content… and rename json.html to json.php or .asp
after that, you can use all the json data in json.php and clean up the input …Thanks to Guillermo Rauch for this script …
-
Has anyone modified the script (or is there an update coming at all) that will allow JSON objects to be used instead of JSON array? I need to pass back a name value pair, displaying the name but storing the value for posting back to the server.
Thanks
-
i need to fill Autocomplete TextBox dynamically while type a character inside that , the textbox is inside one Gridview cell… can anyone help me to resolve ?
-
Great Script!.
I was looking for something like this in jQuery, but I didn’t find anything.Thanks for sharing!
-
As In… Gets Data From JSON Link And Uses It
-
can someone please email the zip file of a working version of “TextboxList meets Autocompletion”
Sense my email is going in public, I’ll use one I rarely use…
Mail {@] hankweb {dot] comAlso, check out my site @ http://hankweb.com — I also have enabled AJAX IM at http://im.hankweb.com and social networking at http://my.hankweb.com
-
love the script - this is fantastic ..thank you!
-
Hi, nice script, too bad it doesn’t work for large database item. It crash if database more than 500 items
-
d76angt0b5341hx4
-
Hi,
The script is returning an error if there are more items in fetched.aspx file. There are around 5000 items in JSON format. This error is being fired in Internet Explorer 7.0. It worked well in Chrome.
Error: Stop Running this script?
A script on this page is causing Internet Explorer to run slowly. If it continues to run, your computer may become unresponsive.
Thanks,
Dheeraj -
hi, There are some parameters to that match the first letters of autocomplete?. thanks
-
Gracias por el codigo exelente
Saludos
—————————————-
http://www.joelcristobal.com -
How work the other parts of facebook, like adding a comment ?
-
If list more than specific number, can it be set to be scroll down, so list is not too long ??
-
That’s so cool.
-
how about a facebook footer navigation??? any example for it??
-
I’ve given up on this for auto-complete functionality. I recommend the Yahoo AJAX library, which is FAR more robust and configurable, with much more user support and documentation provided.
developer.yahoo.com/yui/autocomplete
-
Very Nice, thank you very much
Hi there!
i want to add the TypeWatch, a plugin that monitors the time between key strokes in a text input box with the textboxlist plugin.
Any idea how to do it?