I am attempting to define my own sorting function using the documentation provided at http://docs.angularjs.org/api/ng.filter:orderBy.
Before I explain the code written, I will also mention the behaviour that I am expecting.
I have a table which contains a table header(th) and table data(td). When the user clicks on a column in the table (by column, I mean the th), the table data must sort based on the value in that column.
If the user clicks the same column again, then the sorting is changed to ascending / descending if the previous sorting criteria was descending / ascending respectively.
The user can sort using multiple columns. The first column selected is give the first priority. In case the first column value is the same, then the second column selected for sorting is used.
Now for the code. It can be found here: http://jsfiddle.net/xkjmv/
Problem is that the customSortFunction
returns the array as expected, but the sorting does not work - when the user clicks on the column header, the sorting should be either ascending or descending (basically toggle each time it is clicked).
I want to return an array of string predicates since I will have multiple columns to sort, but a single column sort using string predicate itself is not working
EDIT: You can check the console to see the output that the custom sort function returns, if it is not obvious from the code.
In this plunker you can find an example of what you'r looking for with other stuff, hope this help.
As blazemonger requested the code:
Controllers.js:
app.controller('ctrlRead', ['$scope', '$filter', 'Items', function($scope, $filter, Items) {
// init
$scope.sortingOrder = sortingOrder;
$scope.reverse = false;
$scope.filteredItems = [];
$scope.groupedItems = [];
$scope.itemsPerPage = 5;
$scope.pagedItems = [];
$scope.currentPage = 0;
//#####################################
// get the items from the Items service
Items.then(function(data){
$scope.items = data;
$scope.search();
});
//#####################################
var searchMatch = function (haystack, needle) {
if (!needle) {
return true;
}
return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
};
// init the filtered items
$scope.search = function () {
$scope.filteredItems = $filter('filter')($scope.items, function (item) {
for(var attr in item) {
if (searchMatch(attr, $scope.query)){
return true;
}
}
return false;
});
// take care of the sorting order
if ($scope.sortingOrder !== '') {
$scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sortingOrder, $scope.reverse);
}
$scope.currentPage = 0;
// now group by pages
$scope.groupToPages();
};
// calculate page in place
$scope.groupToPages = function () {
$scope.pagedItems = [];
for (var i = 0; i < $scope.filteredItems.length; i++) {
if (i % $scope.itemsPerPage === 0) {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ];
} else {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
}
}
};
$scope.range = function (start, end) {
var ret = [];
if (!end) {
end = start;
start = 0;
}
for (var i = start; i < end; i++) {
ret.push(i);
}
return ret;
};
$scope.prevPage = function () {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.nextPage = function () {
if ($scope.currentPage < $scope.pagedItems.length - 1) {
$scope.currentPage++;
}
};
$scope.setPage = function () {
$scope.currentPage = this.n;
};
// change sorting order
$scope.sort_by = function(newSortingOrder) {
if ($scope.sortingOrder == newSortingOrder){
$scope.reverse = !$scope.reverse;
}
$scope.sortingOrder = newSortingOrder;
// icon setup
$('th i').each(function(){
// icon reset
$(this).removeClass().addClass('icon-sort');
});
if ($scope.reverse){
$('th.'+newSortingOrder+' i').removeClass().addClass('icon-chevron-up');
}else{
$('th.'+newSortingOrder+' i').removeClass().addClass('icon-chevron-down');
}
};
}]);
app.js:
var app = angular.module('plunker', []);
items.json:
[
{
"ProgramCode":"3DS",
"ProgramGroup":"NCIM",
"EventCode":"20130424TX3DS",
"StartDate":"2013-04-22 00:00:00",
"FormalDate":"April 22-24, 2013",
"LocCity":"Richardson",
"LocState":"TX",
"LocAddress":"3400 Waterview Parkway, #200",
"LocName":"America First Insurance Company",
"Price":"0.00",
"LicenseeURL":null,
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"1",
"LocLatitude":"32.9695",
"LocLongitude":"-96.7409",
"EventType":"SSIH",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Richardson, TX",
"cls":"LIMITED_SEATS"
},
{
"ProgramCode":"PA",
"ProgramGroup":"CISR",
"EventCode":"20130422SDPA",
"StartDate":"2013-04-22 00:00:00",
"FormalDate":"April 22, 2013",
"LocCity":"Rapid City",
"LocState":"SD",
"LocAddress":"445 Mt. Rushmore Road",
"LocName":"Adoba Eco Hotel Rapid City \/ Mt. Rushmore",
"Price":"150.00",
"LicenseeURL":null,
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"19",
"LocLatitude":"44.0853",
"LocLongitude":"-103.213",
"EventType":"SS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Rapid City, SD",
"cls":"LIMITED_SEATS"
},
{
"ProgramCode":"RME",
"ProgramGroup":"CRM",
"EventCode":"20130425FLRME",
"StartDate":"2013-04-22 00:00:00",
"FormalDate":"April 22-25, 2013",
"LocCity":"Orlando",
"LocState":"FL",
"LocAddress":"8101 World Center Dr.",
"LocName":"Caribe Royale",
"Price":"430.00",
"LicenseeURL":"http:\/\/www.faia.com\/PV\/Core\/Events\/Events.aspx",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"32",
"LocLatitude":"28.3916",
"LocLongitude":"-81.4734",
"EventType":"LSIHOERS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Orlando, FL",
"cls":""
},
{
"ProgramCode":"ALM",
"ProgramGroup":"CISR",
"EventCode":"20130423MNALM",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Shoreview",
"LocState":"MN",
"LocAddress":"1000 Gramsie Road",
"LocName":"Hampton Inn",
"Price":"0.00",
"LicenseeURL":"http:\/\/www.iiaba.net\/MN\/03_Education\/01_Calender\/NAV_EDUCalendar?ContentPreference=MN&ActiveState=MN&ActiveTab=NA&ContentLevel1=EDUCTN&ContentLevel2=EDUCAL",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"40",
"LocLatitude":"45.0856",
"LocLongitude":"-93.1353",
"EventType":"LS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Shoreview, MN",
"cls":""
},
{
"ProgramCode":"AO",
"ProgramGroup":"CISR",
"EventCode":"20130423ILAO",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Bannockburn",
"LocState":"IL",
"LocAddress":"1500 South Lakeside Drive",
"LocName":"Mesirow Financial",
"Price":"0.00",
"LicenseeURL":"https:\/\/protech.piiai.org\/Events\/CalendarEventsListView.aspx",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"40",
"LocLatitude":"42.1693",
"LocLongitude":"-87.8656",
"EventType":"LS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Bannockburn, IL",
"cls":""
},
{
"ProgramCode":"AO",
"ProgramGroup":"CISR",
"EventCode":"20130423TXAO",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Richardson (North Dallas)",
"LocState":"TX",
"LocAddress":"900 East Lookout Drive",
"LocName":"Renaissance Dallas-Richardson Hotel",
"Price":"169.00",
"LicenseeURL":"http:\/\/www.iiah.org\/displaycommon.cfm?an=1&SUBARTICLENBR=228",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"16",
"LocLatitude":"32.9934",
"LocLongitude":"-96.659",
"EventType":"SS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Richardson (North Dallas), TX",
"cls":"LIMITED_SEATS"
},
{
"ProgramCode":"FUN",
"ProgramGroup":"CSRM",
"EventCode":"20130423CAFUN",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"San Bernardino",
"LocState":"CA",
"LocAddress":"1950 S. Sunwest Lane, Suite 102",
"LocName":"SCS JPA Conference Center",
"Price":"179.00",
"LicenseeURL":null,
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"16",
"LocLatitude":"34.0807",
"LocLongitude":"-117.274",
"EventType":"SS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"San Bernardino, CA",
"cls":"LIMITED_SEATS"
},
{
"ProgramCode":"IP",
"ProgramGroup":"CISR",
"EventCode":"20130423MAIP",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Peabody",
"LocState":"MA",
"LocAddress":"43 Newbury Street",
"LocName":"Springhill Suites by Marriott",
"Price":"0.00",
"LicenseeURL":"http:\/\/www.massagent.com\/education\/cisr.cfm",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"27",
"LocLatitude":"42.534",
"LocLongitude":"-70.9615",
"EventType":"LS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Peabody, MA",
"cls":""
},
{
"ProgramCode":"IP",
"ProgramGroup":"CISR",
"EventCode":"20130423MIIP",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Troy",
"LocState":"MI",
"LocAddress":"2601 West Big Beaver Road",
"LocName":"Somerset Inn",
"Price":"0.00",
"LicenseeURL":"http:\/\/www.michagent.org\/eweb\/DynamicPage.aspx?Site=AgentNet2&WebKey=2847b6dd-e47d-40ea-b5d1-504c5ff0f800",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"46",
"LocLatitude":"42.5635",
"LocLongitude":"-83.1841",
"EventType":"LS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Troy, MI",
"cls":""
},
{
"ProgramCode":"PA",
"ProgramGroup":"CISR",
"EventCode":"20130423CAPA",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Santa Clara (San Jose)",
"LocState":"CA",
"LocAddress":"5201 Great America Parkway",
"LocName":"Network Meeting Center",
"Price":"169.00",
"LicenseeURL":null,
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"17",
"LocLatitude":"37.3932",
"LocLongitude":"-121.961",
"EventType":"SS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Santa Clara (San Jose), CA",
"cls":"LIMITED_SEATS"
},
{
"ProgramCode":"PA",
"ProgramGroup":"CISR",
"EventCode":"20130423CTPA",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Middletown",
"LocState":"CT",
"LocAddress":"213 Court Street",
"LocName":"MiddleOak",
"Price":"0.00",
"LicenseeURL":"http:\/\/www.pia.org\/EDU\/schedule.php?state=CT",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"40",
"LocLatitude":"41.5537",
"LocLongitude":"-72.6632",
"EventType":"LS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Middletown, CT",
"cls":""
},
{
"ProgramCode":"PA",
"ProgramGroup":"CISR",
"EventCode":"20130423WVPA",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Charleston",
"LocState":"WV",
"LocAddress":"129 Summers Street",
"LocName":"Summit Conference Center",
"Price":"150.00",
"LicenseeURL":"http:\/\/www.ohiopia.com",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"4",
"LocLatitude":"38.3506",
"LocLongitude":"-81.6303",
"EventType":"SS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Charleston, WV",
"cls":"LIMITED_SEATS"
},
{
"ProgramCode":"PR",
"ProgramGroup":"CISR",
"EventCode":"20130423MEPR",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"South Portland",
"LocState":"ME",
"LocAddress":"363 Maine Mall Road",
"LocName":"DoubleTree by Hilton",
"Price":"0.00",
"LicenseeURL":"http:\/\/www.massagent.com\/education\/cisr.cfm",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"10",
"LocLatitude":"43.6315",
"LocLongitude":"-70.2727",
"EventType":"LS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"South Portland, ME",
"cls":""
},
{
"ProgramCode":"PR",
"ProgramGroup":"CISR",
"EventCode":"20130423MOPR",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Springfield",
"LocState":"MO",
"LocAddress":"2720 North Glenstone",
"LocName":"Holiday Inn Hotel and Suites",
"Price":"0.00",
"LicenseeURL":"http:\/\/www.iiaa.org\/MO\/03_Education\/01_Calender\/NAV_EDUCalender?ContentPreference=MO&ActiveState=MO&ActiveTab=STATE&ContentLevel1=EDUCTN&ContentLevel2=EDUCAL",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"40",
"LocLatitude":"37.2571",
"LocLongitude":"-93.2902",
"EventType":"LS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Springfield, MO",
"cls":""
},
{
"ProgramCode":"PR",
"ProgramGroup":"CISR",
"EventCode":"20130423NCPR",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Greensboro",
"LocState":"NC",
"LocAddress":"414 Gallimore Dairy Rd.",
"LocName":"BB&T Greensboro",
"Price":"0.00",
"LicenseeURL":"http:\/\/members.iianc.com\/wcm\/IIANC_Members\/Events\/List\/Core\/Events\/Events.aspx?hkey=90e5e7da-2e1f-4674-ae30-7c12ced0885c",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"16",
"LocLatitude":"36.0839",
"LocLongitude":"-79.9412",
"EventType":"LSIH",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Greensboro, NC",
"cls":""
},
{
"ProgramCode":"PR",
"ProgramGroup":"CISR",
"EventCode":"20130423NMPR",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Albuquerque",
"LocState":"NM",
"LocAddress":"2600 Louisiana, NE",
"LocName":"Sheraton Albuquerque Uptown",
"Price":"145.00",
"LicenseeURL":null,
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"15",
"LocLatitude":"35.1064",
"LocLongitude":"-106.579",
"EventType":"SS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Albuquerque, NM",
"cls":"LIMITED_SEATS"
},
{
"ProgramCode":"PR",
"ProgramGroup":"CISR",
"EventCode":"20130423SDPR",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Rapid City",
"LocState":"SD",
"LocAddress":"445 Mt. Rushmore Road",
"LocName":"Adoba Eco Hotel Rapid City \/ Mt. Rushmore",
"Price":"150.00",
"LicenseeURL":null,
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"18",
"LocLatitude":"44.0853",
"LocLongitude":"-103.213",
"EventType":"SS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Rapid City, SD",
"cls":"LIMITED_SEATS"
},
{
"ProgramCode":"SR",
"ProgramGroup":"CISR",
"EventCode":"20130423ORSR",
"StartDate":"2013-04-23 00:00:00",
"FormalDate":"April 23, 2013",
"LocCity":"Portland",
"LocState":"OR",
"LocAddress":"8931 SE Foster Road Suite 200",
"LocName":"Assurety Northwest",
"Price":"0.00",
"LicenseeURL":"http:\/\/www.piawest.com\/calendar-of-events",
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"40",
"LocLatitude":"45.4786",
"LocLongitude":"-122.562",
"EventType":"LS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"Portland, OR",
"cls":""
},
{
"ProgramCode":"ADM",
"ProgramGroup":"CSRM",
"EventCode":"20130424CAADM",
"StartDate":"2013-04-24 00:00:00",
"FormalDate":"April 24, 2013",
"LocCity":"San Bernardino",
"LocState":"CA",
"LocAddress":"1950 S. Sunwest Lane, Suite 102",
"LocName":"SCS JPA Conference Center",
"Price":"179.00",
"LicenseeURL":null,
"GateKeeper_length":"0",
"GateKeeperHTML":null,
"SeatsAreAvailable":"18",
"LocLatitude":"34.0807",
"LocLongitude":"-117.274",
"EventType":"SS",
"LocationUnivURL":null,
"UnivCourseNumber":null,
"UnivCourseType":"",
"UnivFaculty":null,
"Course_Type":"San Bernardino, CA",
"cls":"LIMITED_SEATS"
}
]
service.js:
app.factory('Items', ['$http', function($http){
var Url = "items.json";
var Items = $http.get(Url).then(function(response){
return response.data;
});
return Items;
}]);
index.html:
<!doctype html>
<html ng-app="plunker">
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link
rel="stylesheet"
href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css"
>
<link rel="stylesheet" href="style.css">
<link
rel="stylesheet"
href="//netdna.bootstrapcdn.com/font-awesome/3.0.2/css/font-awesome.css"
>
</head>
<body>
<script>
var sortingOrder = 'name';
</script>
<div ng-controller="ctrlRead">
<div class="input-append">
<input
type="text"
ng-model="query"
ng-change="search()"
placeholder="Search"
class="input-large search-query"
>
<span class="add-on"><i class="icon-search"></i></span>
</div>
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th class="LocName">
Id
<a ng-click="sort_by('LocName')">
<i class="icon-sort"></i>
</a>
</th>
<th class="Price">
Name
<a ng-click="sort_by('Price')">
<i class="icon-sort"></i>
</a>
</th>
<th class="Course_Type">
Description
<a ng-click="sort_by('Course_Type')">
<i class="icon-sort"></i>
</a>
</th>
<th class="cls">
Field 3
<a ng-click="sort_by('cls')">
<i class="icon-sort"></i>
</a>
</th>
<th class="SeatsAreAvailable">
Field 4
<a ng-click="sort_by('SeatsAreAvailable')">
<i class="icon-sort"></i>
</a>
</th>
<th class="StartDate">
Field 5
<a ng-click="sort_by('StartDate')">
<i class="icon-sort"></i>
</a>
</th>
</tr>
</thead>
<tfoot>
<td colspan="6">
<div class="pagination pull-right">
<ul>
<li ng-class="{disabled: currentPage == 0}">
<a href ng-click="prevPage()">« Prev</a>
</li>
<li
ng-click="setPage()"
ng-class="{active: n == currentPage}"
ng-repeat="n in range(pagedItems.length)"
>
<a href ng-bind="n + 1">1</a>
</li>
<li ng-class="{disabled: currentPage == pagedItems.length - 1}">
<a href ng-click="nextPage()">Next »</a>
</li>
</ul>
</div>
</td>
</tfoot>
<tbody>
<tr ng-repeat="item in pagedItems[currentPage] | orderBy:sortingOrder:reverse">
<td>{{item.LocName}}</td>
<td>{{item.Price}}</td>
<td>{{item.Course_Type}}</td>
<td>{{item.cls}}</td>
<td>{{item.SeatsAreAvailable}}</td>
<td>{{item.StartDate}}</td>
</tr>
</tbody>
</table>
</div>
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://code.angularjs.org/1.1.5/angular.js"></script>
<script src="app.js"></script>
<script src="controllers.js"></script>
<script src="services.js"></script>
</body>
</html>