AngularJS Tables

In AngularJS, tables are more than just static grids; they are dynamic components capable of handling large datasets with ease. By leveraging AngularJS directives and two-way data binding, you can build tables that update in real-time, filter results as a user types, and sort columns without a page refresh. This makes AngularJS an excellent choice for building administrative dashboards, reporting tools, and data-heavy management systems.

Developer Tip: While HTML tables are great for data, always ensure your tables are responsive by wrapping them in a container with overflow-x: auto or using CSS frameworks like Bootstrap to handle mobile views.

Key Concepts of AngularJS Tables

  1. ng-repeat: The workhorse of AngularJS tables. It iterates over a collection (like an array of objects) and clones the HTML element for each item in the list.
  2. ng-model: Used typically in a search input above the table to bind the user's input to a filtering variable.
  3. ng-click: Attached to table headers to trigger sorting functions or to row buttons for actions like "Edit" or "Delete."
  4. ng-show/ng-hide: Perfect for displaying "No results found" messages or toggling the visibility of specific columns based on user roles.
Best Practice: When using ng-repeat, always use track by (e.g., track by person.id) if your data has unique identifiers. This helps AngularJS associate DOM elements with data items, significantly improving rendering performance when the data changes.

 

Basic Example of a Table

Creating a table starts with defining your data in the controller and then using ng-repeat in your HTML to loop through that data. This keeps your view synchronized with your underlying data model automatically.

Simple Table Example

<div ng-app="myApp" ng-controller="myCtrl">
  <table border="1" width="100%">
    <thead>
      <tr>
        <th>Name</th>
        <th>Age</th>
        <th>City</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="person in people">
        <td>{{person.name}}</td>
        <td>{{person.age}}</td>
        <td>{{person.city}}</td>
      </tr>
    </tbody>
  </table>
</div>

<script>
  var app = angular.module("myApp", []);
  app.controller("myCtrl", function($scope) {
    $scope.people = [
      { name: "John", age: 28, city: "New York" },
      { name: "Jane", age: 32, city: "Chicago" },
      { name: "Mike", age: 45, city: "Los Angeles" }
    ];
  });
</script>
  • ng-repeat="person in people": This tells AngularJS to create one <tr> for every object in the people array. Within each row, person acts as a local variable.
Common Mistake: Forgetting to initialize the module or controller. If your table looks like a bunch of curly braces (e.g., {{person.name}}), check that ng-app and ng-controller are correctly spelled and attached to the parent elements.

 

Sorting Table Data

In a real-world application, users expect to click a column header to sort the data. You can achieve this using the orderBy filter. By changing a variable in your controller via ng-click, the table will re-sort itself instantly.

Example with Sorting

<div ng-app="myApp" ng-controller="myCtrl">
  <table border="1" width="100%">
    <thead>
      <tr>
        <th ng-click="sortData('name')" style="cursor:pointer">Name</th>
        <th ng-click="sortData('age')" style="cursor:pointer">Age</th>
        <th ng-click="sortData('city')" style="cursor:pointer">City</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="person in people | orderBy:sortColumn:reverseSort">
        <td>{{person.name}}</td>
        <td>{{person.age}}</td>
        <td>{{person.city}}</td>
      </tr>
    </tbody>
  </table>
</div>

<script>
  var app = angular.module("myApp", []);
  app.controller("myCtrl", function($scope) {
    $scope.people = [
      { name: "John", age: 28, city: "New York" },
      { name: "Jane", age: 32, city: "Chicago" },
      { name: "Mike", age: 45, city: "Los Angeles" }
    ];

    $scope.sortColumn = 'name';
    $scope.reverseSort = false;

    $scope.sortData = function(column) {
      $scope.reverseSort = ($scope.sortColumn == column) ? !$scope.reverseSort : false;
      $scope.sortColumn = column;
    };
  });
</script>
  • orderBy:sortColumn:reverseSort: This filter takes the property to sort by and a boolean for ascending/descending order.
  • ng-click="sortData('name')": This function toggles the sort direction if the same column is clicked twice.
Developer Tip: Use CSS classes to add visual indicators like up/down arrows (â–²/â–¼) in your table headers to let users know which column is currently being sorted.

 

Filtering Table Data

