AngularJS sorting rows by table header

后端 未结 9 1897
旧巷少年郎
旧巷少年郎 2020-12-04 07:08

I have four table headers:

$scope.headers = [\"Header1\", \"Header2\", \"Header3\", \"Header4\"];

And I want to be able to sort my table by

相关标签:
9条回答
  • 2020-12-04 07:46

    Another way to do this in AngularJS is to use a Grid.

    The advantage with grids is that the row sorting behavior you are looking for is included by default.

    The functionality is well encapsulated. You don't need to add ng-click attributes, or use scope variables to maintain state:

        <body ng-controller="MyCtrl">
            <div class="gridStyle" ng-grid="gridOptions"></div>
        </body>
    

    You just add the grid options to your controller:

      $scope.gridOptions = {
        data: 'myData.employees',
        columnDefs: [{
          field: 'firstName',
          displayName: 'First Name'
        }, {
          field: 'lastName',
          displayName: 'Last Name'
        }, {
          field: 'age',
          displayName: 'Age'
        }]
      };
    

    Full working snippet attached:

    var app = angular.module('myApp', ['ngGrid', 'ngAnimate']);
    app.controller('MyCtrl', function($scope) {
    
      $scope.myData = {
        employees: [{
          firstName: 'John',
          lastName: 'Doe',
          age: 30
        }, {
          firstName: 'Frank',
          lastName: 'Burns',
          age: 54
        }, {
          firstName: 'Sue',
          lastName: 'Banter',
          age: 21
        }]
      };
    
      $scope.gridOptions = {
        data: 'myData.employees',
        columnDefs: [{
          field: 'firstName',
          displayName: 'First Name'
        }, {
          field: 'lastName',
          displayName: 'Last Name'
        }, {
          field: 'age',
          displayName: 'Age'
        }]
      };
    });
    /*style.css*/
    .gridStyle {
        border: 1px solid rgb(212,212,212);
        width: 400px;
        height: 200px
    }
    <!DOCTYPE html>
    <html ng-app="myApp">
        <head lang="en">
            <meta charset="utf-8">
            <title>Custom Plunker</title>
            <link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
            <link rel="stylesheet" type="text/css" href="style.css" />
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.js"></script>
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular-animate.js"></script>
            <script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
            <script type="text/javascript" src="main.js"></script>
        </head>
        <body ng-controller="MyCtrl">
            <div class="gridStyle" ng-grid="gridOptions"></div>
        </body>
    </html>

    0 讨论(0)
  • 2020-12-04 07:46

    Try this:

    First change your controller

        yourModuleName.controller("yourControllerName", function ($scope) {
            var list = [
                { H1:'A', H2:'B', H3:'C', H4:'d' },
                { H1:'E', H2:'B', H3:'F', H4:'G' },
                { H1:'C', H2:'H', H3:'L', H4:'M' },
                { H1:'I', H2:'B', H3:'E', H4:'A' }
            ];
    
            $scope.list = list;
    
            $scope.headers = ["Header1", "Header2", "Header3", "Header4"];
    
            $scope.sortColumn = 'Header1';
    
            $scope.reverseSort = false;
    
            $scope.sortData = function (columnIndex) {
                $scope.reverseSort = ($scope.sortColumn == $scope.headers[columnIndex]) ? !$scope.reverseSort : false;
    
                $scope.sortColumn = $scope.headers[columnIndex];
            }
    
        });
    

    then change code in html side like this

        <th ng-repeat= "header in headers">
                <a ng-click="sortData($index)"> {{headers[$index]}} </a>
        </th>
        <tr ng-repeat "result in results | orderBy : sortColumn : reverseSort">
            <td> {{results.h1}} </td>
            <td> {{results.h2}} </td>
            <td> {{results.h3}} </td>
            <td> {{results.h4}} </td>
        </tr>
    
    0 讨论(0)
  • 2020-12-04 07:48

    Here is a fiddle that can help you to do this with AngularJS
    http://jsfiddle.net/patxy/D2FsZ/

    <th ng:repeat="(i,th) in head" ng:class="selectedCls(i)" ng:click="changeSorting(i)">
         {{th}}
    </th>
    

    Then something like this for your data:

    <tr ng:repeat="row in body.$orderBy(sort.column, sort.descending)">
        <td>{{row.a}}</td>
        <td>{{row.b}}</td>
        <td>{{row.c}}</td>
    </tr>
    

    With such functions in your AngularJS controller:

    scope.sort = {
        column: 'b',
        descending: false
    };
    
    scope.selectedCls = function(column) {
        return column == scope.sort.column && 'sort-' + scope.sort.descending;
    };
    
    scope.changeSorting = function(column) {
        var sort = scope.sort;
        if (sort.column == column) {
            sort.descending = !sort.descending;
        } else {
            sort.column = column;
            sort.descending = false;
        }
    };
    
    0 讨论(0)
  • 2020-12-04 07:49

    You can use this code without arrows.....i.e by clicking on header it automatically shows ascending and descending order of elements

        <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script src="scripts/angular.min.js"></script>
        <script src="Scripts/Script.js"></script>
        <style>
            table {
                border-collapse: collapse;
                font-family: Arial;
            }
    
            td {
                border: 1px solid black;
                padding: 5px;
            }
    
            th {
                border: 1px solid black;
                padding: 5px;
                text-align: left;
            }
        </style>
    </head>
    <body ng-app="myModule">
        <div ng-controller="myController">
    
            <br /><br />
            <table>
                <thead>
                    <tr>
                        <th>
                            <a href="#" ng-click="orderByField='name'; reverseSort = !reverseSort">
                                Name
                            </a>
                        </th>
                        <th>
                            <a href="#" ng-click="orderByField='dateOfBirth'; reverseSort = !reverseSort">
                                Date Of Birth
                            </a>
                        </th>
                        <th>
                            <a href="#" ng-click="orderByField='gender'; reverseSort = !reverseSort">
                               Gender
                            </a>
                        </th>
                        <th>
                            <a href="#" ng-click="orderByField='salary'; reverseSort = !reverseSort">
                                Salary
                            </a>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="employee in employees | orderBy:orderByField:reverseSort">
                        <td>
                            {{ employee.name }}
                        </td>
                        <td>
                            {{ employee.dateOfBirth | date:"dd/MM/yyyy" }}
                        </td>
                        <td>
                            {{ employee.gender }}
                        </td>
                        <td>
                            {{ employee.salary  }}
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
        <script>
            var app = angular
            .module("myModule", [])
            .controller("myController", function ($scope) {
    
                var employees = [
                    {
                        name: "Ben", dateOfBirth: new Date("November 23, 1980"),
                        gender: "Male", salary: 55000
                    },
                    {
                        name: "Sara", dateOfBirth: new Date("May 05, 1970"),
                        gender: "Female", salary: 68000
                    },
                    {
                        name: "Mark", dateOfBirth: new Date("August 15, 1974"),
                        gender: "Male", salary: 57000
                    },
                    {
                        name: "Pam", dateOfBirth: new Date("October 27, 1979"),
                        gender: "Female", salary: 53000
                    },
                    {
                        name: "Todd", dateOfBirth: new Date("December 30, 1983"),
                        gender: "Male", salary: 60000
                    }
                ];
    
                $scope.employees = employees;
                $scope.orderByField = 'name';
                $scope.reverseSort = false;
    
            });
        </script>
    </body>
    </html>
    
    0 讨论(0)
  • 2020-12-04 07:50

    Use a third-party JavaScript library. It will give you that and much more. A good example is datatables (if you are also using jQuery): https://datatables.net

    Or just order your bound array in $scope.results when the header is clicked.

    0 讨论(0)
  • 2020-12-04 07:56

    I think this working CodePen example that I created will show you exactly how to do what you want.

    The template:

    <section ng-app="app" ng-controller="MainCtrl">
      <span class="label">Ordered By: {{orderByField}}, Reverse Sort: {{reverseSort}}</span><br><br>
      <table class="table table-bordered">
        <thead>
          <tr>
            <th>
              <a href="#" ng-click="orderByField='firstName'; reverseSort = !reverseSort">
              First Name <span ng-show="orderByField == 'firstName'"><span ng-show="!reverseSort">^</span><span ng-show="reverseSort">v</span></span>
              </a>
            </th>
            <th>
              <a href="#" ng-click="orderByField='lastName'; reverseSort = !reverseSort">
                Last Name <span ng-show="orderByField == 'lastName'"><span ng-show="!reverseSort">^</span><span ng-show="reverseSort">v</span></span>
              </a>
            </th>
            <th>
              <a href="#" ng-click="orderByField='age'; reverseSort = !reverseSort">
              Age <span ng-show="orderByField == 'age'"><span ng-show="!reverseSort">^</span><span ng-show="reverseSort">v</span></span>
              </a>
            </th>
          </tr>
        </thead>
        <tbody>
          <tr ng-repeat="emp in data.employees|orderBy:orderByField:reverseSort">
            <td>{{emp.firstName}}</td>
            <td>{{emp.lastName}}</td>
            <td>{{emp.age}}</td>
          </tr>
        </tbody>
      </table>
    </section>
    

    The JavaScript code:

    var app = angular.module('app', []);
    
    app.controller('MainCtrl', function($scope) {
      $scope.orderByField = 'firstName';
      $scope.reverseSort = false;
    
      $scope.data = {
        employees: [{
          firstName: 'John',
          lastName: 'Doe',
          age: 30
        },{
          firstName: 'Frank',
          lastName: 'Burns',
          age: 54
        },{
          firstName: 'Sue',
          lastName: 'Banter',
          age: 21
        }]
      };
    });
    
    0 讨论(0)
提交回复
热议问题