The Facebook autocomplete address to: field.
August 13th, 2008
We've extended the Autocomplete.Local from Scriptaculous to implement the autocomplete to: field mimicing the Facebook's features. This was a little challenging at the start, but prototype.js and scriptaculous have just made it so much easier.
Concepts
- json - array of contacts with names and email address and any other fields you wish to search
- The input box changes size dynamically and reposition itself according to the keystrokes
- Each 'token' created is an input field, submitting the id of the user or an email address
Straight to the source
Syntax
new Autocompleter.LocalAdvanced(id_of_text_field, id_of_div_to_populate, json_array, options) |
The constructor takes four parameters. The first two are, as usual, the id of the monitored textbox, and id of the autocompletion menu. The third is an array of strings that you want to autocomplete from, and the fourth is the options block.
Extra local autocompletion options
| Option | Default Value | Description |
|---|---|---|
search_field |
"name" | Which attribute to search in the json array. |
choices |
10 | How many autocompletion choices to offer |
partialSearch |
off | If false, the autocompleter will match entered text only at the beginning of strings in the autocomplete array. Defaults to true, which will match text at the beginning of any word in the strings in the autocomplete array. If you want to search anywhere in the string, additionally set the option fullSearch to true |
fullSearch |
false | Search anywhere in autocomplete array strings. |
partialChars |
2 | How many characters to enter before triggering a partial match (unlike minChars, which defines how many characters are required to do any match at all). |
ignoreCase |
true | Whether to ignore case when autocompleting |
Example
HTML
1 2 3 4 5 6 7 8 9 10 |
<div tabindex="-1" id="ids" class="clearfix tokenizer" onclick="$('autocomplete_input').focus()"> <span class="tokenizer_stretcher">^_^</span><span class="tab_stop"><input type="text" id="hidden_input" tabindex="-1"></span> <div id="autocomplete_display" class="tokenizer_input"> <input type="text" size="1" tabindex="" id="autocomplete_input" /> </div> </div> <div id="autocomplete_populate" class="clearfix autocomplete typeahead_list" style="width: 358px; height: auto; overflow-y: hidden;display:none"> <div class="typeahead_message">Type the name of a friend, friend list, or email address</div> </div> |
Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
(new Image()).src='/inbox/images/token.gif'; (new Image()).src='/inbox/images/token_selected.gif'; (new Image()).src='/inbox/images/token_hover.gif'; (new Image()).src='/inbox/images/token_x.gif'; var contacts = [ {name:"phoenix zhuang",email:"phoenix@rorcraft.com"}, {name:"jian xie",email:"jan.xie@rorcraft.com"}, {name:"isaiah peng",email:"isaiah.peng@rorcraft.com"}, {name:"chris chan",email:"chris.chan@rorcraft.com"}, {name:"rex chung",email:"rex@rorcraft.com"}, {name:"chung rex",email:"chung@rorcraft.com"}, {name:"chan chris",email:"chan@rorcraft.com"}, {name:"peng isaiah",email:"peng@rorcraft.com"} ]; var typeahead = new Autocompleter.LocalAdvanced('autocomplete_input', 'autocomplete_populate', contacts, { frequency: 0.1, updateElement: addContactToList, search_field: "name" }); var hidden_input = new HiddenInput('hidden_input',typeahead); |
CSS
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 |
/* autcompleter.advancedlocal css */
.tokenizer{min-height:5px;padding:0px 0px 3px 3px;width:100%;background:#fff;font-size:11px;}
.tokenizer_locked{background:#f4f4f4;}
.tokenizer,
.tokenizer *{cursor:text}
.tokenizer input{width:100%;}
.tokenizer .tokenizer_input,
.tokenizer .token{float:left;margin-right:3px;margin-top:3px;}
.tokenizer .tab_stop,
.tokenizer .tokenizer_stretcher{display:block;float:left;overflow:hidden;width:0px;}
.tokenizer .tab_stop{height:0px;}
.tokenizer .tokenizer_stretcher{padding-top:7px;}
#autocomplete_input{width:20px;}
#facebook .tokenizer .tab_stop input{border:0px solid black;display:inline;position:relative;left:-500px;}
#facebook .tokenizer .tokenizer_input_borderless {left:4px;margin-left:-1px;overflow:hidden;position:relative;}
#facebook .tokenizer_input_borderless #autocomplete_input{border:3px solid white!important;border-left:none;display:block;margin:-3px 3px -4px -2px;padding:0px!important;}
/*IE6-/Win only*/
/*\*/ * html#facebook .tokenizer_input_borderless #autocomplete_input { border:3px solid black;margin: -3px 3px -4px 14px:padding-left:10px; } /**/
.tokenizer div:-moz-first-node{padding-top:1px!important;}
.tokenizer_input{max-width:450px;overflow:hidden;padding:1px 0px;}
#facebook .tokenizer_input input,
.tokenizer_input_shadow{border:0px solid black;outline:0;font-family:'lucida grande', tahoma, verdana, arial, sans-serif;font-size:11px;padding:0px 5px;margin:0 0 -1px 0;white-space:pre;}
.tokenizer_input_shadow{display:inline;left:-10000px;position:absolute;top:-10000px;}
.tokenizer .tokenizer_input_shadow{height:0px;display:block;left:0px;overflow:hidden;position:relative;top:0px;}
div.tokenizer .token{background-image:url('/inbox/images/token.gif');background-repeat:no-repeat;color:black;white-space:nowrap;}
div.tokenizer .token span{background-image:url('/inbox/images/token.gif');background-position:top right;background-repeat:no-repeat;display:block;}
div.tokenizer .token span span{background-position:bottom right;}
div.tokenizer .token span span span{background-position:bottom left;}
div.tokenizer .token span span span span{background-image:none;padding:2px 3px 2px 5px;}
div.tokenizer.tokenizer_locked .token span span span span{padding-right:5px;}
html div.tokenizer_locked .token:hover,
html div.tokenizer_locked .token:hover span{background-image:url('/inbox/images/token.gif');}
div.tokenizer .token:hover,
div.tokenizer .token:hover span{background-image:url('/inbox/images/token_hover.gif');text-decoration:none;}
div.tokenizer .token_selected,
div.tokenizer .token_selected span,
div.tokenizer .token_selected:hover,
div.tokenizer .token_selected:hover span{background-image:url('/inbox/images/token_selected.gif');color:white;text-decoration:none;}
div.tokenizer .token span.x,
div.tokenizer .token span.x_hover,
div.tokenizer .token:hover span.x,
div.tokenizer .token:hover span.x_hover{background-image:url('/inbox/images/token_x.gif');background-position:4px 2px;cursor:pointer;display:inline;padding:0px 6px 0px 5px;}
div.tokenizer.tokenizer_locked .token span.x,
div.tokenizer.tokenizer_locked .token span.x_hover{display:none;}
div.autocomplete { position:absolute; width:355px; background-color:white; border:1px solid #888; margin-top:-2px; padding:0px;}
div.autocomplete ul { list-style-type:none;margin:0px; padding:0px;}
div.autocomplete ul li.selected { background-color: #ffb;}
div.autocomplete ul li { list-style-type:none; display:block; margin:0; padding:2px; height:32px;cursor:pointer;}
/* end of autcompleter.advancedlocal css */ |
Download the full source
Autocomplete_AdvancedLocal.zip
[update] We've forked a version of the control.js and changed all reference to element.style to setStyle(). It was causing script errors in IE.
http://github.com/rorcraft/scriptaculous/tree/master/src/controls.js
8 Responses to “The Facebook autocomplete address to: field.”
Sorry, comments are closed for this article.

August 20th, 2008 at 06:48 AM Nice. Any plans on being able to use a web service with this?
August 22nd, 2008 at 09:46 AM Wow, great piece of script. Is it possible to easily limitate the number of "tokens" that a user can add? BR Cedric
August 22nd, 2008 at 01:49 PM This would be useful if I could use JSON for options. Please consider make a Ajax version :-)
September 1st, 2008 at 03:38 PM Is it possible for this to be a Server Side request? instead of a hardcoded list of names?
September 2nd, 2008 at 02:58 PM Server side lookup would be ideal here :(
September 4th, 2008 at 05:20 PM Nice Rex. Did you issue a pull request for your style fix? As for the people asking for server side support, there's one here http://www.interiders.com/ but be aware that it spawns a lot of HTTP requests and is quite slow. You should rather try and cache your users in a JS file and work on that using this complete (IMO).
September 6th, 2008 at 06:16 AM is possible to trigger an event when an option from the list of possible options is selected (li.selected)
September 11th, 2008 at 02:50 PM How i get the values of all emails typed?