Hey guys,
In the previous post we’ve learned How To Use Filters in Angular JS.
In this post I’ll show you how to implement a Quick Search Tab in Angular JS. In this tutorial, we’ll build a demo application that will enable users to search through a list of entities. By the end of this tutorial, you’ll see exactly how I’ve implemented this feature. You can see a live demo of this tutorial at this link – Live Demo
The sample listing we are going to use in this tutorial is a list of country names. So let’s get to it.
There are many ways in which you can define the folder structure for Angular JS. I find it easier just to follow the conventional web project directory structure. Here’s what the project structure should look like:
1. index.html
2. app (folder)
This is the starting point of your Angular JS search application.
(function() { // define a new module angular.module("searchtab", []); })();
In the above code snippet, we have just initialized the angular app named “searchtab”.
Now, let’s have a look at the app.js file. As you can see from the code above, we have instantiated a module here and named it searchtab. This name is basically used to declare all other angular components in our application like controllers, services, filters, directives, etc.
In Angular JS, it is a recommended practice to separate the user interface (UI) layers from the data layers, for which, Angular JS uses the concept of services. And that’s what we will use in this step. Here, we will simply create a service that will be responsible for providing the required data.
(function() { // define a new module angular.module("searchtab").service("SearchService", SearchService); function SearchService() { this.countries = [ {"name": "Afghanistan", "code": "af"}, {"name": "Albania", "code": "al"}, … … … {"name": "Zimbabwe", "code": "zw"} ]; this.get = function () { return this.countries; } } })();
The first line of code in the above snippet, tells Angular JS to register a service named “SearchService”and passed the reference of this SearchService function.
In this SearchService function, we have an array that holds information about various countries’ names. And we have a get function which returns a list of countries.
In Angular JS, we use filters to format or filter data. These are called Pipes in Angular 2. These filters can be added to expressions by using the pipe character ‘|’ followed by a filter (as shown in the code snippet below).
(function() { // define a new module angular.module("searchtab").filter('search', SearchFilter); function SearchFilter() { return function (array, query) { // if no query defined, then return complete array if (!query) { return array; } var filtered = []; // convert search query to lower case query = query.toLowerCase(); // loop on all items of array and match with query angular.forEach(array, function (item) { var name = item.name.toLowerCase(); var found = name.indexOf(query) > -1; // if query matches name field // then add item in filtered array if (found === true) { filtered.push(item); } }); return filtered; }; } })();
As you can in the above given snippet, the first line of code tells Angular JS to register a filter named ‘search’ and pass the reference of the SearchFilter function to it, to perform the filtration task.
The SearchFilter function returns a function which is invoked by Angular JS, which basically has two parameters – an array and a query. The array parameter contains the list of items on which filtration has to be performed and the query parameter contains the keyword entered by user.
In Angular JS, we use controllers to project data to HTML templates. Let’s create our Search Controller (as shown below).
(function() { // define a new module angular.module("searchtab").controller("SearchController", ['SearchService', SearchController]); function SearchController(searchService) { this.countries = searchService.get(); } })();
Now, let’s create the HTML page. The basic structure of an HTML page in Angular JS is typically as follows:
<!DOCTYPE html> <html lang="en" ng-app="searchtab"> <head> <meta charset="UTF-8"> <title>Angular Search Tab - Folio3</title> </head> <body ng-cloak> </body> </html>
In the code snippet above, you’ll notice that we have added the ng-cloak directive on the body tag. The ngCloak directive is used to prevent the Angular JS HTML template from being briefly displayed by the browser in its raw (uncompiled) form when your application is loading. You can use this directive to avoid the undesirable flicker effect caused by the HTML template display.
Also, notice that we have added ng-app attribute on the HTML tag. This attribute tells Angular JS about the main module from which all the controllers, directives, services and other components will be loaded.
Now, add the following stylesheets in the head section after the title tag. These stylesheets will help us change the look and feel of our web page.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous"> <link rel="stylesheet" href="https://cloud.github.com/downloads/lafeber/world-flags-sprite/flags32.css" type="text/css" /> <style> .container {margin-top: 30px;} .search-bar {margin-bottom: 15px;} .f32 .flag {vertical-align: middle;} </style>
Now, add the following HMTL in the body section.
<div ng-controller="SearchController as searchController" class="container"> <div class="search-bar"> <!-- Create a binding between the searchController.query model and the text field --> <input type="text" ng-model="searchController.query" placeholder="search countries..." class="form-control input-lg" /> </div> <!-- Render a div element for every entry in the countries array. Notice the custom search filter "search". It takes the value of the searchController.query model as an argument. --> <div class="list-group"> <div class="list-group-item f32" ng-repeat="item in searchController.countries | search:searchController.query"> <i class="flag {{item.code}}"></i> <span class="list-group-item-heading"> {{item.name}} </span> </div> </div> </div>
I’ll explain the directives we’ve used in the code above in a bit but for now, just note that adding the ng-controller=”SearchController as searchController” in the first div binds the SearchController class and adding ng-model=”searchController.query” to the input in this div, defines the query you want to bind with this field.
The second div of listings has a child div with ng-repeat=”item in searchController.countries | search:searchController.query”. This basically shows the results of the query being executed with the above defined input field.
At the end of this HTML file, we will include the Angular JS library path and the other files that our program will use (shown below), which we have also placed in the app folder.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script> <script src="app/app.js"></script> <script src="app/search_filter.js"></script> <script src="app/search_service.js"></script> <script src="app/search_controller.js"></script>
<!DOCTYPE html> <html lang="en" ng-app="searchtab"> <head> <meta charset="UTF-8"> <title>Angular Search Tab - Folio3</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous"> <link rel="stylesheet" href="https://cloud.github.com/downloads/lafeber/world-flags-sprite/flags32.css" type="text/css" /> <style> .container {margin-top: 30px;} .search-bar {margin-bottom: 15px;} .f32 .flag {vertical-align: middle;} </style> </head> <body ng-cloak> <div ng-controller="SearchController as searchController" class="container"> <div class="search-bar"> <!-- Create a binding between the searchController.query model and the text field --> <input type="text" ng-model="searchController.query" placeholder="search countries..." class="form-control input-lg" /> </div> <!-- Render a div element for every entry in the countries array. Notice the custom search filter "search". It takes the value of the searchController.query model as an argument. --> <div class="list-group"> <div class="list-group-item f32" ng-repeat="item in searchController.countries | search:searchController.query"> <i class="flag {{item.code}}"></i> <span class="list-group-item-heading"> {{item.name}} </span> </div> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script> <script src="app/app.js"></script> <script src="app/search_filter.js"></script> <script src="app/search_service.js"></script> <script src="app/search_controller.js"></script> </body> </html>
In this tutorial, we have created an Angular JS application which displays a listing of countries’ names and flags, along with a search field that takes an input from the user, to filter this list as per the user’s input.
In the next post we will learn how to create a Todo Application using Angular JS
USA408 365 4638
1301 Shoreway Road, Suite 160,
Belmont, CA 94002
Whether you are a large enterprise looking to augment your teams with experts resources or an SME looking to scale your business or a startup looking to build something.
We are your digital growth partner.
Tel:
+1 408 365 4638
Support:
+1 (408) 512 1812
COMMENTS ()
Tweet