Autocomplete using Angular 4/5/6 with Bootstrap 4

Autocomplete using AngularJS 2 with Bootstrap 4:

Autocomplete is a functionality that completes words/phrases/strings without the need to type them in full.
It predicts the remaining strings/words/phrases/characters based on the input or the word has been typed so far. If you are looking autocomplete functionality using jQuery then check in the below link,

Autocomplete using jQuery, PHP and MySQL


This post explains autocomplete using angularjs 2 in bootstrap 4. Combining md-* components with bootstrap will create some alignment and UI issues.
But I have done my best to provide best responsive header autocomplete search using angularjs 2 with bootstrap 4.

 

Autocomplete using AngularJS 2 with Bootstrap 4 – Demo:
demo

 

 

AngularJS 2 Autocomplete Official Documentation and Demo

 

Requirements:

[html]
<!– jQuery first, then Tether, then Bootstrap JS. –>
<script src=”https://code.jquery.com/jquery-3.1.1.slim.min.js” integrity=”sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n” crossorigin=”anonymous”></script>
<script src=”js/tether.js”></script>
<script src=”https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js” integrity=”sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn” crossorigin=”anonymous”></script>

<!– Angular Material requires Angular.js Libraries –>
<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js”></script>
<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js”></script>
<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js”></script>
<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js”></script>

<!– Angular Material Library –>
<script src=”http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js”></script>
[/html]

 

 

Javascript Code: [Taken from angularjs official documentation]

 

[html]
<!– Your application bootstrap –>
<script type=”text/javascript”>
/**
* You must include the dependency on ‘ngMaterial’
*/
angular.module(‘BlankApp’, [‘ngMaterial’]);
(function () {
‘use strict’;
angular
.module(‘autocompleteDemo’, [‘ngMaterial’])
.controller(‘DemoCtrl’, DemoCtrl);

function DemoCtrl ($timeout, $q, $log) {
var self = this;

self.simulateQuery = false;
self.isDisabled = false;

// list of `state` value/display objects
self.states = loadAll();
self.querySearch = querySearch;
self.selectedItemChange = selectedItemChange;
self.searchTextChange = searchTextChange;

self.newState = newState;

function newState(state) {
alert(“Sorry! You’ll need to create a Constitution for ” + state + ” first!”);
}

// ******************************
// Internal methods
// ******************************

/**
* Search for states… use $timeout to simulate
* remote dataservice call.
*/
function querySearch (query) {
var results = query ? self.states.filter( createFilterFor(query) ) : self.states,
deferred;
if (self.simulateQuery) {
deferred = $q.defer();
$timeout(function () { deferred.resolve( results ); }, Math.random() * 1000, false);
return deferred.promise;
} else {
return results;
}
}

function searchTextChange(text) {
$log.info(‘Text changed to ‘ + text);
}

function selectedItemChange(item) {
$log.info(‘Item changed to ‘ + JSON.stringify(item));
}

/**
* Build `states` list of key/value pairs
*/
function loadAll() {
var allStates = ‘Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware,\
Florida, Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana,\
Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana,\
Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, New York, North Carolina,\
North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina,\
South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia,\
Wisconsin, Wyoming’;

return allStates.split(/, +/g).map( function (state) {
return {
value: state.toLowerCase(),
display: state,
link: state+state
};
});
}

/**
* Create filter function for a query string
*/
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);

return function filterFn(state) {
return (state.value.indexOf(lowercaseQuery) === 0);
};

}
}
})();

</script>
<script>
$(function() {
window.prettyPrint && prettyPrint()
$(document).on(‘click’, ‘.yamm .dropdown-menu’, function(e) {
e.stopPropagation()
})
})
</script>
[/html]

 

 

Header search box code: Angularjs 2 md-autocomplete component inside bootstrap 4 navbar:

 

[html]
<div class=”collapse navbar-collapse” id=”navbarTopMenu”>
<div class=”navbar-toggleable-sm”>
<!– autocomplete bootstrap header ends –>
<div ng-app=”autocompleteDemo” ng-cloak>
<div ng-controller=”DemoCtrl as ctrl” layout=”column” ng-cloak>
<form class=”form-inline my-2 my-lg-0″ ng-submit=”$event.preventDefault()”>
<md-autocomplete
ng-disabled=”ctrl.isDisabled”
md-no-cache=”ctrl.noCache”
md-selected-item=”ctrl.selectedItem”
md-search-text-change=”ctrl.searchTextChange(ctrl.searchText)”
md-search-text=”ctrl.searchText”
md-selected-item-change=”ctrl.selectedItemChange(item)”
md-items=”item in ctrl.querySearch(ctrl.searchText)”
md-item-text=”item.display”
md-min-length=”0″
placeholder=”What is your favorite US state?”>
<md-item-template>
<a href=”#” alt=”{{item.link}}”><span md-highlight-text=”ctrl.searchText” md-highlight-flags=”^i”>{{item.display}}</span></a>
</md-item-template>
<md-not-found>
No states matching “{{ctrl.searchText}}” were found.
<a ng-click=”ctrl.newState(ctrl.searchText)”>Create a new one!</a>
</md-not-found>
</md-autocomplete>
<button class=”btn btn-outline-success my-2 my-sm-0″ type=”submit”>Search</button>
</form>
</div>
</div>
</div>
<!–/.container inside nav–>
</div>
[/html]

 

 

 

Full source code: [This file can be copied and ran directly]

Above snippets are given separately to make you understand it better.

