IT IS HERE! Get Smashing Node.JS on Amazon Kindle today!
Show Posts
← Back to homepage

TextboxList turns normal textboxes into a widget which can be navigated with the keyboard, effectively turning your input into a “list” of items that can be easily deleted. It comes with an Autocomplete plugin.



Click here to see it in action.


You can use and modify TextboxList freely for any non-commercial use. Otherwise you need to purchase a one-time per-domain license of $20, by clicking on the link on the right.


Click here to purchase

Browsers support

TextboxList has been tested and is officially supported on IE6, IE7, IE8, Firefox, Safari and Chrome. You may report bugs concerning other browsers, but they’ll get a lower priority.

How to use

TextboxList is essentially very easy to use, but is extremely configurable and extensible. Let’s review some sample usage scenarios:


This turns the <input id="form_tags_input"> into a TextboxList widget. By default, as shown in the demo, the user can add new boxes by pressing enter, write between boxes, delete them with backspace and delete keys. Additionally, a delete button is shown in each of the added items. All these behaviors can be configured, as shown in the sections below.

var t = new $.TextboxList('#form_tags_input');
t.add('Tag 1').add('Tag 2').add('Tag 3');

In this example we call the public add() method of the TextboxList instance to add items from JavaScript.

The anatomy of TextboxList

This section will be useful for those interested in customizing the default behavior of TextboxList, extending the main classes or writing their own plugins.

The parts that constitute a TextboxList widget are called bits. These parts have common characteristics: they can be focused, blurred, deleted, hidden, they are a fragment of the overall value, etc. TextboxList has two essential bits: the editable and the box bit.

Some options involved in the behavior and appearance of the widget are specific to the editable bits, and some are specific to the box bits, which are separate classes from TextboxList ((Even though they are separate classes and you can instantiate them from your code, usually you’ll want to use the add or create methods.)). To easily pass them from the main class, you use the bitsOptions property. For example, to disable the delete button in boxes bits, and use the shift key for adding items instead of the enter key:

$('#form_tags_input').textboxlist({bitsOptions: {
    box: {deleteButton: false},
    editable: {addKeys: Event.Keys.shift}

Knowing this gives you more customization power. If you want to target the blur event of any bit, attach a onBitBlur listener. If you want to target boxes, you can use onBitBoxBlur. You can see a complete list of options and events at the bottom of this page.

The anatomy of a bit

Each bit has a value of the format [id, plaintext, html]. For boxes, this can mean that one that says “John Doe” really passes the value “3” when making a POST. And it even allows you to customize the content of the box by using a different HTML representation. The id and html, however, are optional, like shown in the first example above. We called add() with just the plain text, and not an id or html, which are the second and third arguments of the method ((If we had wanted to add an item with an id 31 and html, we could have done t.add(‘Entry’, 31, ‘<img src=”some_entry_image.png” /> Entry’); )).

There’s TextboxListBit class deals with the creation, focusing, blurring, removal and display of the bits, and communicates with the main class by firing events/callbacks. There’re still many tasks that have to be taken care of by the TextboxList class, such as making sure the name of bits doesn’t exceed the value the user specified with the max option.


Autocompletion is another chapter in the TextboxList story. Again, if you plan to use Autocompletion, it’d be wise to read the sections above.

Autocomplete (like other plugins) is initialized like this:

var t = new $.TextboxList('#input_id', {plugins: {autocomplete: {options}});

You can then access the TextboxList.Autocomplete instance from the plugins property:

var autocomplete = t.plugins['autocomplete'];
// autocomplete.someMethod();

The autocompleter plugin is independent of the datasource. In order for autocompletion to be enabled, you have to supply a valid array of would-be bits by calling setValues(). The searches are performed on the bit plain text.

// continues from the last example
  [31, 'Bit Plain Text', 'Bit html', 'Suggestion item html'],
  // ...

Autocompletion: querying the server as the user types

The autocomplete can also query the server as the user types. When the user types at least as many characters as specified by the minLength option, a XHR request is performed to the server, which has to respond with a subset of results in JSON.

$('#form_tags_input_4').textboxlist({unique: true, plugins: {autocomplete: {
	minLength: 3,
	queryRemote: true,
	remote: {url: 'autocomplete2.php'}

Binary search is a very efficient searching algorithm which you can use by including the TextboxList.Autocomplete.Binary.js file and passing the method: 'binary' option to the Autocomplete plugin:

new $.TextboxList('#input_id', {plugins: {autocomplete: {method: 'binary'}}});

Only use it under these conditions:

  • You have many values to filter
  • The values array is sorted alphabetically
  • You can afford searching only the beginning of the strings

The method works by first locating the first match of the user input in the values. As an example, if we search for ‘z’ in the demo, it takes linear, standard filtering 62 tries to determine there’re no results. For binary search, it takes 6.

Since binary search was conceived to find a single match, what the filtering method does is look up and down through the array for other matches and come up with a list of suggestions.

Custom styling

Please refer to the comments in TextboxList.css and TextboxList.Autocomplete.css for style customization guidelines.



  • prefix (default to ‘textboxlist’) Prefix of the HTML classes of the different parts of the widget.
  • max (defaults to null) If set to a value other than null or false, a maximum number of boxes that can be added.
  • unique (defaults to false) If set to true, an id (or plain text if id not present) of a bit can’t be repeated.
  • uniqueInsensitive (defaults to true) If set to true and an id is not present for a bit, the check for a repeated plain text disregards case.
  • endEditableBit (defaults to true) Whether an editable bit at the end of the widget is added by default.
  • startEditableBit (defaults to true) Whether an editable bit can be added to the left of the first box (ie: beginning of the widget)
  • hideEditableBits (defaults to true) Whether to hide editables bit that are not currently focused
  • inBetweenEditableBits (defaults to true) Whether to add editable bits between to boxes
  • keys (defaults to left key and right key) An object consisting of a previous and next key whose values are event codes for moving to previous and next bits.
  • plugins (defaults to {}) An object with maps a plugin name and its options, for initialization. The plugin name is camelcased and capitalized to find the class ((If you pass plugins: {‘some-plugin': {}} it’ll try to initialize TextboxList.SomePlugin))
  • encode A function that turns an array into the string that is sent along with the form. The default takes the values, filters out commas and comma-separes them. Tip: you can use JSON here (JSON.stringify)
  • decode Does the opposite of encode. Used when initializing textboxlist, which tries to read values from the element. The default looks for commas to split the string. Tip: you can use JSON here (JSON.parse)


Events are managed like this:

t.addEvent('focus', fn); // bind focus event to fn
t.removeEvent('focus', fn); // remove focus event
t.fireEvent('focus', fn); // fire focus event (advanced use only)

This is an extension I made for jQuery to resemble MooTools events management. The main reason for this is that TextboxListBit classes communicate with TextboxList through an internal layer of events, which means a standard single-callback system is not enough.

  • focus: when the widget is focused
  • blur: when the widget is blurred
  • bitFocus: when a bit is focused. Passes the bit object as parameter
  • bitBlur: when a bit is blurred. Passes the bit object as parameter
  • bitAdd: when a bit is added. Passes the bit object as parameter
  • bitRemove: when a bit is removed. Passes the bit object as parameter
  • bitBoxFocus: when a box bit is focused. Passes the bit object as parameter
  • bitBoxBlur: when a box bit is blurred. Passes the bit object as parameter
  • bitBoxAdd: when a box bit is added. Passes the bit object as parameter
  • bitBoxRemove: when a box bit is removed. Passes the bit object as parameter
  • bitEditableFocus: when a editable bit is focused. Passes the bit object as parameter
  • bitEditableBlur: when a editable bit is blurred. Passes the bit object as parameter
  • bitEditableAdd: when a editable bit is added. Passes the bit object as parameter
  • bitEditableRemove: when a editable bit is removed. Passes the bit object as parameter

Public Methods

  • create (klass, value, options) Creates a bit of class klass, with value value and options options. Returns the bit
  • focusRelative (dir, element) Moves the focus to the dir (previous, next) element of the element element, if supplied. Otherwise it uses the current element
  • focusLast Focuses the last bit
  • add (plain, id, html, afterEl) Adds a box bit with value [id, plain, html], and injects it after the last available box, unless afterEl is supplied.
  • getOptions Retrieves the current set options for the instance.
  • getContainer Retrieves the container element, which is usually <div class="textboxlist">.
  • getValues Returns an array with the values from all the box bits.
  • setValues (values) Creates the box bits from the values array.
  • update (values) Updates the input with the values from getValues. This is done for you automagically, and is rarely needed.

Editable Bits Options

Refer to the bit anatomy section to see how to pass these.

  • tabIndex (defaults to null) Don’t set this option directly. Set the tabindex attribute to the original input
  • grows (defaults to true) Whether a GrowingInput instance is created for the input
  • growingOptions (defaults to {}) An options object passed to GrowingInput
  • stopEnter (defaults to true) Whether the event propagation is stopped when enter is pressed. Useful because enter triggers form submission
  • addOnBlur (defaults to false) Whether a box is added with the input content when the input is blurred.
  • addKeys (defaults to Event.Keys.enter) A key or array of keys that trigger adding a box with the input content.

Box Bits Options

Refer to the bit anatomy section to see how to pass these.

  • deleteButton (defaults to true) Whether a delete button is added in the box.

Autocomplete Options

Refer to the binary search section to see how to pass these.

  • minLength (defaults to 1) Minimum number of characters typed in to trigger search.
  • maxResults (defaults to 10) Maximum number of results to display.
  • insensitive (defaults to true) Whether to perform a case-insensitive search
  • highlight (defaults to true) Whether to highlight results.
  • highlightSelector (defaults to null) Optionally, A CSS3 selector to determine on which elements of the autocomplete suggestion to perform highlighting.
  • mouseInteraction (defaults to true) Whether to allow mouse (hovering and clicking) interaction.
  • onlyFromValues (defaults to false) If set to true, the user can only pick values from the suggestions.
  • method (defaults to ‘standard’) Search/highlighting method defined in TextboxList.Autocomplete.Methods
  • placeholder (defaults to ‘Type to receive suggestions’) A placeholder text to display. If it evaluates to false, placeholder is not shown or inserted.

Autocomplete Public Methods

Refer to autocompletion section to see how to call these.

  • setValues (values) Seeds the autocompleter with suggestions from the values array.


  • 0.1: first release
  • 0.2
    • Autocomplete adding with click bugs
    • Unique indexes bugs on IE (which lacked native array.indexOf)
    • Bugs with how options were being extended
  • 0.3: width calculations for growing inputs corrected.
  • 0.4
    • [FEATURE] Autocompletion with on-demand server querying
    • [ENHANCEMENT] All classes moved to $. to avoid global namespace pollution.
    • [FEATURE] Easier jQuery-friendly initialization
    • [BUGFIX] GrowingInput now works in noConflict mode
    • [BUGFIX] Fix for GrowingInput to handle special characters and correctly calculate the input length.
    • [BUGFIX] Fix for support of multiple addKeys
    • [BUGFIX] Fix for focus problem when TextboxList gains focus through focusing an editable input
    • [BUGFIX] Autocomplete search term is now trimmed (thanks Mike Feng)
    • [BUGFIX] Fix for the .max option


Hi, I would like to download this plugin..
Where is it available ?

Anonymous said

@Guilherme not sure either, of where the source is :(

Magnus said

Guilherme, thanks for a super plugin! One thing though, I noticed there is a problem with the remove icon, not triggering events handlers added with textboxlist.addEvent. Both backspace and delete keys when inside the container element work fine.

Is this a bug you intend to fix? I’m using IE 8.0.7600.16385..

    Magnus said

    A little correction: the ‘x’ icon does indeed trigger ‘bitRemove’ event handler (myFunction), that is attached using textlistbox.addEvent(‘bitRemove’, myFunction). But when using the option ‘unique: true’, the textboxlist doesn’t register that the bit was removed. It does however, when using backspace and delete.

    When the next call to textboxlist.add() is done, the bitAdd event never triggers..

Samed said

fcbkcomplete v2.7.5 better than this? i can’t use TextboxList multiple in same page, but i use fcbkcomplete without any error (for now) prefix is just for styling, i think you should a selector for multiple uses

Arvind said

I am trying to run copying the Source code, saving as html, copying css and js files, but this feature is not working, I am not sure, what am i missing. any Help would be great, Thanks and advance.

Saygley said

hi, thanks for the gorgeous work; we really appreciate the effort.
however, it has problems with special characters such as turkish character “ı” (little i without a dot).
If my finding is correct, I think it would be nice to improve the script by using html encoding for the user input in the script and decoding it in server side, so that these kinds of specials would have been taken care of..

    Saygley said

    btw this comment is for autocomplete feature. cheers!

      ahmet said

      türkçe karakter sorununu bulduysan çözümü yazarmısın rica etsem?

Cyngus106 said

anyone manage to get the spinner.gif working properly or the “please wait” text??

Thanh Binh said

Some drawbacks:
1. After delete a tagged item, auto completed showed all items including items has tagged.
2. Add duplicate tagged items because case 1 occur.

I fixed them. Can I contribute my code to fix this problem exists?

    Hogy said

    Can you please post your code here? I too noticed this issue!

    Atif Dastgir said

    Can you please post your code here as i’m facing the same problem.


Bonatoque said

Does a CSS guru have a hint on how to make the autocomplete results appear ABOVE the input, and not below ?

Lib3Ns said

Hi I bought the script… but I want to know if it’s possibile to clear after I submit the request


Lib3Ns said

i’d like to know if it’s possible to set up the function of auto-complete pushing down additional characters such as @ | + –

Declan said

Hey, is it possible to append extra strings to already created “bits”. May that be by directly interacting with a bit by clicking on it so the user is able to expand that bit with extra information or allowing the user to continue typing after selecting the correct option from auto complete.

From the example picture in this article. If I wanted to append “Foo” to the end of the “John Doe” bit, I click on it that bit and it allows me to update that bit with “Foo”. Same for when selecting from auto complete.

Thanks in advance,


PS. Super awesome plugin btw :P

Crilla86 said

Hey, it is possible to use the TextboxList.js with an other autocomplete plugin, like jquery autocomplete plugin? I’m interesting to the functionality of TextboxList.js but i’m already using the jquery autocomplete.

Navotera said

can u give me the autocomplete.php files so i can exacly learn how to set the JSON array for TextBoxList…

it’s great.. Thanks anyway 

Lance said

There are two example php files in the demo

Steven said

Going to point out — jQuery is open-source. Don’t release something you don’t intend on being free… don’t release it to anyone, lol. Just sayin’   — decent work though.

cde said

The best in class for this type of widget is for Ext:

If you’re using jQuery, this is as good as it gets, which is too bad, because it’s still not usable for a commercial site. Autocomplete is broken on IE. Tabbing behavior is awkward. The setValues() method is not public as documented. You can only add values to the widget, not replace or clear them. It hasn’t been maintained by the author for over a year. On the other hand, it is only $20 and there’s no restrictions on modifying it.

It’d be nice if it could be refactored as a jQueryUI widget, then it’d be more extensible.

Mo said

Awesome job!

One question, after clicking a suggestion and making it a tag, autocomplete shuts off and doesn’t poll the server anymore for suggestions.

How can I fix this?

Ni said

How can I make it so tags can have commas in them? Example, so you can have a tag with “Star Wars, A New Hope”

Ni said

You have an error in your code pertaining to commas. In TextboxList.js, the line:

return chk(v) ? v.toString().replace(/,/, ”) : null;

Needs to be

return chk(v) ? v.toString().replace(/,/g, ”) : null;

So it’ll replace ALL the commas with a blank.

Tung Nguyen said

I have a error at “decode: function(o){ return o.split(‘,’); }” in TextboxList.jsError: o is undefined. Please help me!

Will this ever get updated to work with jQuery 1.6+? I have a site that
uses this and other plugins and we need to update to the latest version
of jQuery for some of the other plugins to work correctly, but this is
one thing holding us back.

Will this ever get updated to work with jQuery 1.6+? I have a site that
uses this and other plugins and we need to update to the latest version
of jQuery for some of the other plugins to work correctly, but this is
one thing holding us back.

Rafael B. said

So, how does one get a hold of you or make this payment? I don’t see the link, and can’t find your email to ask!

You can use and modify TextboxList freely for any non-commercial use. Otherwise you need to purchase a one-time per-domain license of $20, by clicking on the link on the right.

Christian Ranebäck said

Someone should fix this bug… is this the correct fix?
Autocomplete with non acii chars?

Gökalp Turan said

I do not want motools. I would like to jquery. Would you please send the download link to jquery?

Nic Wolff said

I guess the current version isn’t on GitHub either? I paid for a license, it’d be nice to be able to contribute fixes back…

Anyway, if you’re using Autocomplete but you’d like to allow the Enter key to propagate up and submit the form, change the code at line 187 of Textboxlist.Autocomplete.js to

case 13: if (current && current.length) { evStop(); addCurrent(); } else if (!options.onlyFromValues){ evStop(); var value = currentInput.getValue(); var b = textboxlist.create(‘box’, value); if (b){ b.inject(currentInput.toElement(), ‘before’); currentInput.setValue([null, ”, null]); } }

Vincent Osmont said

Great job !

Can this plugin be forked ?
I’ve made some improvements and transform it in a jQuery UI widget.

I don’t understand your licence, especially as you seem to have end your support : can you make it opensource now ?.

Rqx110 said

Add validate the inputs method please~

    Rqx110 said

    I have add myself!  if someone want to get the code, please email me to get it. rqx110[at]

Sander said

I like it, very handsome!

Nazar Hussain said

Its really great. Thanks for such a wonderfull open source thing.

Tessemeze said

User can make empty tags without text.
Is it bug or feature?

Tarun Sood said

When I trying to use it, I am getting error like

Options is not defined
TextBoxList is undefined

any solution?? How I can get rid off this problem

shovan said

The plugin is wonderful to use and such a nice plugin as an open source is awesome.

I had an issue with using this plugin as I want to use this plugin for every textbox present in my form. The textbox are dynamically generated with a different id but same class. How can I use this plugin for dynamic generated textbox. How can I resolve this issue?

Willie said

Very nice. I do have a question with autocomplete. I use a remote URL to populate. The problem is that the user will type in ROO and the backend will send a list of all values starting with ROO which is fine. For every extra character the backend is queried again while not needed.

Jordan said

Hi Guillermo,

Another thing. I’m trying to use the addOnBlur option that is listed in your api, but am running into a problem. When i blur the input and have no value in my edit input, it’s creating an empty tag anyway. I’ve added a conditional statement to the toBox function, to make sure that value[1] is not !== ”. I know this is a little hacky, and would love a better solution. Thanks for your help.

Roger said

The enter key, left/right arrows, backspace, delete to navigate dont work with Mootools 1.4.5!

Ali AlManqur said

To make this tool working on IE9 , you need to update the mootools.js file with assets ,

You can Download it from

joa said

this is fuck*ing mootols!!! not jquery, sucks!

Your thoughts?

About Guillermo Rauch:

CTO and co-founder of LearnBoost / Cloudup (acquired by Automattic in 2013). Argentine living in SF.