Custom Scroll In AngularJS-UI-Grid With Web API

If you want to know how to get started with UI-Grid and how to set up a project in AngularJS and Web API, read the articles given below first.

The custom scrolling feature allows you to provide your own scroller function to replace default element, On('scroll') function. It is particularly helpful if you are facing issues with scrolling on devices or slow machines, because it allows you to use third-party scrollers.

After creating all basic and adding mandatory script, let’s implement custom scrolling on ui-grid. Thus, after adding data in Entity Model, create a Web API to get the data from Entity model.

Web API

Here, my Web API class code is given below.

  1. public class EmployeesAPIController: ApiController {  
  2.     private NORTHWNDEntities db = new NORTHWNDEntities();  
  3.     // GET: api/Employees  
  4.     public IQueryable < Employee > GetEmployees() {  
  5.         return db.Employees;  
  6.     }  
  7.     // GET: api/Employees/5  
  8.     [ResponseType(typeof(Employee))]  
  9.     public async Task < IHttpActionResult > GetEmployee(int id) {  
  10.         Employee employee = await db.Employees.FindAsync(id);  
  11.         if (employee == null) {  
  12.             return NotFound();  
  13.         }  
  14.         return Ok(employee);  
  15.     }  
  16.     protected override void Dispose(bool disposing) {  
  17.         if (disposing) {  
  18.             db.Dispose();  
  19.         }  
  20.         base.Dispose(disposing);  
  21.     }  
  22.     private bool EmployeeExists(int id) {  
  23.         return db.Employees.Count(e => e.EmployeeID == id) > 0;  
  24.     }  
  25. }   

Module
  1. var employeeapp = angular.module('employeeapp', ['ui.grid''ui.grid.pagination']);  

Service

  1. employeeapp.service("employeeservice"function($http) {  
  2.     //Function to call get genre web api call  
  3.     this.GetEmployee = function() {  
  4.         var req = $http.get('api/EmployeesAPI');  
  5.         return req;  
  6.     }  
  7. });   

Controller
  1. //Controller  
  2. employeeapp.controller("employeecontroller"function($scope, employeeservice, $filter, $window, $interval) {  
  3.     GetEmployee();  
  4.   
  5.     function GetEmployee() {  
  6.         employeeservice.GetEmployee().then(function(result) {  
  7.             $scope.Employees = result.data;  
  8.             console.log($scope.Employees);  
  9.         }, function(error) {  
  10.             $window.alert('Oops! Something went wrong while fetching genre data.');  
  11.         })  
  12.     }  
  13.     //Columns  
  14.     $scope.columnDefs = [{  
  15.         name: 'photo',  
  16.         enableSorting: false,  
  17.         field: 'PhotoPath',  
  18.         cellTemplate: "<img width=\"50px\" ng-src=\"{{grid.getCellValue(row, col)}}\" lazy-src>",  
  19.         enableCellEdit: false,  
  20.         enableFiltering: false,  
  21.         width: 100  
  22.     }, {  
  23.         name: 'First Name',  
  24.         field: 'FirstName',  
  25.         headerCellClass: 'tablesorter-header-inner',  
  26.         enableCellEdit: true,  
  27.         enableFiltering: true,  
  28.         width: 150  
  29.     }, {  
  30.         name: 'Last Name',  
  31.         field: 'LastName',  
  32.         headerCellClass: 'tablesorter-header-inner',  
  33.         enableCellEdit: true,  
  34.         enableFiltering: true,  
  35.         width: 150  
  36.     }, {  
  37.         name: 'Title',  
  38.         field: 'Title',  
  39.         headerCellClass: 'tablesorter-header-inner',  
  40.         enableCellEdit: true,  
  41.         enableFiltering: false,  
  42.         width: 200  
  43.     }, {  
  44.         name: 'City',  
  45.         field: 'City',  
  46.         headerCellClass: 'tablesorter-header-inner',  
  47.         enableCellEdit: true,  
  48.         enableFiltering: true,  
  49.         width: 150  
  50.     }, {  
  51.         name: 'Country',  
  52.         field: 'Country',  
  53.         headerCellClass: 'tablesorter-header-inner',  
  54.         enableCellEdit: true,  
  55.         enableFiltering: true,  
  56.         width: 150  
  57.     }, {  
  58.         name: 'Notes',  
  59.         field: 'Notes',  
  60.         headerCellClass: 'tablesorter-header-inner',  
  61.         enableCellEdit: true,  
  62.         enableFiltering: false,  
  63.         width: 800  
  64.     }];  
  65.     //Used to bind ui-grid  
  66.     $scope.gridOptions = {  
  67.         customScroller: function myScrolling(uiGridViewport, scrollHandler) {  
  68.             uiGridViewport.on('scroll'function myScrollingOverride(event) {  
  69.                 $scope.scroll.top = uiGridViewport[0].scrollTop;  
  70.                 $scope.scroll.left = uiGridViewport[0].scrollLeft;  
  71.                 // You should always pass the event to the callback since ui-grid needs it  
  72.                 scrollHandler(event);  
  73.             });  
  74.         },  
  75.         enableFiltering: false,  
  76.         onRegisterApi: function(gridApi) {  
  77.             $scope.gridApi = gridApi;  
  78.         },  
  79.         columnDefs: $scope.columnDefs,  
  80.         data: 'Employees',  
  81.     };  
  82. });  
