Autocomplete
Framework7 comes with mobile-friendly and touch optimized Autocomplete component.
Autocomplete could be used in standalone mode or as a dropdown.
Autocomplete can be created and initialized only using JavaScript. We need to use related App’s method:
app.autocomplete.create(parameters)- create Autocomplete instance
- parameters - object. Object with autocomplete parameters
Method returns created Autocomplete’s instance
- el - HTMLElement or string (with CSS Selector) or object. Autocomplete instance to destroy.
app.autocomplete.get(el)- get Autocomplete instance by HTML element
- el - HTMLElement or string (with CSS Selector). Autocomplete element.
Method returns Autocomplete’s instance
app.autocomplete.open(el)- open Autocomplete
- el - HTMLElement or string (with CSS Selector). Autocomplete element to open.
Method returns Autocomplete’s instance
app.autocomplete.close(el)- closes Autocomplete
- el - HTMLElement or string (with CSS Selector). Autocomplete element to close.
For example:
Autocomplete Parameters
Let’s look on list of all available parameters:
Note that all following parameters can be used in global app parameters under autocomplete
property to set defaults for all autcompletes. For example:
var app = new Framework7({
autocomplete: {
openIn: 'popup',
animate: false,
}
});
After we initialize Autocomplete we have its initialized instance in variable (like autocomplete
variable in example above) with helpful methods and properties:
Autocomplete Events
Autocomplete instance emits events on both self instance and app instance. App instance events has same names prefixed with autocomplete
.
Note that commented variables are not specified by default and their values is what they fallback to in this case.
:root {
--f7-autocomplete-dropdown-bg-color: #fff;
--f7-autocomplete-dropdown-placeholder-color: #a9a9a9;
--f7-autocomplete-dropdown-preloader-size: 20px;
/*
--f7-autocomplete-dropdown-selected-bg-color: rgba(var(--f7-theme-color-rgb), 0.2);
*/
}
.ios {
--f7-autocomplete-dropdown-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
--f7-autocomplete-dropdown-text-color: #000;
--f7-autocomplete-dropdown-text-matching-color: #000;
--f7-autocomplete-dropdown-text-matching-font-weight: 600;
--f7-autocomplete-dropdown-font-size: var(--f7-list-font-size);
}
.ios .theme-dark,
.ios.theme-dark {
--f7-autocomplete-dropdown-bg-color: #1c1c1d;
--f7-autocomplete-dropdown-text-color: #fff;
--f7-autocomplete-dropdown-text-matching-color: #fff;
}
.md {
--f7-autocomplete-dropdown-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.25);
--f7-autocomplete-dropdown-text-color: rgba(0, 0, 0, 0.54);
--f7-autocomplete-dropdown-text-matching-color: #212121;
--f7-autocomplete-dropdown-text-matching-font-weight: 400;
--f7-autocomplete-dropdown-font-size: var(--f7-list-font-size);
}
.md .theme-dark,
.md.theme-dark {
--f7-autocomplete-dropdown-bg-color: #1c1c1d;
--f7-autocomplete-dropdown-text-color: rgba(255, 255, 255, 0.54);
--f7-autocomplete-dropdown-text-matching-color: rgba(255, 255, 255, 0.87);
}
.aurora {
--f7-autocomplete-dropdown-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2);
--f7-autocomplete-dropdown-text-color: #000;
--f7-autocomplete-dropdown-text-matching-color: #000;
--f7-autocomplete-dropdown-text-matching-font-weight: 700;
--f7-autocomplete-dropdown-font-size: 13px;
}
.aurora .theme-dark,
.aurora.theme-dark {
--f7-autocomplete-dropdown-bg-color: #1c1c1c;
--f7-autocomplete-dropdown-text-color: #fff;
--f7-autocomplete-dropdown-text-matching-color: #fff;
}
Examples
var app = new Framework7();
var $$ = Dom7;
// Fruits data demo array
var fruits = ('Apple Apricot Avocado Banana Melon Orange Peach Pear Pineapple').split(' ');
Simple Dropdown Autocomplete
<div class="list no-hairlines-md">
<div class="block-header">Simple Dropdown Autocomplete</div>
<ul>
<li class="item-content item-input inline-label">
<div class="item-inner">
<div class="item-title item-label">Fruit</div>
<div class="item-input-wrap">
<input id="autocomplete-dropdown" type="text" placeholder="Fruit">
</div>
</div>
</li>
</ul>
</div>
var autocompleteDropdownSimple = app.autocomplete.create({
inputEl: '#autocomplete-dropdown',
openIn: 'dropdown',
source: function (query, render) {
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
}
});
Dropdown With Input Expand
<div class="list no-hairlines-md">
<div class="block-header">Dropdown With Input Expand</div>
<ul>
<li class="item-content item-input inline-label">
<div class="item-inner">
<div class="item-title item-label">Fruit</div>
<div class="item-input-wrap">
<input id="autocomplete-dropdown-expand" type="text" placeholder="Fruit">
</div>
</div>
</li>
</ul>
</div>
var autocompleteDropdownExpand = app.autocomplete.create({
inputEl: '#autocomplete-dropdown-expand',
openIn: 'dropdown',
expandInput: true, // expand input
source: function (query, render) {
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
}
});
Dropdown With All Values
var autocompleteDropdownAll = app.autocomplete.create({
inputEl: '#autocomplete-dropdown-all',
openIn: 'dropdown',
source: function (query, render) {
var results = [];
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
}
});
Dropdown With Placeholder
<div class="list no-hairlines-md">
<div class="block-header">Dropdown With Placeholder</div>
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Fruit</div>
<div class="item-input-wrap">
</div>
</div>
</li>
</ul>
</div>
var autocompleteDropdownPlaceholder = app.autocomplete.create({
inputEl: '#autocomplete-dropdown-placeholder',
openIn: 'dropdown',
dropdownPlaceholderText: 'Try to type "Apple"',
source: function (query, render) {
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
}
});
Dropdown With Typeahead
<div class="list no-hairlines-md">
<div class="block-header">Dropdown With Typeahead</div>
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Fruit</div>
<div class="item-input-wrap">
<input id="autocomplete-dropdown-typeahead" type="text" placeholder="Fruit">
</div>
</div>
</li>
</ul>
</div>
var autocompleteDropdownTypeahead = app.autocomplete.create({
inputEl: '#autocomplete-dropdown-typeahead',
openIn: 'dropdown',
dropdownPlaceholderText: 'Try to type "Pineapple"',
typeahead: true,
source: function (query, render) {
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) === 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
}
});
Dropdown With Ajax-Data
<div class="list no-hairlines-md">
<div class="block-header">Dropdown With Ajax-Data</div>
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Language</div>
<div class="item-input-wrap">
<input id="autocomplete-dropdown-ajax" type="text" placeholder="Language">
</div>
</div>
</li>
</ul>
</div>
var autocompleteDropdownAjax = app.autocomplete.create({
inputEl: '#autocomplete-dropdown-ajax',
openIn: 'dropdown',
preloader: true, //enable preloader
/* If we set valueProperty to "id" then input value on select will be set according to this property */
valueProperty: 'name', //object's "value" property name
textProperty: 'name', //object's "text" property name
limit: 20, //limit to 20 results
dropdownPlaceholderText: 'Try "JavaScript"',
source: function (query, render) {
var autocomplete = this;
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Show Preloader
autocomplete.preloaderShow();
// Do Ajax request to Autocomplete data
app.request({
url: 'autocomplete-languages.json',
method: 'GET',
dataType: 'json',
//send "query" to server. Useful in case you generate response dynamically
data: {
query: query,
},
success: function (data) {
// Find matched items
for (var i = 0; i < data.length; i++) {
if (data[i].name.toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(data[i]);
}
// Hide Preoloader
autocomplete.preloaderHide();
// Render items by passing array with result items
render(results);
}
});
}
});
Dropdown With Ajax-Data + Typeahead
<div class="list no-hairlines-md">
<div class="block-header">Dropdown With Ajax-Data + Typeahead</div>
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Language</div>
<div class="item-input-wrap">
<input id="autocomplete-dropdown-ajax-typeahead" type="text" placeholder="Language">
</div>
</div>
</li>
</ul>
</div>
Searchbar Dropdown
<div class="page">
<div class="navbar">
<div class="navbar-inner sliding">
...
<!-- Put searchbar in subnavbar -->
<div class="subnavbar">
<form class="searchbar" id="searchbar-autocomplete">
<div class="searchbar-inner">
<div class="searchbar-input-wrap">
<input type="search" placeholder="Search">
<i class="searchbar-icon"></i>
<span class="input-clear-button"></span>
</div>
<span class="searchbar-disable-button">Cancel</span>
</div>
</form>
</div>
</div>
</div>
...
</div>
var searchbar = app.searchbar.create({
el: '#searchbar-autocomplete',
customSearch: true,
on: {
search: function (query) {
console.log(query);
}
}
});
var autocompleteSearchbar = app.autocomplete.create({
openIn: 'dropdown',
inputEl: '#searchbar-autocomplete input[type="search"]',
dropdownPlaceholderText: 'Type "Apple"',
source: function (query, render) {
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
}
})
Simple Standalone Autocomplete
div class="list">
<li>
<a class="item-link item-content" href="#" id="autocomplete-standalone">
<input type="hidden">
<div class="item-inner">
<div class="item-title">Favorite Fruite</div>
<div class="item-after"></div>
</div>
</a>
</li>
</ul>
</div>
var autocompleteStandaloneSimple = app.autocomplete.create({
openIn: 'page', //open in page
openerEl: '#autocomplete-standalone', //link that opens autocomplete
closeOnSelect: true, //go back after we select something
source: function (query, render) {
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
},
on: {
change: function (value) {
console.log(value);
// Add item text value to item-after
$$('#autocomplete-standalone').find('.item-after').text(value[0]);
// Add item value to input value
$$('#autocomplete-standalone').find('input').val(value[0]);
},
},
});
Popup Autocomplete
<div class="list">
<div class="block-header">Popup Autocomplete</div>
<ul>
<li>
<a class="item-link item-content" href="#" id="autocomplete-standalone-popup">
<input type="hidden">
<div class="item-inner">
<div class="item-title">Favorite Fruite</div>
<div class="item-after"></div>
</div>
</a>
</li>
</ul>
</div>
var autocompleteStandalonePopup = app.autocomplete.create({
openIn: 'popup', //open in page
openerEl: '#autocomplete-standalone-popup', //link that opens autocomplete
closeOnSelect: true, //go back after we select something
source: function (query, render) {
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
},
on: {
change: function (value) {
// Add item text value to item-after
$$('#autocomplete-standalone-popup').find('.item-after').text(value[0]);
// Add item value to input value
$$('#autocomplete-standalone-popup').find('input').val(value[0]);
},
},
});
Multiple Values
<div class="list">
<div class="block-header">Multiple Values</div>
<ul>
<li>
<a class="item-link item-content" href="#" id="autocomplete-standalone-multiple">
<input type="hidden">
<div class="item-inner">
<div class="item-title">Favorite Fruite</div>
<div class="item-after"></div>
</div>
</a>
</li>
</ul>
</div>
var autocompleteStandaloneMultiple = app.autocomplete.create({
openIn: 'page', //open in page
openerEl: '#autocomplete-standalone-multiple', //link that opens autocomplete
multiple: true, //allow multiple values
source: function (query, render) {
var autocomplete = this;
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Find matched items
for (var i = 0; i < fruits.length; i++) {
if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
}
// Render items by passing array with result items
render(results);
},
on: {
change: function (value) {
// Add item text value to item-after
$$('#autocomplete-standalone-multiple').find('.item-after').text(value.join(', '));
// Add item value to input value
$$('#autocomplete-standalone-multiple').find('input').val(value.join(', '));
}
}
});
Standalone With Ajax-Data
var autocompleteStandaloneAjax = app.autocomplete.create({
openIn: 'page', //open in page
openerEl: '#autocomplete-standalone-ajax', //link that opens autocomplete
multiple: true, //allow multiple values
valueProperty: 'id', //object's "value" property name
textProperty: 'name', //object's "text" property name
limit: 50,
preloader: true, //enable preloader
source: function (query, render) {
var autocomplete = this;
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Show Preloader
autocomplete.preloaderShow();
// Do Ajax request to Autocomplete data
app.request({
url: 'autocomplete-languages.json',
method: 'GET',
dataType: 'json',
//send "query" to server. Useful in case you generate response dynamically
data: {
query: query
},
success: function (data) {
// Find matched items
for (var i = 0; i < data.length; i++) {
if (data[i].name.toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(data[i]);
}
// Hide Preoloader
autocomplete.preloaderHide();
// Render items by passing array with result items
render(results);
}
});
},
on: {
change: function (value) {
var itemText = [],
inputValue = [];
for (var i = 0; i < value.length; i++) {
itemText.push(value[i].name);
inputValue.push(value[i].id);
}
// Add item text value to item-after
$$('#autocomplete-standalone-ajax').find('.item-after').text(itemText.join(', '));
// Add item value to input value
$$('#autocomplete-standalone-ajax').find('input').val(inputValue.join(', '));
},
});