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
-
can u tell me how i can get the selected value in php to insert into database of user selection.
because the field name is not working for me.
When i add a Submit button and try to get Date ($_GET/$_POST) empty string i find.
Can u help me. thanks -
como te jodio el flaco que te copio el plugin!!!
-
Quisiera saber si se necesita alguna configuracion especial para que funcione en un servidor LINUX, gracias por cualquier ayuda.
-
Good Demo!!!
-
Hi, I am considering paying to this on one of my clients sites but i need it to work in Swedish. Anyone who knows how to add suport for letters: “å”, “ä”, “ö”?
-
I was looking for an autosuggest style dropdown that could be used in two scenarios: first, for a search box like Google Suggest/Facebook search/OS X Spotlight search; second, for a taglist-style box accepting multiple values. Textboxlist seems a good solution, but I’ve come across a few problems in TextboxList.Autocomplete.js:
1. When a function was given in options.remote.extraParams, the line data[this.options.remote.param] = search; stopped working (‘data undefined’).
2. In search() I had to change
if(this.values.length) this.showResults(search);
to
if(this.values) {if(this.values.length) this.showResults(search);}
to prevent ‘this.values is null’ error when deleting characters from a search phrase to make the currently displayed search results invalid.3. Instead of search() being called directly on keypress events, I modified the code to run an intermediate method that only runs search() after a delay, to prevent too many requests to the server for remote requests.
searchTimeout:false,
searchIfRightTime: function(bit)
{
if(this.searchTimeout) clearTimeout(this.searchTimeout);
this.searchTimeout = setTimeout(function(){this.search();}.bind(this), 250);
},PS The ‘LOAD PRIOR 50 COMMENTS’ link on this page doesn’t appear to be working (Safari 4)
-
I like how you have the floating clouds on this page…how did you do that?
-
Looks great, but I cannot get it to work. I am trying to use the jquery version with autocomplete and am having an issue. When I type a few characters in the input field and then click on one of the matches, I get a bug in Firebug that says “m is undefined”. And no selection appears up in my input field. Any ideas as to what might be happening? It feels like I may have initialized the plug-in incorrectly, but I can’t see what’s wrong.
-
thankl you very good.
-
You plugin seems pretty sweet, but the test in the download isn’t working. Its throwing a JS error of “j is undefined” from line 170 of test.js It won’t do any auto-complete functionality unless you delete the predefined values and search specifically for them.
-
If someone has resolvde how to get the box empty and not auto with all this stuff you write in, msg me pls ! I will pay for resolve this problem! Mail @ milan.andjelkovic@hotmail.com
-
If someone has resolvde how to get the box empty and not auto with all this stuff you write in, msg me pls ! I will pay for resolve this problem!
-
I have a problem.
This scripts work fine in my case.
But, I was wondering. I just need ONE entry(with autocompletion, of course), and not the hability to select a lot of inputs.. .. how can I do it?
Andy idea? -
no good because have only one text , i want multi text ?
var tlist1 = new FacebookList(‘userlist1′, ‘user-auto’);
var tlist2 = new FacebookList(‘userlist2′, ‘user-auto’);….
only one Request.JOIN …. I see not ok -
:-(,
-
Увлекательно. Некоторые моменты не знал.
-
So I have a database with about 8,000 entries (minimum, this is subject to grow). Naturally I don’t want to have a PHP file read the entire contents of the database and send back all 8,000 items to be cached and used in the auto-suggest. That’s just ridiculous. Rather, I’d prefer to select only those entries which begin with whatever the user has already typed (so if you type “aut”, it will turn up things like “automobile”, “automatic”, “autism”, etc)
I could do this if instead of sending the data to json.html it were sent to json.php?tag=aut, however I don’t know how to get the content of the input box while it’s still being edited. Help would be appreciated.
-
Nevermind. Found the solution in your more recent project.
http://devthought.com/projects/mootools/textboxlist/
Autosuggest has a url and param request. With those I can do everything I need.
-
-
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?
-
How in the world do you get this working with mysql????
want it to pull data from database not JSON.HTMLplease help!!!!
-
-
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/-
backspace doesn’t work with mootools 1.2.3.
-
-
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.
-
one day ago I had not noticed the backspace bug too, because my page (send new message) is opened in a new tab and thus the browser has no way to back to the previous page.
after I sent a new message, the script back to the same page with a short sentence notifying the user that message has been sent. Here I re-use the page again by pressing enter in the address bar, now the page has chance to back to the previous page and the backspace bug can happen.
-
-
How do to put nothing in input field at starting ?
-
It pass ! sorry my question was untils
-
hi Thomas, i am facing same problem , please let me know how did you solved it
Advance thanks
raki -
this is th tstin messag thi in th sn thirh owhorihwoihrowhorh oiwhroi
-
-
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
-
Million thanks, very useful information and it works perfectly.
-
-
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
-
hey dude, could i please get the fix for mootools 1.2?
i hope it addresses my problem.. cos i cant get the autocomplete to work with barackslides on the same index file. seems to be some conflict. thanks!
-
-
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
-
Hi Christian
I am looking for same thing , just wondering if you have found any solution please .If you manage to find one please let me know rikmon1 at gmail dot com
Regards
raki -
Hey guyes.
I am looking for same thing , just wondering if you have found any solution please .
If you manage to find one please let me know milan.andjelkovic@hotmail.com
Regards
-
mensaje xx