0

Im trying to do a custom sort for a table using angular.js. My angular module looks like this,

angular.module('app', ['ui.bootstrap', 'ngAnimate'])
angular.factory('sortable', ['$filter', '$rootScope', function($filter, $rootScope){

return function (scope, data, itemsPerPage, initSortingOrder) {

scope.sortingOrder = initSortingOrder;
scope.reverse = false;
scope.filteredItems = [];
scope.groupedItems = [];
scope.itemsPerPage = itemsPerPage;
scope.pagedItems = [];
scope.currentPage = 1;
scope.items = data;
scope.maxSize = 5;

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, $rootScope.query);

      // take care of the sorting order
    if (scope.sortingOrder !== '') {
        scope.filteredItems = $filter('orderBy')(scope.filteredItems, scope.sortingOrder, scope.reverse);
    }

      scope.currentPage = 1;

      // now group by pages
      scope.groupToPages();

      // reset the total items for the pagination buttons
      scope.totalItems = scope.filteredItems.length;
  };


  // 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;
  };


  // functions have been described process the data for display
  scope.search();


  // change sorting order
  scope.sort_by = function(newSortingOrder) {
      if (scope.sortingOrder == newSortingOrder)
          scope.reverse = !scope.reverse;

      scope.sortingOrder = newSortingOrder;

      // call search again to make sort affect whole query
      scope.search();
  };

  scope.sort_by(initSortingOrder);
  scope.totalItems = scope.filteredItems.length;
  }

}])

  .controller('main', [ '$scope', '$rootScope', 'sortable', function($scope, $rootScope, sortable) {


$rootScope.query = '';

$scope.gridToggle = true;

$scope.onQueryChange = function(val){
   $rootScope.query = val;
   $scope.search();
};

var items = [
  { 'icon' : 'm-desktop', 'name' : 'Jerry\'s Blog',          'date' : '06/03/2016', 'user' : { 'name' : 'Jerry',   'color' : '#4677A7'} },
  { 'icon' : 'm-form',    'name' : 'Ape\'s Capture Form',    'date' : '01/06/2013', 'user' : { 'name' : 'Ape',     'color' : '#09ABC5'} },
  { 'icon' : 'm-phone',   'name' : 'Some Mobile Site',       'date' : '05/06/2015', 'user' : { 'name' : 'Someone', 'color' : '#456183'} },
  { 'icon' : 'm-bell',    'name' : 'Fish\'s Wordpress Site', 'date' : '04/06/2013', 'user' : { 'name' : 'Fish',    'color' : '#1CB7BB'} },
  { 'icon' : 'm-group',   'name' : 'Kitty Kat Kapture Form', 'date' : '05/06/2015', 'user' : { 'name' : 'Kitty',   'color' : '#1D9D9D'} }
];

sortable($scope, items, 6, 'updated_at');

  }]);

The sorting function works fine for strings. How do i go about converting a string date into a angular date object and then sort.

this is the entire html ,

<body ng-app="app" ng-controller="main">
  <header>

  <h1>Objects <span>( {{ items.length }} )</span></h1>
</header>

<div class="ctrls">

  <div class="filter">
    <span class="m m-search"></span>
    <input type="text" ng-model="searchies" ng-change="onQueryChange(searchies)" class="form-control" placeholder="Filter">
  </div>

  <div class="grid-toggle">
    <a ng-click="gridToggle = !gridToggle" ng-class="{ 'active' : gridToggle }">
      <span class="m m-squares"></span>
      <span class="m m-form"></span>
    </a>
  </div>

</div>


<div class="container">

  <ul class="grid" ng-class="{ 'grid-list' : gridToggle, 'grid-thumb' : !gridToggle }">
    <li class="grid-head">
      <ul>
        <li style="width:40%"><a ng-click="sort_by('name')">Name</a></li>
        <li style="width:30%"><a ng-click="sort_by('user.name')">User</a></li>
          <li style="width:15%"><a ng-click="sort_by('date')">Date</a></li>
        <li style="width:15%"></li>
      </ul>
    </li>
    <li class="grid-body animate-repeat" ng-repeat="item in pagedItems[currentPage - 1] | orderBy:sortingOrder:reverse" ng-class="{'last':$last}">

      <ul>
        <li>

          <span class="grid-icon m" ng-class="item.icon"></span>
          <span class="grid-title"><a href="#">{{ item.name }}</a></span>
        </li>

        <li>
          <span class="grid-user">
            <span class="grid-usericon" ng-style="{ 'background' : item.user.color }">{{ item.user.name }}</span>
            <span class="grid-username">Updated by {{ item.user.name }}</span>
          </span>
        </li>

        <li>
          <span class="grid-date">{{ item.date }}</span>
        </li>

        <li>
          <span class="grid-options"><a href="#"><span class="m m-ellipsis"></span></a></span>
        </li>
      </ul>

    </li>

    <li class="clear-fix"></li>

    <li class="pagination">
      <pager total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" max-size="maxSize" ng-change="pageChanged()"></pager>
      <p ng-if="itemsPerPage * currentPage < totalItems">
        Showing {{ itemsPerPage * currentPage - itemsPerPage + 1 }} - {{ itemsPerPage * currentPage }} of {{ totalItems }} total items
      </p>
      <p ng-if="itemsPerPage * currentPage >= totalItems">
        Showing {{ itemsPerPage * currentPage - itemsPerPage + 1 }} - {{ totalItems }} of {{ totalItems }} total items
      </p>
    </li>
  </ul>

</div>

vardha
  • 414
  • 7
  • 20

1 Answers1

1

It's not entirely clear what an item in pagedItems looks like, but if they are strings which represent dates, you can convert them to Date objects by using Date.parse(string).

See details here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

Once you have them as Date objects, you can sort them several ways. Here is an answer that will help you https://stackoverflow.com/a/10124053/5780097

Community
  • 1
  • 1
Raphi
  • 390
  • 2
  • 5
  • Please don't recommend using *Date.parse* (or the *Date* constructor to parse strings, they are equivalent). Built–in parsing is almost entirely implementation dependent and very unreliable across browsers. Date strings should be manually parsed, a library can help but usually isn't necessary. – RobG Jun 02 '16 at 22:58