Auto Complete with ngTagInput using Web API in AngularJS

In this article, you will learn how to implement ngTagsInput directive in AngularJS. We will use Web API to get the data from SQL Server database with Entity Framework.

What is a tags input?
A tags input is an input box that automatically creates tags – also called tokens – out of typed text every time a certain key is pressed. It's useful for tagging and highlighting information right on the input box.

What is ngTagsInput?
ngTagsInput is a highly customizable tags input directive built for the AngularJS framework, with no external dependencies. It provides a <tags-input> element so you can semantically express you're using an input with tagging capabilities.

Where should I use it?
You can benefit from an input with tagging support when you want to let users enter tags for a post, select multiples contacts from a list, or any other situation where it's appropriate to have an inline, as-you-type list of items.

Stored Procedure

  1. USE [NORTHWND]  
  2. GO  
  3. /****** Object: StoredProcedure [dbo].[GetEmployee] Script Date: 11/15/2017 4:36:15 PM ******/  
  4. SET ANSI_NULLS ON  
  5. GO  
  6. SET QUOTED_IDENTIFIER ON  
  7. GO  
  8. ALTER PROCEDURE [dbo].[GetEmployee]  
  9. AS  
  10. SELECT EmployeeID,  
  11. FirstName,  
  12. LastName,  
  13. City,  
  14. Region,  
  15. PostalCode,  
  16. Country,  
  17. Notes  
  18. FROM Employees  
  19. ORDER BY EmployeeID DESC 
Web API –

Let’s work on Web API part first:

