Mar 07 2010
Meio.Autocomplete – A Mootools Autocomplete Plugin
Download (Forge)
Meio.Autocomplete on Mootools Forge
Introduction
This plugin creates an autocomplete list of options at the bottom of an input text or textarea element. The list can be any other container that you like too. See the demos to understand it better.
Please don’t hesitated to ask anything. Feel free.
Dependencies
Meio.Autocomplete depends on Mootools-more Element.Forms. It’s included into the “/Assets” folder. There’s also a “BGIFrame.js” port into the “/Source” folder for solving the z-index issues with select and object elements on IE6. You just need to include it into your page for it to work together with Meio.Autocomplete.
Class: Meio.Autocomplete
Implements: Options, Events.
Meio.Autocomplete Method: Constructor
Syntax:
var myAutocomplete = new Meio.Autocomplete(element, data [, options, listInstance]);
Arguments:
- element – (mixed) A string ID of the Element or an Element to apply the Meio.Autocomplete List to.
- data – (mixed) An array of objects or a url to a page that will respond with a json object that will be converted to an array of objects.
- options – (object, optional) The Meio.Autocomplete options object
Options:
- delay – (number: defaults to 200) The delay before rendering the list of options. Usefull when you are using the autocomplete with ajax
- minChars – (number: defaults to 0) The minimum number of characters the user has to input before the list of options to select is shown.
- cacheLength – (number: defaults to 20) The cache length. Cache will decrease the number of ajax calls. Each time you make a different query it will be cached locally.
- cacheType – (string: defaults to ‘shared’) Can be ‘shared’ or ‘own’.
- ‘shared’ – The cache instance will be shared with other Meio.Autocomplete instances in the same page.
- ‘own’ – The Meio.Autocomplete instance will have its own cache.
- selectOnTab – (boolean: defaults to true) If the user press the ‘tab’ key, the current focused option will be selected.
- maxVisibleItems – (number: defaults to 10) Defines the height of the list. If its 10, for example, the list will have its height adjusted to show 10 options, but you can still scroll to the others.
- filter – (object) The filter options. Its posible to pass the filter functions directly or by passing a type and optionaly a path.
- type – (string: defaults to ‘contains’) If ‘contains’ is used, the items that contains the inputted text will be listed. If ‘startswith’ is used, only the items that starts with the inputted text will be listed. You can still define your own filter using the Meio.Autocomplete.Filter.define method, see the code to understand how it works.
- path – (string: default to ”) Should define the path to the text key into the objects that are in the data array. Ex: ‘a.b.c’ will get the ‘c’ key from the object {a: {b: {c: ‘some-text’}}}.
- filter – (function(text, data)) Filters the data array. It should return true if the ‘data’ should be listed while the passed ‘text’ is inputted in the field.
- formatMatch – (function(text, data, i)) This function should return the text that will be matched with the current inputted text into the field.
- formatItem – (function(text, data)) The return of this function will be applied to the ‘html’ of the li’s into the list.
- fieldOptions – (object) The options that are gonna be applied to the field element.
- classes – (object) Defines the classes that are applied to the field element you pass as first parameter to the Meio.Autocomplete constructor.
- loading – (string: defaults to ‘ma-loading’) Applied to the field when there is an Ajax call being made
- selected – (string: defaults to ‘ma-selected’) Applied to the field when there is a selected value
- classes – (object) Defines the classes that are applied to the field element you pass as first parameter to the Meio.Autocomplete constructor.
- listOptions – (object) The options that are gonna be applied to the list element.
- width – (mixed: defaults to ‘field’) Defines the width of the list. If ‘field’, the list will have the same width as the field. It’s possible to pass any other value settable by set(‘width’, value).
- classes – (object) Defines the classes that are applied to the list element.
- container – (string: defaults to ‘ma-container’) Applied to the container of the list.
- hover – (string: defaults to ‘ma-hover’) Applied to the focused ‘li’.
- odd – (string: defaults to ‘ma-odd’) Applied to the odd “li’s”.
- even – (string: defaults to ‘ma-even’) Applied to the even “li’s”.
- requestOptions – (object) The options that are gonna be applied to the Request.JSON instance (when using the Autocomplete with Ajax).
- formatResponse – (function: defaults function(jsonResponse){return jsonResponse;}) This function should return the array of autocomplete data from your jsonResponse.
- noCache – (boolean: defaults to true) The noCache option is setted by default to avoid cache problem on ie
- You can pass any of the Request.JSON options. http://mootools.net/docs/core/Request/Request.JSON
- urlOptions – (object) The options that are gonna be applied to the URL instance.
- queryVarName – (string: defaults to ‘q’) The name of the variable that’s going to the server with the query value inputed by the user.
- extraParams – (mixed: defaults to null) Can be an array of elements or objects with ‘name’ and ‘value’ keys. ‘value’ can be a function. Ex: if you pass [{'name': 'x', 'value': function(){ return 2; }}] the url generated to get the list of options will have the ‘x’ parameter with value ’2′. If it is an element or an object which its ‘value’ is a function, the value passed to the URL will be retrieved at the time the plugin makes the Ajax request.
- max – (number: defaults to 20) The max number of options that should be listed. This will be sent to the Ajax request as the ‘limit’ parameter.
Events:
noItemToList
Fires onkeypress while there are no options to list.
Signature:
onNoItemToList(elements)
Arguments:
- elements – (object) An object with the ‘field’ and ‘list’ instances.
select
Fires when you select an autocomplete option.
Signature:
onSelect(elements, value)
Arguments:
- elements – (object) An object with the ‘field’ and ‘list’ instances.
- value – (mixed) The object that represents the option that has been selected.
deselect
Fires when you deselect an autocomplete option.
Signature:
onDeselect(elements)
Arguments:
- elements – (object) An object with the ‘field’ and ‘list’ instances.
Returns:
(object) A new Meio.Autocomplete instance.
Class: Meio.Autocomplete.Select
This class does exactly what Meio.Autocomplete does plus it can easy act as a DOM select element, putting the ‘value’ attribute of it’s options into a form field (which will be called valueField). It can synchronize its value with the valueField ondomready of the page, working perfectly when the field comes pre-filled with a text value (like on an edit form).
Extends: Meio.Autocomplete
Meio.Autocomplete.Select Method: Constructor
Syntax:
var mySelectAutocomplete = new Meio.Autocomplete.Select(element, data [, options]);
Arguments:
- element – (mixed) A string ID of the Element or an Element to apply the Meio.Autocomplete.Select List to.
- data – (mixed) An array of objects or a url to a page that will respond with a json object that will be converted to an array of objects.
- options – (object, optional) The Meio.Autocomplete.Select options object
Options:
- syncName – (mixed: defaults to ‘id’) Defines the parameter that will contain the unique identifier of the option that is selected at that moment (ondomready). If falsy it wont synchronize the value.
- valueField – (mixed: defaults to null) A string ID of the Element or an Element that will receive the unique identifier of the selected option. This is the field that will be used on your server-side so be sure it has the correct name attribute.
- valueFilter – (function: defaults to function(data){ return data.id; }) This function should return the unique identifier of the ‘data’ object.
Demos
Meio.Autocomplete.Select with a local Array
Meio.Autocomplete.Select with a URL (It will make Ajax requests to the passed URL)
Meio.Autocomplete.Select with a local Array and using accent folding
Meio.Autocomplete.Select.One
Meio.Autocomplete.Select with the same Meio.Element.List instance
Changelog
2.0
This is basically the same as 1.0 but with full support for Mootools 1.3.
1.0
This is basically the same as 0.8.5 (with some code cleanups). The 1.x and before series support Mootools 1.2.x version. Meio.Autocomplete 2.x and greater support Mootools 1.3.
0.8.5
- FIX: Fixed the select bug while synchronizing the value from the input that has the id with the text input on the Meio.Autocomplete.Select class;
- Small code improvements.
0.84
- NEW: Adding the queryVarName option for the urlOptions, now it’s possible to choose the name of the variable that stores the inputed query.
- NEW: Adding formatResponse option as a requestOptions. Redefine it if the array of autocomplete data is inside a key from your response. It receives as first parameter the jsonResponse and should return the array of autocomplete data.
- FIX: the value doesn’t become empty while synchronizing the values at start anymore on Meio.Autocomplete.Select (and the Classes that inherit from it).
0.83
- CHANGED: listInstance is not an option anymore, it’s now the last parameter (after the options). See the new demo.
- FIX: the global cache uses safer keys now.
- FIX: rare error on page unload.
0.82
- NEW: now there’s the Meio.Autocomplete.Select.One Class that will replace a select element with an autocomplete field that will have the same options as the select, just removing the ones that have empty values.
- FIX: The list classes are now being correctly applied.
- FIX: The valueField option was not accepting an ID, just an element. Now it accepts both.
- Created this documentation.
0.81
- Initial release
Credits
License
All this documentations and examples are under the Open Source MIT License.
The MIT License
Copyright (c) 2008 Fábio Miranda Costa
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