[html]
<!DOCTYPE html>
<html lang=”en”>
<head>
<!– Required meta tags –>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1, shrink-to-fit=no”>
<!– Angular Material style sheet –>
<link rel=”stylesheet” href=”http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css”>
<!– Bootstrap CSS –>
<link rel=”stylesheet” href=”https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css” integrity=”sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ” crossorigin=”anonymous”>
<!– Yamm styles–>
<link href=”css/yamm.css” rel=”stylesheet”>
<!– Demo styles–>
<link href=”css/cc.css” rel=”stylesheet”>
</head>
<body>
<nav class=”navbar fixed-top navbar-toggleable-md navbar-inverse bg-primary yamm” id=”slide-nav”>
<button class=”navbar-toggler navbar-toggler-left” type=”button” data-toggle=”collapse” data-target=”#navbarTopMenu” aria-controls=”navbarTopMenu” aria-expanded=”false” aria-label=”Toggle navigation”>
<span class=”navbar-toggler-icon”></span>
</button>
<div class=”container”>
<a class=”navbar-brand” href=”#”>BrandName12</a>
<div class=”navbar-brand”>
</div>
<div class=”collapse navbar-collapse” id=”navbarTopMenu”>
<div class=”navbar-toggleable-sm”>
<!– autocomplete bootstrap header ends –>
<div ng-app=”autocompleteDemo” ng-cloak>
<div ng-controller=”DemoCtrl as ctrl” layout=”column” ng-cloak>
<form class=”form-inline my-2 my-lg-0″ ng-submit=”$event.preventDefault()”>
<md-autocomplete
ng-disabled=”ctrl.isDisabled”
md-no-cache=”ctrl.noCache”
md-selected-item=”ctrl.selectedItem”
md-search-text-change=”ctrl.searchTextChange(ctrl.searchText)”
md-search-text=”ctrl.searchText”
md-selected-item-change=”ctrl.selectedItemChange(item)”
md-items=”item in ctrl.querySearch(ctrl.searchText)”
md-item-text=”item.display”
md-min-length=”0″
placeholder=”What is your favorite US state?”>
<md-item-template>
<a href=”#” alt=”{{item.link}}”><span md-highlight-text=”ctrl.searchText” md-highlight-flags=”^i”>{{item.display}}</span></a>
</md-item-template>
<md-not-found>
No states matching “{{ctrl.searchText}}” were found.
<a ng-click=”ctrl.newState(ctrl.searchText)”>Create a new one!</a>
</md-not-found>
</md-autocomplete>
<button class=”btn btn-outline-success my-2 my-sm-0″ type=”submit”>Search</button>
</form>
</div>
</div>
</div>
<!–/.container inside nav–>
</div>
</div>
</nav>
<!– jQuery first, then Tether, then Bootstrap JS. –>
<script src=”https://code.jquery.com/jquery-3.1.1.slim.min.js” integrity=”sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n” crossorigin=”anonymous”></script>
<script src=”js/tether.js”></script>
<script src=”https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js” integrity=”sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn” crossorigin=”anonymous”></script>
<!– Angular Material requires Angular.js Libraries –>
<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js”></script>
<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js”></script>
<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js”></script>
<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js”></script>
<!– Angular Material Library –>
<script src=”http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js”></script>
<!– Your application bootstrap –>
<script type=”text/javascript”>
/**
* You must include the dependency on ‘ngMaterial’
*/
angular.module(‘BlankApp’, [‘ngMaterial’]);
(function () {
‘use strict’;
angular
.module(‘autocompleteDemo’, [‘ngMaterial’])
.controller(‘DemoCtrl’, DemoCtrl);

function DemoCtrl ($timeout, $q, $log) {
var self = this;
self.simulateQuery = false;
self.isDisabled = false;
// list of `state` value/display objects
self.states = loadAll();
self.querySearch = querySearch;
self.selectedItemChange = selectedItemChange;
self.searchTextChange = searchTextChange;
self.newState = newState;
function newState(state) {
alert(“Sorry! You’ll need to create a Constitution for ” + state + ” first!”);
}
// ******************************
// Internal methods
// ******************************
/**
* Search for states… use $timeout to simulate
* remote dataservice call.
*/
function querySearch (query) {
var results = query ? self.states.filter( createFilterFor(query) ) : self.states,
deferred;
if (self.simulateQuery) {
deferred = $q.defer();
$timeout(function () { deferred.resolve( results ); }, Math.random() * 1000, false);
return deferred.promise;
} else {
return results;
}
}
function searchTextChange(text) {
$log.info(‘Text changed to ‘ + text);
}
function selectedItemChange(item) {
$log.info(‘Item changed to ‘ + JSON.stringify(item));
}
/**
* Build `states` list of key/value pairs
*/
function loadAll() {
var allStates = ‘Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware,\
Florida, Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana,\
Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana,\
Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, New York, North Carolina,\
North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina,\
South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia,\
Wisconsin, Wyoming’;

return allStates.split(/, +/g).map( function (state) {
return {
value: state.toLowerCase(),
display: state,
link: state+state
};
});
}
/**
* Create filter function for a query string
*/
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);

return function filterFn(state) {
return (state.value.indexOf(lowercaseQuery) === 0);
};

}
}
})();
</script>
<script>
$(function() {
window.prettyPrint && prettyPrint()
$(document).on(‘click’, ‘.yamm .dropdown-menu’, function(e) {
e.stopPropagation()
})
})
</script>
</body>
</html>
[/html]

 

Leave a Reply