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

Check out a demo of TextboxList before reading!

While working on my big and exciting new project, I decided to include an input that resembles the famous Apple Mail to: textfield. 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)

I created my own, MooTools 1.2 compatible, in just 5kb. It’s not only small, but also really frexible! Here are some notes of the creation process and how to implement it in your own projects.

Anatomy of the control

As usual, I try to come up with a semantic, unobstrusive approach. I start with the CSS and the markup that will be my end result.

I want to go from something like this:

  • to something like this (only one possible scenario, naturally)

    • Jorge Luis Borges
    • Julio Cortazar
  • Basically, it’s a group of pieces (that I’ll call bits), that can be either a box or an input (small, except for the main one). The user is able to move around between the bits by using his keyboard or his mouse.

    Javascript

    As far as the javascript goes, I try to first think about reusable code (usually classes) that I may use. I thus first coded the class that adds resizing capabilities to the small fields as the user types, and a small utility method to find the caret position.

    The only challenges I found was handling the complex events while keeping everything crossbrowser. Again, none of this would have been possible if it wasn’t for MooTools (1.2).

    Using it

    All you have to do is:

    new TextboxList('input-demo');
    

    Where input-demo is the id of the desired input to replace

    The constructor can take these options:

    • onInputFocus (event, fired when an input gets focus)
    • onInputBlur (event, fired when an input loses focus)
    • onBoxFocus (event, fired when a box gets focus)
    • onBoxBlur (event, fired when a box loses focus)
    • onBoxDispose (event, fired when a box is removed)
    • resizable (option, hash, passed to ResizableTextbox constructor)
    • className (option, string, prefix of the classnames of the generated objects)
    • extrainputs (option, boolean, adds small inputs between boxes if true)
    • startinput (option, boolean, adds a small input before the first box if true)
    • hideempty (option, boolean, hides the small inputs by default)

    Extending it

    One of the my favorite features of MooTools is how easily you can create and extend classes. It makes you feel in a truly Object-Oriented environment, overcoming all Javascript limitations and complexities to handle functionalities like this by default.

    I decided that, for the sake of simplicity, the class would not incorporate stuff like boxes removal through clicks, or even autocompletion (like Facebook does), since the scenarios to use this control are multiple and diverse.

    Here is an example of how easily you can add the small remove links next to the name (and some CSS, of course)

    var FacebookList = new Class({
    
    Extends: TextboxList,
    
    	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)
    			}
    		}));
    		return li;
    	}
    
    });
    

    Changelog

    • 0.1: initial release
    • 0.2: code cleanup, small blur/focus fixes

    Download

    Click here to download a zip file containing examples, TextboxList documented (8kb) and compressed (5kb)

    New! TextboxList with autocompletion

    62 Comments

    Boris said

    Nice script ! Congrats’ !

    Davis said

    Sweet!!!

    Great code for the great Mootools library :)

    Richard said

    Fantastic!! mootools too I love it :)

    Any chance I could get a port of the script for Moo 1.1, the project I am currently working on was going to use some 1.2 scripts but the compatibility package on Moo’s site wasn’t compatibilizing :) the way it should in many cases. Pleaseeeee!!!!

    Thanks a mil!

    Guillermo Rauch said

    @Daniel
    I don’t plan on supporting 1.11. However, it shouldn’t be hard to do it yourself.

    mediodia said

    He llegado gracias al blog de Anieto2k…Me ha parecido un gran trabajo el tuyo, pero para ser la primera vez que me acerco al mundo mootols, me pierdo bastante a la hora de hacer una cosa muy basica para poder importar tu script a mi herramienta…

    ¿Crees sencillo que pudiera implementar un autocomplete dinamico haciendo llamadas al servidor si el patron de busqueda no aparece en el primer fichero cargado?

    A la hora de hacer submit del formulario, bajo que “name” aparecen los elementos que se añaden? Supongo que existe la manera de poder pasar el contenido el “text” de los nodos por debajo de class=”feed” al text cuyo id es “facebook-demo” , pero no consigo ver el modo…

    Saludos y gracias de todos modos por tu esfuerzo

    Matt said

    Hi there,

    json.html is a static file and is giving me a 405 error under IIS 5.x as the POST method is not allowed for text/html by default.

    If I change the extension to json.asp and alter the file name to json.asp in test.js it works OK.

    …. is this an acceptable workaround or should I reconfigure IIS ?

    { Thanks Guillermo for a great library ]

    Guillermo Rauch said

    Matt
    Whatever URL data comes from is fine! json.html is only intended as an example.

    Right on! And good job keeping the code clean too.

    Great work, what if I want to make it with single select?

    Chaffe said

    Greetings, I wrote a class to extend the TextBoxList class, and I’m in need to run some function onBoxDispose. I uncommented the onBoxDispose: $empty, option in the TextBoxList class and wrote a function in my new class onBoxDispose: function(){//mystuff}, but for some reasons, it’s not getting run when the box is disposed. what am I missing here? Thanks.

    Chaffe said

    Guillermo, any word of advice on the question above?

    Will said

    the TextboxList is very cool~!

    jason said

    tested and works a treat! thanks

    Kim Steinhaug said

    Really cool! It does however throw some errors in IE7 when testing the demo, some small try catch would solve it I know, just wanted to mention it. As Im sitting on a developer machine with script debugger on the forced error popup really gets you, :D

    Great work!

    mark said

    If you want this working with mootools 1.2 (the newer, non-beta one), only a few changes are necessary.
    You can get it here:
    http://www.learningtoshred.com/js/textboxlist.js

    This version also lets you “auto tag” when entering text in the last text entry (it does not do this if you enter text in the small text inputs between the tags).
    When typing in the box, if you hit the space key it will turn that previous word into a new tag. If you want another key to trigger this instead of space (such as comma), then pass the ascii code of the character with the option ‘autoTagSeparator’.

    - mark

      M1 said

      Mark, in your autoTag function you’ve incorrectly checked to see if this.autoTag is true, rather that this.options.autoTag. I replaced the first line by removing it to after ‘a’ is set, and returning false but also setting the value of a[0] to an empty string, so when autotag is off and they hit the autoTag key, it just empties the text input.

      autoTag:function(){
      var a=this.maininput.getChildren(‘input’);
      if(!this.options.autoTag){
      a[0].set(‘value’,”);
      return this;
      }
      if(!a.length)return this;
      var b=a[0].get(‘value’);
      if(!b.length)return this;
      while(b.substr(b.length-1,b.length)==String.fromCharCode(this.options.autoTagSeparator))b=b.substr(0,b.length-1);
      if(!b.length)return this;
      this.add(b);
      a[0].set(‘value’,”);
      return this
      }

    mark said

    Also, fixed a bug in dispose() that prevented you from removing the first element if you were using the startinput:false, extrainputs:false options.

    Luke said

    This is a really clean extension for an interface, but what it seems to lack (quite remarkedly) is a clear example or handle for this plugin to be used when interacting with an actual form.

    You can select names from the list and they are shown in the field, all nice and Facebook-y, but when you submit the form they do nothing. Also, there is no clear way to allow for the JSON resource to be extended so as to have a displayed text value and a hidden actual value (kind of like OPTION tags in a SELECT set – where they can be labelled “Apple” but have a value of “23″, etc.)

    With these small additions, this would certainly become my plugin of choice in place of bulky SELECTs, or rows upon rows of buttons.

    What does this line of code do? It’s in the test.js file Line: 35

    arguments.callee.parent(element, options);

    It’s not recognizable by Mootools 1.2.

      Martijn said

      Change it to: this.parent(element, options);

    Guillermo Rauch said

    Replace it with
    this.parent(element, options);

    Karina said

    Hi there,

    This is a really cool tool, thank for sharing.
    I have a question though, How can I save the data entered in the input field? I added a “name” to the input but still when I submit the values and check on my database it isn’t saving. Forgive me if this seems to be a basic question but I’m new in Mootools and I don’t know if there is some extra code that I need to add when using this tool. Am I missing something here?

    Ruben Ortiz said

    Hello, i am testing in Windows Server 2003 and not working but in Debian Linux this work. Request config special?

    Thank you, great script.

    Hi,
    I’ve a question regarding Auto completer.
    I contact mail and name with angular braces.
    If I use the emails are discard. e.g. kaushanipal.
    It will be ok if I usr &lt and &gt in place of respectively. But in text box if I type
    g or l the &gt or &lt is showing. Please help me.

    nunzio said

    Hi, i like a lot your script… thank you

    cicekci said

    çiçekçi thecicekci supports script

    eljot said

    Hy, Guillermo! The script fort he autocompletion works great. I have made some changes to use it with moo 1.2.2 and it works great. But I am no able to get the content of the ‘autocompleted’ field submitted. Have you an idea? Greetings from Austria.

    Here is the source of my form.

    Ausgebüter Beruf oder ausgebüte Berufe…

    Bitte hier … eingeben …

    Joe Cabe said

    Has anyone implemented this in ASP.Net?

      andrew said

      hi Joe, have you managed to get it working in asp.net yet?

    Radjiv said

    Great work, je suis fan (i speak a litle english)
    After submit, how in php, i have list of username ?

    Radjiv said

    How empty the list with javascript? (with a button for exemple)

    biggy said

    Hi, very nice script I’m wonder if it’s possible to merge exemple 2 and 3, I mean autocomplete + add a new item with coma ? thanks

    ver nice script and useful , thanx

    milan said

    nice script but how to get the input empty?! does someone knoow?:S

    sandrar said

    Hi! I was surfing and found your blog post… nice! I love your blog. :) Cheers! Sandra. R.

    Nice example of web application integrated to the social media. Really hot nowadays. Thanks

      ewrsd said

      Keep up your blog, very useful ;) thanks

    David said

    Hi
    very very nice! Thank you!
    But I’m confused ’bout how to start with an empty input?
    Because, when loading the js, the input-box is already filled with elements.
    I tried document.getElementById(inputbox).value=””; and many more ways… no solution =(
    Can u give me a hint please :)?

    Ian Qvist said

    I saw some guys asking for a demo in ASP.net, so I decided to create a simple demo that shows off the TextboxList using a JSON auto-completion written in C#:

    http://ianqvist.blogspot.com/2009/12/facebook-style-autocomplete-textbox-in.html

    Raman said

    Very coollllllll

    jagadeesh said

    all them are done but i don’t get that value add the name how can we get in php

    foreverextend said

    Here is fully customizable ASP.NET auto complete control (AJAX facebook like and more functionality):

    http://www.simplified.com/ControlDemo.aspx

    foreverextend said

    Here is fully customizable ASP.NET auto complete control (AJAX facebook like and more functionality):

    http://www.simp.lified.com/ControlDemo.aspx

    Kiran said

    Hi, i have worked on this mootool am able to display my data base dat in your autosuggest box, but when i try to submit the details am not able get the values from auto text box. Could you please help me…

    my code is….

    Simple input

    FacebookList input

    Type the name of an argentine writer you like

    Thanks Inadvance..

    Pedro Pereira said

    Hi, is possible to get this working in IE9??
    Thanks in advanced…

    faraz said

    How would we retrieve the data after the form is submitted??

    Your thoughts?

    About Guillermo Rauch:

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