Model Class:

  1. public partial class GetEmployee_Result  
  2. {  
  3. public int EmployeeID { get; set; }  
  4. public string FirstName { get; set; }  
  5. public string LastName { get; set; }  
  6. public string City { get; set; }  
  7. public string Region { get; set; }  
  8. public string PostalCode { get; set; }  
  9. public string Country { get; set; }  
  10. public string Notes { get; set; }  

Builder Class:
  1. /// <summary>  
  2. /// Get Employee using stored procedure  
  3. /// </summary>  
  4. /// <returns></returns>  
  5. public async Task<IEnumerable<GetEmployee_Result>> GetEmployee()  
  6. {  
  7. try  
  8. {   
  9. return await db.Database.SqlQuery<GetEmployee_Result>("GetEmployee").ToListAsync();   
  10. }  
  11. catch (Exception ex)  
  12. {  
  13. throw ex;  
  14. }  

Web API
  1. [RoutePrefix("api/EmployeeAPI")]  
  2. public class EmployeeAPIController : ApiController  
  3. {  
  4. private readonly EmployeeVMBuilder _employeeVMBuilder = new EmployeeVMBuilder();  
  5. // GET api/<controller>  
  6. [Route("GetEmployee")]  
  7. public async Task<IEnumerable<GetEmployee_Result>> GetEmployee()  
  8. {  
  9. return await _employeeVMBuilder.GetEmployee();  
  10. }  

Thus, we are done with Entity framework and API Controller here. Now, install the files given below, using "Manage NuGet Package".


Add JavaScript files and CSS reference in BundleConfig.cs.

  1. bundles.Add(new StyleBundle("~/Content/css").Include(  
  2. "~/Content/bootstrap.css",  
  3. "~/Content/site.css",  
  4. "~/Content/ui-grid.min.css",  
  5. "~/Content/ng-tags-input.css"));  
  6. bundles.Add(new ScriptBundle("~/bundles/angular").Include(  
  7. "~/Scripts/angular.js",  
  8. "~/Scripts/angular-route.js",  
  9. "~/Scripts/ui-grid.js",  
  10. "~/Scripts/angular-ui/ui-bootstrap.js",  
  11. "~/Scripts/angular-ui/ui-bootstrap-tpls.js"));  
  12. bundles.Add(new ScriptBundle("~/bundles/ngtagsInput").Include(  
  13. "~/Scripts/ng-tags-input.js"));  
  14. bundles.Add(new ScriptBundle("~/bundles/employee").Include(  
  15. "~/Angular/app.js",  
  16. "~/Angular/Services/employeeService.js",  
  17. "~/Angular/Controller/employeeController.js",  
  18. "~/Angular/Controller/editEmployeeController.js",  
  19. "~/Angular/Controller/addEmployeeController.js",  
  20. "~/Angular/Controller/ngtagsInputController.js")); 
And, render on _layout.cshtml.
  1. @Scripts.Render("~/bundles/jquery")  
  2. @Scripts.Render("~/bundles/bootstrap")   
  3. @Scripts.Render("~/bundles/angular")   
  4. @Scripts.Render("~/bundles/employee")  
  5. @Scripts.Render("~/bundles/ngtagsInput")  
  6. @RenderSection("scripts", required: false
Now, add a new Angular Controller with scope. I am using just one script for Module, Service, and Controller. You can have it separate if working on a big project.

Module

  1. //Define an angular module for our app  
  2. var app = angular.module('app', ['ngRoute',   
  3. 'ui.grid',  
  4. 'ui.grid.edit',  
  5. 'ui.grid.pagination',  
  6. 'ui.grid.autoResize',  
  7. 'ui.grid.expandable',  
  8. 'ui.grid.selection',  
  9. 'ui.grid.pinning',  
  10. 'ui.bootstrap',  
  11. 'ngTagsInput'])  
  12. .config(function ($routeProvider, $locationProvider) {   
  13. $locationProvider.hashPrefix('');  
  14. $routeProvider  
  15. .when('/', {  
  16. templateUrl: 'Home',  
  17. controller: 'homeController'  
  18. })   
  19. .when('/employee', {  
  20. templateUrl: 'Employee',  
  21. controller: 'employeeController'  
  22. });  
  23. }); 

Service

  1. app.service('employeeService', function ($http) {   
  2. //get   
  3. this.getEmployees = function () {  
  4. var req = $http.get('api/EmployeeAPI/GetEmployee');  
  5. return req;   
  6. };   
  7. }); 

Controller

  1. app.controller("ngtagsInputController", function (  
  2.                                         $scope, $filter,   
  3.                                         employeeService, $window,    
  4.                                         $http, $log, $interval, $uibModal, $q) {    
  5.   
  6. $scope.tags = [];  
  7. $scope.employees = [];  
  8.   
  9.  //get employees  
  10. employeeService.getEmployees().then(function (result) {  
  11.             angular.forEach(result.data, function (value, index) {  
  12.                 $scope.employees.push({ id: value.EmployeeID, name: value.FirstName + " " + value.LastName  });  
  13.             });  
  14.             console.log($scope.employees);  
  15.         }, function (error) {  
  16.             $window.alert('Something went wrong while fetching the employee data.');  
  17.  });  
  18.     
  19. $scope.loadEmployees = function($query)  
  20.   {  
  21.       var myemployees =  $scope.employees;  
  22.       return myemployees.filter(function(employee) {  
  23.         return employee.name.toLowerCase().indexOf($query.toLowerCase()) != -1;  
  24.       });  
  25.     }  
  26. //end  
  27. }); 

Index

  1. @{  
  2. ViewBag.Title = "Index";  
  3. Layout = "~/Views/Shared/_Layout.cshtml";  
  4. }  
  5. <h2>ngTagInput Sample</h2>  
  6. <div ng-controller="ngtagsInputController">  
  7. <tags-input ng-model="tags" display-property="name" placeholder="Add a employee" replace-spaces-with-dashes="false">  
  8. <auto-complete source="loadEmployees($query)"  
  9. min-length="1"  
  10. load-on-focus="false"  
  11. load-on-empty="false"  
  12. max-results-to-show="32"  
  13. template="my-custom-template"></auto-complete>  
  14. </tags-input>  
  15. <p>Selected Model: {{tags}}</p>  
  16. <script type="text/ng-template" id="my-custom-template">  
  17. <div class="right-panel">  
  18. <span ng-bind-html="$highlight($getDisplayText())"></span>  
  19. </div>  
  20. </script>  
  21. </div> 

As everything is done, run the application.


Type some keyword in textbox.


As you can see data is auto populate based on keyword, and whatever keyword you entered that is highlighted.


After selection you selection you can see that is added in textbox with remove option.

Conclusion

In this article, we have seen how to implement AutoComplete text box with Web API and Entity Framework in MVC. If you have any questions or comments, drop me a line in the comments section.