TextboxList meets Autocompletion

TextboxList Autocompletion

Demo here

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)

Click here to see Javascript code

  1. var FacebookList = new Class({
  2.  
  3. Extends: TextboxList,
  4.  
  5. data: [],
  6.  
  7. options: {
  8. onInputFocus: function() { this.autoShow(); },
  9. onInputBlur: function(el) {
  10. el.value = '';
  11. this.autoHide();
  12. },
  13. onBoxDispose: function(item) {
  14. this.autoFeed(item.$attributes.$text);
  15. },
  16. autocomplete: {
  17. 'opacity': 0.8,
  18. 'maxresults': 10,
  19. 'minchars': 1
  20. }
  21. },
  22.  
  23. initialize: function(element, autoholder, options) {
  24. arguments.callee.parent(element, options);
  25. this.autoholder = $(autoholder).set('opacity', this.options.autocomplete.opacity);
  26. this.autoresults = this.autoholder.getElement('ul');
  27. var children = this.autoresults.getElements('li');
  28. children.each(function(el) { this.add(el.innerHTML); }, this);
  29. },
  30.  
  31. autoShow: function(search) {
  32. this.autoholder.setStyle('display', 'block');
  33. this.autoholder.getElements('*').setStyle('display', 'none');
  34. if(! search || ! search.trim() || (! search.length || search.length < this.options.autocomplete.minchars ))
  35. {
  36. this.autoholder.getElement('.default').setStyle('display', 'block');
  37. this.resultsshown = false;
  38. } else {
  39. this.resultsshown = true;
  40. this.autoresults.setStyle('display', 'block').empty();
  41. this.data.filter(function(str) { return str ? str.test(search, 'i') : false; }).each(function(result, ti) {
  42. if(ti >= this.options.autocomplete.maxresults) return;
  43. var el = new Element('li').set('html', this.autoHighlight(result, search)).inject(this.autoresults);
  44. el.$attributes.$result = result;
  45. if(ti == 0) this.autoFocus(el);
  46. }, this);
  47. }
  48. },
  49.  
  50. autoHighlight: function(html, highlight) {
  51. return html.replace(new RegExp(highlight, 'gi'), function(match) {
  52. return '<em>' + match + '</em>';
  53. });
  54. },
  55.  
  56. autoHide: function() {
  57. this.resultsshown = false;
  58. this.autoholder.setStyle('display', 'none');
  59. },
  60.  
  61. autoFocus: function(el) {
  62. if(! el) return;
  63. if(this.autocurrent) this.autocurrent.removeClass('auto-focus');
  64. this.autocurrent = el.addClass('auto-focus');
  65. },
  66.  
  67. autoMove: function(direction) {
  68. if(!this.resultsshown) return;
  69. this.autoFocus(this.autocurrent['get' + (direction == 'up' ? 'Previous' : 'Next')]());
  70. },
  71.  
  72. autoFeed: function(text) {
  73. if(this.data.indexOf(text) == -1)
  74. this.data.push(text);
  75. },
  76.  
  77. autoAdd: function(el) {
  78. if(!el || ! el.$attributes.$result) return;
  79. this.add(el.$attributes.$result);
  80. delete this.data[this.data.indexOf(el.$attributes.$result)];
  81. this.autoHide();
  82. this.current.$attributes.$input.value = '';
  83. },
  84.  
  85. createInput: function(options) {
  86. var li = arguments.callee.parent(options);
  87. var input = li.$attributes.$input;
  88. input.addEvents({
  89. 'keydown': function(e) {
  90. e = new Event(e);
  91. this.dosearch = false;
  92. switch(e.code) {
  93. case Event.Keys.up: return this.autoMove('up');
  94. case Event.Keys.down: return this.autoMove('down');
  95. case Event.Keys.enter:
  96. this.autoAdd(this.autocurrent);
  97. this.autocurrent = false;
  98. this.autoenter = true;
  99. break;
  100. default: this.dosearch = true;
  101. }
  102. }.bind(this),
  103. 'keyup': function() {
  104. if(this.dosearch) this.autoShow(input.value);
  105. }.bind(this)
  106. });
  107. input.addEvent(Browser.Engine.trident ? 'keydown' : 'keypress', function(e) {
  108. if(this.autoenter) new Event(e).stop();
  109. this.autoenter = false;
  110. }.bind(this));
  111. return li;
  112. },
  113.  
  114. createBox: function(text, options) {
  115. var li = arguments.callee.parent(text, options);
  116. li.addEvents({
  117. 'mouseenter': function() { this.addClass('bit-hover') },
  118. 'mouseleave': function() { this.removeClass('bit-hover') }
  119. });
  120. li.adopt(new Element('a', {
  121. 'href': '#',
  122. 'class': 'closebutton',
  123. 'events': {
  124. 'click': function(e) {
  125. new Event(e).stop();
  126. if(! this.current) this.focus(this.maininput);
  127. this.dispose(li);
  128. }.bind(this)
  129. }
  130. }));
  131. li.$attributes.$text = text;
  132. return li;
  133. }
  134.  
  135. });
  136.  
  137. window.addEvent('domready', function() {
  138. // init
  139. var tlist2 = new FacebookList('facebook-demo', 'facebook-auto');
  140.  
  141. // fetch and feed
  142. new Request.JSON({'url': 'json.html', 'onComplete': function(j) {
  143. j.each(tlist2.autoFeed, tlist2);
  144. }}).send();
  145. });

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:

