AngularJS sorting rows by table header

人盡茶涼 提交于 2019-11-28 02:52:37
Adam Thomas

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
    }]
  };
});
Deblaton Jean-Philippe

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;
    }
};
David Rinck

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>
lastlink

Here is an example that sorts by the header. This table is dynamic and changes with the JSON size.

I was able to build a dynamic table off of some other people's examples and documentation. http://jsfiddle.net/lastlink/v7pszemn/1/

<tr>
    <th class="{{header}}" ng-repeat="(header, value) in items[0]" ng-click="changeSorting(header)">
    {{header}}
  <i ng-class="selectedCls2(header)"></i>
</tr>

<tbody>
    <tr ng-repeat="row in pagedItems[currentPage] | orderBy:sort.sortingOrder:sort.reverse">
        <td ng-repeat="cell in row">
              {{cell}}
       </td>
    </tr>

Although the columns are out of order, on my .NET project they are in order.

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>
Eran H.

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.

I'm just getting my feet wet with angular, but I found this great tutorial.
Here's a working plunk I put together with credit to Scott Allen and the above tutorial. Click search to display the sortable table.

For each column header you need to make it clickable - ng-click on a link will work. This will set the sortName of the column to sort.

<th>
     <a href="#" ng-click="sortName='name'; sortReverse = !sortReverse">
          <span ng-show="sortName == 'name' && sortReverse" class="glyphicon glyphicon-triangle-bottom"></span>
          <span ng-show="sortName == 'name' && !sortReverse" class="glyphicon glyphicon-triangle-top"></span>
           Name
     </a>
</th>

Then, in the table body you can pipe in that sortName in the orderBy filter orderBy:sortName:sortReverse

<tr ng-repeat="repo in repos | orderBy:sortName:sortReverse | filter:searchRepos">
     <td>{{repo.name}}</td>
     <td class="tag tag-primary">{{repo.stargazers_count | number}}</td>
     <td>{{repo.language}}</td>
</tr>
----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>
saiteja chowdary

I had found the easiest way to solve this question. If efficient you can use

HTML code: import angular.min.js and the angular.route.js library

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>like/dislike</title>
</head>
<body ng-app="myapp" ng-controller="likedislikecntrl" bgcolor="#9acd32">
<script src="./modules/angular.min.js"></script>
<script src="./modules/angular-route.js"></script>
<script src="./likedislikecntrl.js"></script>
</select></h1></p>
<table border="5" align="center">
<thead>
<th>professorname <select ng-model="sort1" style="background-color: 
chartreuse">
<option value="+name" >asc</option>
<option value="-name" >desc</option>
</select></th>
<th >Subject <select ng-model="sort1">
<option value="+subject" >asc</option>
<option value="-subject" >desc</option></select></th>
<th >Gender <select ng-model="sort1">
<option value="+gender">asc</option>
<option value="-gender">desc</option></select></th>
<th >Likes <select ng-model="sort1">
<option value="+likes" >asc</option>
<option value="-likes" >desc</option></select></th>
<th >Dislikes <select ng-model="sort1">
<option value="+dislikes" >asc</option>
<option value="-dislikes">desc</option></select></th>
<th rowspan="2">Like/Dislike</th>
</thead>
<tbody>
<tr ng-repeat="sir in sirs | orderBy:sort1|orderBy:sort|limitTo:row" >
<td >{{sir.name}}</td>
<td>{{sir.subject|uppercase}}</td>
<td>{{sir.gender|lowercase}}</td>
<td>{{sir.likes}}</td>
<td>{{sir.dislikes}}</td>
<td><button ng-click="ldfi1(sir)" style="background-color:chartreuse" 
>Like</button></td>
<td><button ng-click="ldfd1(sir)" style="background-
color:chartreuse">Dislike</button></td>
</tr>
</tbody>
</table>
</body> 
</html>
JavaScript Code::likedislikecntrl.js

var app=angular.module("myapp",["ngRoute"]);

app.controller("likedislikecntrl",function ($scope) {
var sirs=[
    {name:"Srinivas",subject:"dmdw",gender:"male",likes:0,dislikes:0},
    {name:"Sharif",subject:"dms",gender:"male",likes:0,dislikes:0},
    {name:"Chaitanya",subject:"daa",gender:"male",likes:0,dislikes:0},
    {name:"Pranav",subject:"wt",gender:"male",likes:0,dislikes:0},
    {name:"Anil Chowdary",subject:"ds",gender:"male",likes:0,dislikes:0},
    {name:"Rajesh",subject:"mp",gender:"male",likes:0,dislikes:0},
    {name:"Deepak",subject:"dld",gender:"male",likes:0,dislikes:0},
    {name:"JP",subject:"mp",gender:"male",likes:0,dislikes:0},
    {name:"NagaDeepthi",subject:"oose",gender:"female",likes:0,dislikes:0},
    {name:"Swathi",subject:"ca",gender:"female",likes:0,dislikes:0},
    {name:"Madavilatha",subject:"cn",gender:"female",likes:0,dislikes:0}



]
$scope.sirs=sirs;
$scope.ldfi1=function (sir) {
    sir.likes++

}
$scope.ldfd1=function (sir) {
   sir.dislikes++

}
$scope.row=8;

})
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!