JSFiddle - React, Tailwind, and code Playground
by Giray
HTML
<script src="https://cdn.jsdelivr.net/gh/giray123/javascript-autocomplete@v1.1/js/autocomplete.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/giray123/javascript-autocomplete@v1.1/css/autocomplete.css">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Autocomplete for Native Javascript</title>
</head>
<body>
<div id="main">
<h1>Autocomplete for Native Javascript</h1>
<p>autocomplete snippet for HTML input fields build with native javascript and no dependencies</p>
<p>
This snippet:
<ul>
<li>is built with **native javascript**</li>
<li>is built with <b>native javascript</b></li>
<li>requires <b>no dependencies</b></li>
<li>can be used <b>with OR without AJAX</b></li>
<li>highy <b>customizable</b> yet very <b>simple</b></li>
<li>user experience is <b>inspired from Google search</b></li>
</ul>
</p>
<h2>Without AJAX (list array)</h2>
<p>Search for 'apple', 'applepie', 'abacus', 'grape', 'watermelon', 'cherry'</p>
<input id="search_wihtout_ajax" class="ac-input-default" type="text" placeholder="Search..." autocomplete="off">
<h2>Without AJAX (list array) and Custom Search Function</h2>
<p>Search for 'apple', 'applepie', 'abacus', 'grape', 'watermelon', 'cherry'</p>
<input id="search_wihtout_ajax_custom_search" class="ac-input-default" type="text" placeholder="Search..." autocomplete="off">
<h2>Built-in AJAX</h2>
<p>Search for anime names</p>
<input id="search_auto_ajax" class="ac-input-default" type="text" placeholder="Search..." autocomplete="off">
<h2>Custom AJAX Handler</h2>
<input id="search_manual_ajax" class="ac-input-default" type="text" placeholder="Search..." autocomplete="off">
</div>
</body>
</html>
CSS
body {
font-family: sans-serif;
text-align: center;
padding-bottom: 400px;
padding-left: 20px;
padding-right: 20px;
}
#main {
width: 100%;
text-align: left;
}
h1 {
margin-top: 60px;
}
h2 {
margin-top: 60px;
}
input.ac-input-default {
width: 350px;
transition: all .25s ease-out;
color: #4a5568;
padding: 10px 20px 10px 20px;
line-height: 1.5;
border-width: 1px;
border-radius: .5rem;
border-color: transparent;
background-color: #edf2f7;
font-family: sans-serif;
font-size: 15px;
}
input.ac-input-default:focus {
outline: none;
background-color: white;
border: 1px solid #edf2f7;
}
/* below styles are to grap icons from the cdn instead of the server */
.ac-wrapper .ac-autocomplete-clear-icon {
background-image: url(https://cdn.jsdelivr.net/gh/giray123/javascript-autocomplete@v1.1/img/clear.svg);
}
.ac-wrapper .ac-autocomplete-loading-icon {
background-image: url(https://cdn.jsdelivr.net/gh/giray123/javascript-autocomplete@v1.1/img/loading.svg);
}
.ac-wrapper .ac-suggestion-list div.autocomplete-mobile-icon {
background-image: url(https://cdn.jsdelivr.net/gh/giray123/javascript-autocomplete@v1.1/img/arrow-top-left.svg);
}
JavaScript
var autocomplete = new Autocomplete({
selector: "#search_wihtout_ajax",
minChar: 1,
delay: 100,
list: ['apple', 'applepie', 'abacus', 'grape', 'watermelon', 'cherry'],
submitHandler: function(str) {
console.log("Searched: " + str)
}
})
var autocomplete = new Autocomplete({
selector: "#search_wihtout_ajax_custom_search",
minChar: 1,
delay: 100,
list: ['apple', 'applepie', 'abacus', 'grape', 'watermelon', 'cherry'],
customSearch: function(value, list) {
var regexp = new RegExp(value.toLowerCase().trim())
var results = list.filter(v => regexp.test(v)).sort()
return results
},
submitHandler: function(str) {
console.log("Searched: " + str)
}
})
var autocomplete = new Autocomplete({
selector: "#search_auto_ajax",
minChar: 1,
maxListHeight: 400,
ajax: {
method: "GET",
url: "https://kitsu.io/api/edge/anime",
withCredentials: false,
fields: "?fields[anime]=titles&page[limit]=10&filter[text]",
responseHandler: function(response) {
var array = JSON.parse(response).data
.map(v => v.attributes.titles.en || v.attributes.titles.en_jp)
.filter(v => v) // remove false/undefined values
console.log(array, 'array')
return array
},
},
beforeAjax: function(search) {
return search.toLowerCase()
},
submitHandler: function(str) {
console.log("Searched: " + str)
}
})
var autocomplete = new Autocomplete({
selector: "#search_manual_ajax",
minChar: 1,
manualAjax: function(value) {
return new Promise(function(resolve, reject) {
var request = new XMLHttpRequest();
request.open('GET', 'https://kitsu.io/api/edge/anime?fields[anime]=titles&page[limit]=10&filter[text]=' + value, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.onreadystatechange = function() {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
console.log('succeed');
...