Click here to see HTML code

  1. <label>FacebookList input</label>
  2. <input type="text" value="" id="facebook-demo" />
  3. <div id="facebook-auto">
  4. <div class="default">Type the name of an argentine writer you like</div>
  5. <ul class="feed">
  6. <li>Jorge Luis Borges</li>
  7. <li>Julio Cortazar</li>
  8. </ul>
  9. </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

118 Responses to “TextboxList meets Autocompletion”

Pages: « 8 7 6 [5] 4 3 2 1 » Show All

  1. 75
    Martin Says:

    Great script, I will for shure use it in my future projects.

  2. 74
    Facebook List TextboxList with AutoCompletion | GreatSo.com Says:

    [...] an input that resembles the famous Apple Mail to: textfield? It would be something similar to Facebook List Input. Basically, it’s a group of pieces or bits, that can be either a box or an input. The user is [...]

  3. 73
    Fatih Hayrioğlu’nun not defteri » 01 Mart 2008 web’den seçme haberler Says:

    [...] Facebook benzeri otomatik tamamlama scripti. Bağlantı [...]

  4. 72
    sanath Says:

    Hi I am very much interested in this work . I am from a java background and we use DWR not JSON(and I am not familiar with JSON ). I need to understand this piece of code that I have pasted here.

    new Request.JSON({’url’: ‘json.html’, ‘onComplete’:

    I have also downloaded the sample demo and found that it contained a file named “json.html’ which contained a string array. How can I integrate this with DWR? or else If I am going to use jason wuts the step that I need to take to integrate it with my code . CURRENTLY i AM GETTING THE DB DATA VIA DWR TO MY CLIENT SIDE AND I AM ABLE TO PRINT THE RELEVANT DATA USING “alerts”"”

  5. 71
    Best Of February 2008 | Best of the Month | Smashing Magazine Says:

    [...] Facebook Style Input BoxThe approach to re-create the autocomplete method of adding multiple recipients to messages used on Facebook. “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)” [...]

  6. 70
    Best Of February 2008 | Best of the Month | Smashing Magazine Says:

    [...] Facebook Style Input BoxThe approach to re-create the autocomplete method of adding multiple recipients to messages used on Facebook. “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)” [...]

  7. 69
    CSSgallery.info » ajax autosuggest or autocomplete Says:

    [...] TextboxList meets Autocompletion [...]

  8. 68
    Jan Says:

    Hey All,
    Love the script. Yet, I have a problem. I am new to Java and I have no idea how to ‘call the update()’ function, does anyone have an example of how this is done? Sure I can figure it out if I just can see how it’s done.

    Thanks!

  9. 67
    Jan Says:

    Does anyone have an example of how to use update function (new to java…). Any example will do, I’m sure I can figure it out, just don’t know where to start on this one.
    Thanks!

  10. 66
    ian Says:

    nevermind i got update to work.

  11. 65
    ian Says:

    i tired using the update function, it works for default values, but after trying to input something, list2.bits gets whatever was in the autocomplete list, instead of what is in the textboxlist. Any solution?

  12. 64
    Bobby Says:

    I have the same issue like Brian. However, it seems there is no support or advice here. If someone of you knows the answer could you please help us. I believe many people here have the same problem.

  13. 63
    Opeyemi Obembe Says:

    The autocomplete is a very wonderful tool. However, the problem is adding a value that does not exist in the autocomplete list to the input box. if for example Im using it for a intramail whereby users can send mails to each other within a site and the autocomplete lists out users who are already in the member’s friend list, what happens if he also wants to send to a member who is not in his friend’s list? I was thinnking thst typing in the value and pressing enter will do the trick but it doesnt. Tested on IE7 and Opera9

  14. 62
    Brian Says:

    I still can’t figure out how to pull values using the update function.

    I set the onsubmit=”tlist2.update()” for a button in my form, but it doesn’t do anything. It seems to be something simple that I’m missing. Could anybody please shed some light?

  15. 61
    fedi Says:

    very nice script.

    However, I am trying to insert the selected options into the DB and can’t get it work. What do I need to do?

    working with php/mysql

    thanks in advance

Pages: « 8 7 6 [5] 4 3 2 1 » Show All

Leave a Reply