├── auto-complete.css ├── auto-complete.js ├── auto-complete.min.js ├── bower.json ├── demo.html ├── img ├── at.png ├── au.png ├── bg.png ├── br.png ├── ca.png ├── ch.png ├── cn.png ├── cz.png ├── de.png ├── dk.png ├── es.png ├── fi.png ├── fr.png ├── hu.png ├── in.png ├── it.png ├── ja.png ├── nl.png ├── no.png ├── pt.png ├── ro.png ├── ru.png ├── tr.png └── us.png └── readme.md /auto-complete.css: -------------------------------------------------------------------------------- 1 | .autocomplete-suggestions { 2 | text-align: left; cursor: default; border: 1px solid #ccc; border-top: 0; background: #fff; box-shadow: -1px 1px 3px rgba(0,0,0,.1); 3 | 4 | /* core styles should not be changed */ 5 | position: absolute; display: none; z-index: 9999; max-height: 254px; overflow: hidden; overflow-y: auto; box-sizing: border-box; 6 | } 7 | .autocomplete-suggestion { position: relative; padding: 0 .6em; line-height: 23px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 1.02em; color: #333; } 8 | .autocomplete-suggestion b { font-weight: normal; color: #1f8dd6; } 9 | .autocomplete-suggestion.selected { background: #f0f0f0; } 10 | -------------------------------------------------------------------------------- /auto-complete.js: -------------------------------------------------------------------------------- 1 | /* 2 | JavaScript autoComplete v1.0.4 3 | Copyright (c) 2014 Simon Steinberger / Pixabay 4 | GitHub: https://github.com/Pixabay/JavaScript-autoComplete 5 | License: http://www.opensource.org/licenses/mit-license.php 6 | */ 7 | 8 | var autoComplete = (function(){ 9 | // "use strict"; 10 | function autoComplete(options){ 11 | if (!document.querySelector) return; 12 | 13 | // helpers 14 | function hasClass(el, className){ return el.classList ? el.classList.contains(className) : new RegExp('\\b'+ className+'\\b').test(el.className); } 15 | 16 | function addEvent(el, type, handler){ 17 | if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler); 18 | } 19 | function removeEvent(el, type, handler){ 20 | // if (el.removeEventListener) not working in IE11 21 | if (el.detachEvent) el.detachEvent('on'+type, handler); else el.removeEventListener(type, handler); 22 | } 23 | function live(elClass, event, cb, context){ 24 | addEvent(context || document, event, function(e){ 25 | var found, el = e.target || e.srcElement; 26 | while (el && !(found = hasClass(el, elClass))) el = el.parentElement; 27 | if (found) cb.call(el, e); 28 | }); 29 | } 30 | 31 | var o = { 32 | selector: 0, 33 | source: 0, 34 | minChars: 3, 35 | delay: 150, 36 | offsetLeft: 0, 37 | offsetTop: 1, 38 | cache: 1, 39 | menuClass: '', 40 | renderItem: function (item, search){ 41 | // escape special characters 42 | search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); 43 | var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi"); 44 | return '
67 | Released under the MIT License. 68 | Source on Github (changelog). 69 | Tested in Firefox, Safari, Chrome, Opera, Internet Explorer 8+. 70 |
71 |79 | This plugin was developed by Pixabay.com - an international repository for free Public Domain images. 80 | We have implemented this piece of software in production on plainJS and we share it - in the spirit of Pixabay - freely with others. 81 |
82 | 83 |85 | Include the JavaScript file auto-complete.min.js before the closing </body> tag 86 | and the stylesheet auto-complete.css in the <head> section of your page. 87 | autoComplete accepts settings from an object of key/value pairs, and can be assigned to any text input field. 88 |
89 |// initialize
90 | var my_autoComplete = new autoComplete({key1: value1, key2: value2});
91 |
92 | // destroy
93 | my_autoComplete.destroy();
94 |
95 | Property | Default | Description |
---|---|---|
selector | string or DOM element | Required selector for text input field or DOM element. |
source(term, response) | null |
100 | Required callback function to connect any data source to autoComplete. The callback gets two arguments:
101 |
|
minChars | 3 | Minimum number of characters (>=1) a user must type before a search is performed. |
delay | 150 | The delay in milliseconds between when a keystroke occurs and when a search is performed. A zero-delay is more responsive, but can produce a lot of load. |
offsetLeft | 0 | Optional left offset of the suggestions container. |
offsetTop | 1 | Optional top offset of the suggestions container. |
cache | true | Determines if performed searches should be cached. |
menuClass | '' | 116 |Custom class/es that get/s added to the dropdown menu container.
117 | Example: { menuClass: 'class1 class2' } |
118 |
renderItem | function | 121 |
122 | A function that gives you control over how suggestions are displayed. Default: 123 |
128 | |
129 |
Callbacks | ||
onSelect(event, term, item) | 134 | A callback function that fires when a suggestion is selected by mouse click, enter, or tab. 135 | event is the event that triggered the callback, 136 | term is the selected value. 137 | and item is the item rendered by the renderItem function. 138 | | |
Public Methods | ||
destroy | Removes the autoComplete instance and its bindings. |
149 | This plugin was designed mainly with AJAX requests in mind, but it may be used with local data, as well. 150 | Connecting the autocompletion suggester to an array of strings can be done in the source function like so: 151 |
152 |new autoComplete({
153 | selector: 'input[name="q"]',
154 | minChars: 2,
155 | source: function(term, suggest){
156 | term = term.toLowerCase();
157 | var choices = ['ActionScript', 'AppleScript', 'Asp', ...];
158 | var matches = [];
159 | for (i=0; i<choices.length; i++)
160 | if (~choices[i].toLowerCase().indexOf(term)) matches.push(choices[i]);
161 | suggest(matches);
162 | }
163 | });
164 | 165 | The source function iterates through an array of (local) choices and we return a new array containing all (lowercased) matches. 166 | Simple as that. 167 |
168 | 169 |171 | AJAX requests may come with very different requirements: JSON, JSONP, GET, POST, additionaly params, authentications, etc. 172 | In order to keep the source code small while retaining full flexibility, we decided to only use a simple callback function as the source for suggestions. 173 | Make your AJAX call inside this function and return matching suggestions with the response callback. For brevity, this example uses jQuery for AJAX: 174 |
175 |new autoComplete({
176 | selector: 'input[name="q"]',
177 | source: function(term, response){
178 | $.getJSON('/some/ajax/url/', { q: term }, function(data){ response(data); });
179 | }
180 | });
181 | 182 | The AJAX call in this example needs to return an array of strings. 183 | The callback response must always be called, even if no suggestions are returned or if an error occured. 184 | This ensures the correct state of the autoComplete instance. 185 |
186 | 187 |189 | All search results are cached by default and unnecessary requests are prevented in order to keep server load as low as possible. 190 | To further reduce server impact, it's possible to abort unfinished AJAX requests before starting new ones. 191 | Again using jQuery's AJAX method for brevity: 192 |
193 |var xhr;
194 | new autoComplete({
195 | selector: 'input[name="q"]',
196 | source: function(term, response){
197 | try { xhr.abort(); } catch(e){}
198 | xhr = $.getJSON('/some/ajax/url/', { q: term }, function(data){ response(data); });
199 | }
200 | });
201 | 202 | By typing along, the user may trigger one AJAX request after the other. 203 | With this little trick, we make sure that only the most current one actually gets executed - if not done so already. 204 |
205 | 206 |208 | By making use of the renderItem() function, it's possible to turn the autocompleter into an item suggester: 209 |
210 | 213 |214 | While typing country names or language codes, a list of matching suggestions is displayed. E.g. typing "de" will show "Germany" as a suggestion, because "de" is the language code for German. 215 | Source code for this example: 216 |
217 |new autoComplete({
218 | selector: 'input[name="q"]',
219 | minChars: 1,
220 | source: function(term, suggest){
221 | term = term.toLowerCase();
222 | var choices = [['Australia', 'au'], ['Austria', 'at'], ['Brasil', 'br'], ...];
223 | var suggestions = [];
224 | for (i=0;i<choices.length;i++)
225 | if (~(choices[i][0]+' '+choices[i][1]).toLowerCase().indexOf(term)) suggestions.push(choices[i]);
226 | suggest(suggestions);
227 | },
228 | renderItem: function (item, search){
229 | search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
230 | var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
231 | return '<div class="autocomplete-suggestion" data-langname="'+item[0]+'" data-lang="'+item[1]+'" data-val="'+search+'"><img src="img/'+item[1]+'.png"> '+item[0].replace(re, "<b>$1</b>")+'</div>';
232 | },
233 | onSelect: function(e, term, item){
234 | alert('Item "'+item.getAttribute('data-langname')+' ('+item.getAttribute('data-lang')+')" selected by '+(e.type == 'keydown' ? 'pressing enter' : 'mouse click')+'.');
235 | }
236 | });
237 | 238 | In this case, autocompleting the text field is not desired, so we turn it off by setting data-val="'+search+'" in the renderItem() function. 239 | However, when choosing an item, the onSelect() callback returns all required information. 240 |
241 | 242 | 252 | 253 |Please report any bugs and issues at the GitHub repositiory.
254 |This software is released as Open Source under the MIT License by Simon Steinberger / Pixabay.com.
255 |