March 12th, 2010 14:42
Very nice Autocomplete class!! I want to use it in a JSR-168 portlet, and want to use the portlet namespace as part of the CSS container class (to avoid collisions with other CSS classes on the page). I set the listOptions.classes.container but it was not working. I put some logging in the code, and the List.render() function was happening BEFORE the list.initialize, and I realized it was because List.initialize() was calling this.parent() before it called this.setOptions(options). I needed to change the code, so that it called this.setOptions(options) FIRST, and then called this.parent() (which caused the List to render).
March 15th, 2010 23:15
[...] Meio.Autocomplete Docs and Demos [...]
March 16th, 2010 15:23
Nice work, Fábio!
Abraço
Pedro Martins
March 19th, 2010 03:15
Hey Fabio, good work.
Does this rely on Moo 1.2.4, or do you think it would work on 1.2.0?
I’m a Joomla extension developer, where we are stuck in 1.2.0 land for a while longer …
– hugh
April 9th, 2010 11:48
hey good code! congratulations! a question: which version of 1.2.4 or 1.2.1 works m00tools? I work with 1.2.1 and MochaUI
April 22nd, 2010 03:23
Hey Fabio. Could you completeled the “Meio.Autocomplete.Select with a URL (It will make Ajax requests to the passed URL)”?, the demos not clear thanks
June 7th, 2010 20:06
Hello Fabio, nice plugin. As it works with Mootool, is there any possibility to make it work inside Joomla? Thank you in advance
September 8th, 2010 17:26
ohhhh nice…cool..awesome..how can describe the beauty of this images…fantastic,thanks dear,congratulations man
September 9th, 2010 19:34
I found your website via google thanks for the post. I will bookmark it for future reference.
October 1st, 2010 14:10
The demos on your page are showing errors. Some problem with your server? Would love to see it working.
October 1st, 2010 19:56
MooShell has been switched off without warning – jsFiddle is not responsible for this. I’m working on the issue and I will try to make them woerk as soon as on jsFiddle.
Thanks for using them, apologies for the inconvenience
November 8th, 2010 19:39
Meio.Autocomplete.Select with a URL
how the json data must be sent from the server to display the result as autocomplete (not the local data example)
for this code ?
Thanks & regards Irfan Ahmed
November 8th, 2010 19:49
if you can provide me PHP server script example that would be great for sending json response
November 8th, 2010 20:02
i am using joomla with mootools upgraded plugin
November 16th, 2010 09:21
Hey Fabio, you’re fiddles are outdated – they don’t work since 1.2.x is selected instead of 1.3.
November 16th, 2010 19:54
Updated the fiddles, thanks again @Oskar!
November 22nd, 2010 08:23
[...] recently building a app i was need to suggest data to the user when trying to fill a input. so i look for a js script for this. i usually use mootools for my development in js, so looking for a plugin i found this: Meio.Autocomplete plugin for mootools [...]
November 30th, 2010 05:15
Hi! This plugin looks realy nice, nut i´m missing one multiple – to split the user entered text into multiple values;
Nice to be used in a email client, so if i search for on address first, then after entering ; i just search for the second value and so on..
December 2nd, 2010 13:20
How can I set it to use POST instead of GET?
Ive set it to use a URL
I would like to send the queryVarName parameter as POST
Cheers
December 4th, 2010 22:51
hmm it’s not possible right now, but im marking this so i can add it on the next release
December 8th, 2010 21:08
Hi Fabio, great script and work, many thanks.
Could you give an example of the Autocompleter thay sends a GET request to database query page (php page for example) and then returns results for “data” variable please?
I have over 10,000 records which I import locally from a PHP script but it is too heavy for the page.
I can do the PHP no problem, I just don’t have the expertise to do the Javascript.
Thanks in advance!
January 8th, 2011 08:58
Olá Fabio! Baixei o código e não consegui fazer rodar o autocomplete fica dando um erro que “Meio is undefined” tem alguma biblioteca a mais daquelas do demo que tem que incluir ?
Obrigado! Alex.
February 3rd, 2011 09:28
Hi, This plugin is very buggy while using AJAX and server-side value checking: 1. “Success” Event of Request.JSON in Meio.Autocomplete.Data.Request::createRequest is never run! It seems MooTools bug; anyway I changed Request.JSON to Request and it’s solved. 2. Plugin uses GET method and i did many changes to pass extraParams as POST values. I think that it should be optional! 3. Meio.Autocomplete::refreshCache never runs in plugin and the cache is never emptied, i always get first result set and second request is never sent so i appended “&rand=(new Date()).getTime()” to request URL. 4. Meio.Autocomplete.Filter::_getValueFromKeys makes error while options.path is not set so method below returns input object so i added a new line to it: _getValueFromKeys: function(obj, keys){ // keys is [""] when options.path is not set var key, value = obj; if(keys.length==1 && keys[0]==”") return obj.value; // Added by me for (var i = 0; key = keys[i++];) value = value[key]; return value; }
It will be a great plugin if you debug it. Thanks AHHP
February 5th, 2011 04:46
Hi,
Another problem, It requests empty fields too! i add a line to Meio.Autocomplete.Data.Request::prepare to prevent it:
if(!text || text==”") return;
I’m sorry for my bad reports but i think reports may make it perfect…
May 3rd, 2011 15:01
hi,
nice plugin, too bad, i can’t have it work with ajax. With a local array it works lie a charm with ajax, i can see the response in firebug but apparently the plugin doesn’t read it (even exactly the same object hardcoded in the ajax called url) i’m stuck
but will find out a salvage solution with an array…
May 10th, 2011 04:04
hi again, just for you to know, this line throws an error in IE 7&8
if (this.node) this.node.set(‘autocomplete’, ‘on’); line 589
commenting it doesn’t prevent the script from working and doing what the comment says it should do
Have swing
July 19th, 2011 04:19
I like the helpful info you provide in your articles. I’ll bookmark your weblog and check again here frequently. I am quite sure I will learn plenty of new stuff right here! Good luck for the next!
August 19th, 2011 10:49
That’s awesome Nestor! thanks for sharing!
August 26th, 2011 18:15
Hi, well, great plugin, and I got it worked fine with ajax. No worries there. There’s just one more thing I need to do : after a result has been selected, I need to clear the autocomplete field to be able to start a new search. Tried to just clear the field’s value but it’s not enough. How do I completely reset the thing ?
December 5th, 2011 03:42
[...] Meio I cannot get to work with a url/json request. it is throwing a strange test is not a function error. [...]
December 14th, 2011 05:35
Hello!
Fantastic code! Thanks for sharing. I’m a bit of a beginner with JS and mootools, so please accept apologies if this is a silly question: I’m trying to get it work with a backend PHP script which gets data from a db (instead of hard-coded var):
I’ve got it to work as far as sending the request to the backend, but it’s not processing the response correctly. Here’s the code:
new Meio.Autocomplete.Select('field', 'localhost/ac/', { valueFilter: function(data){ return data.identifier; }, requestOptions: { method: 'get', formatResponse: function(response){ var data = []; new JSON.decode(response).each(function(identifier, item){ this.include({value: identifier, text: item.text}); }, data); return data; } }, ...And the PHP pseudocode:
loop for all like '%abc%' { $a = array('identifier'=>0, 'item'=>$row["term"]); array_push ($result, $a); } print json_encode($result);
I’m not getting any errors in js console, etc, so I’m a little stumped and would appreciate any assistance.
Thank you so much!
December 14th, 2011 06:20
Tweaked the code a bit:
formatResponse: function(response){ var data = []; new response.each(function(identifier, item){ this.include({value: identifier, text: item.text}); }, data); return data; }using a JS debugger, I can see that the response variable receives the correct data from the backend, but the data variable is not being populated with identifier/item values.
Sorry, I know this is wrong forum, but would appreciate any help.
December 14th, 2011 09:27
Solved!
requestOptions: { method: 'get', formatResponse: function(response){ var data = []; response.each(function(obj) { this.include({identifier: obj.id, value: obj.descr}); }, data); return data; } },December 14th, 2011 17:35
Hi,
Great contribution, thanks!
I’m wondering though: how can I get something like onChange=”this.form.submit()” to work with this autocomplete system? ie, if the user clicks with mouse or selects with keyboard one of the autocomplete options, I’d like the Submit button to be fired automatically (the way google does on their search box).
Since onChange=”this.form.submit()” is actually for a tag, how can this be achieved when this autocompleter uses a tag instead?
I’d appreciate any comments.
Thanks
December 14th, 2011 17:37
sorry, your form ate my tags:
Since onChange=”this.form.submit()” is actually for an
selecttag, how can this be achieved when this autocompleter uses aninputtag instead?January 5th, 2012 10:33
[...] Meio.Autocomplete Docs and Demos [...]
January 27th, 2012 08:38
Hello. I want to ask you, how can i move focus from autocomplete input to another element on the page after any item from autocomplete list is selected? Event “onSelect” doesn’t help me in this purpose.
January 27th, 2012 09:14
Done. Overloaded setInputValue in my own class like this:
setInputValue: function(){ this.parent(); this.fireEvent(‘afterSelect’); }
And then defined onAfterSelect function:
onAfterSelect: function(){ this.elements.field.node.blur(); myElement.focus(); }
March 20th, 2012 17:07
I get a $(document.body) is null on line 718. Line 718 Contents: $(document.body).grab(node);
How do I fix this? I’m using MooTools version 1.3.2
Best regards,
March 20th, 2012 17:25
Nevermind.
March 21st, 2012 20:48
Any idea on how to ignore accented characters. A real life example: A user searches for the word “Grafica” and there is a result “Gráfica” but it is not displayed because in theory it does not match, however I need to be a valid match;
Thanks in advanced for your help.