The filter filter is one of the most powerful features in AngularJS. It allows users to search through an entire table in real-time. By binding an input field to a model, you can pipe that model directly into the ng-repeat directive.

Example with Filtering

<div ng-app="myApp" ng-controller="myCtrl">
  <p>Type to filter results:</p>
  <input type="text" ng-model="searchText" placeholder="Search by name, age, or city..." style="margin-bottom: 10px; width: 300px;">
  
  <table border="1" width="100%">
    <thead>
      <tr>
        <th>Name</th>
        <th>Age</th>
        <th>City</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="person in people | filter:searchText">
        <td>{{person.name}}</td>
        <td>{{person.age}}</td>
        <td>{{person.city}}</td>
      </tr>
      <tr ng-if="(people | filter:searchText).length == 0">
        <td colspan="3" style="text-align:center">No matching records found</td>
      </tr>
    </tbody>
  </table>
</div>

<script>
  var app = angular.module("myApp", []);
  app.controller("myCtrl", function($scope) {
    $scope.people = [
      { name: "John", age: 28, city: "New York" },
      { name: "Jane", age: 32, city: "Chicago" },
      { name: "Mike", age: 45, city: "Los Angeles" }
    ];
  });
</script>
  • filter:searchText: This automatically searches all properties of the objects in the array. If the user types "New", only "New York" will remain.
  • ng-if: This is a useful addition to show a message when the filter returns no results.
Watch Out: Filtering large datasets (thousands of rows) on the client side can lead to UI lag. For very large tables, consider implementing server-side filtering.

 

Pagination for Tables

When you have dozens or hundreds of rows, you shouldn't display them all at once. Pagination improves the user experience and page load times. While many developers use libraries, understanding how to slice your data manually is crucial for custom implementations.

Example with Pagination (Manual)

<div ng-app="myApp" ng-controller="myCtrl">
  <table border="1" width="100%">
    <thead>
      <tr>
        <th>Name</th>
        <th>Age</th>
        <th>City</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="person in people.slice(((currentPage-1)*pageSize), (currentPage*pageSize))">
        <td>{{person.name}}</td>
        <td>{{person.age}}</td>
        <td>{{person.city}}</td>
      </tr>
    </tbody>
  </table>
  
  <div style="margin-top:10px;">
    <button ng-disabled="currentPage == 1" ng-click="prevPage()">Previous</button>
    <span>Page {{currentPage}} of {{ numberOfPages() }}</span>
    <button ng-disabled="currentPage >= numberOfPages()" ng-click="nextPage()">Next</button>
  </div>
</div>

<script>
  var app = angular.module("myApp", []);
  app.controller("myCtrl", function($scope) {
    $scope.people = [
      { name: "John", age: 28, city: "New York" },
      { name: "Jane", age: 32, city: "Chicago" },
      { name: "Mike", age: 45, city: "Los Angeles" },
      { name: "Emma", age: 25, city: "Boston" },
      { name: "Lucas", age: 30, city: "Dallas" },
      { name: "Sophia", age: 22, city: "Miami" }
    ];

    $scope.currentPage = 1;
    $scope.pageSize = 2;

    $scope.numberOfPages = function() {
      return Math.ceil($scope.people.length / $scope.pageSize);
    };

    $scope.prevPage = function() {
      if ($scope.currentPage > 1) $scope.currentPage--;
    };

    $scope.nextPage = function() {
      if ($scope.currentPage < $scope.numberOfPages()) $scope.currentPage++;
    };
  });
</script>
  • people.slice(...): This JavaScript method creates a new array containing only the items for the current page. The formula (currentPage-1)*pageSize calculates the starting index.
  • ng-disabled: A clean way to prevent users from clicking "Previous" on the first page or "Next" on the last page.
Best Practice: In production apps, keep your pagination logic in a custom filter or a service to keep your controller clean and your code reusable across different tables.

 

Summary

AngularJS provides a robust framework for building interactive tables that feel fast and responsive. By mastering ng-repeat, you can render complex data structures, while the built-in filter and orderBy tools allow you to provide advanced search and sort functionality with minimal code. Whether you are building a small internal tool or a complex data dashboard, these table manipulation techniques are essential skills for any AngularJS developer.