Global

Now, add a few lines in Global.asax in Application_Start event.

  1. GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings  
  2. .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;  
  3. GlobalConfiguration.Configuration.Formatters  
  4. .Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);   

Now, add the mandatory packages given below, using NuGet Package Manager.

Bundling

Bundle the required styles and scripts.

Add the bundles given below in BundleConfig.cs

  1. bundles.Add(new StyleBundle("~/Content/css").Include(  
  2. "~/Content/bootstrap.css",  
  3. "~/Content/site.css",  
  4. "~/Content/ui-grid.css"));  
  5. bundles.Add(new ScriptBundle("~/bundles/uigrid").Include(  
  6. "~/Scripts/ui-grid.min.js"));  
  7. bundles.Add(new ScriptBundle("~/bundles/angular").Include(  
  8. "~/Scripts/angular.min.js",  
  9. "~/Angular/Services/employees.js"));   

Render all the scripts and styles in _Loyout.cshtml
  1. @Styles.Render("~/Content/css")  
  2. @Scripts.Render("~/bundles/modernizr")  
  3. @Scripts.Render("~/bundles/jquery")  
  4. @Scripts.Render("~/bundles/bootstrap")  
  5. @Scripts.Render("~/bundles/angular")  
  6. @Scripts.Render("~/bundles/uigrid")  
  7. @RenderSection("scripts", required: false)  

View
  1. @ {  
  2.     ViewBag.Title = "Index";  
  3.     Layout = "~/Views/Shared/_Layout.cshtml";  
  4. } < h2 > Employees < /h2> < div ng - app = "employeeapp"  
  5. ng - controller = "employeecontroller" > < div class = "row" > < label class = "col-sm-2" > Scroll Top: < /label> < div class = "col-sm-4" > {  
  6.     {  
  7.         scroll.top  
  8.     }  
  9. } < /div> < label class = "col-sm-2" > Scroll Left: < /label> < div class = "col-sm-4" > {  
  10.     {  
  11.         scroll.left  
  12.     }  
  13. } < /div> < /div> < div ui - grid = "gridOptions"  
  14. ui - grid - pagination ui - grid - selection class = "grid"  
  15. ui - grid - auto - resize > < /div> < /div> < style > .grid {  
  16.     width: 100 % ;  
  17.     height: 400 px;  
  18. } < /style>  

Output

Conclusion

In this article, we have seen how to implement custom scroll bar in angular ui-grid with Web API with an Entity Framework in MVC. If you have any question or comments, drop me a line in the comments section.