Sunday, 16 August 2015

AngularJS filter: orderby Date

Angular provides orderBy only with string and numeric values. When we require to sort or order by Date we need custom filter, for which Angular helps us beautifully.

So, if you have an array in controller like:

$scope.employee = [];

//Uses: item in items | orderByDate: 'member_of_item'
    app.filter('orderByDate', function () {
        return function (input, dateProperty) {
            //dateProperty: string with single property
            input = input || [];

            var reverse = dateProperty.charAt(0) === '-';
            //if reverse: truncate '-' from dateProperty name
            dateProperty = reverse ? dateProperty.slice(1) : dateProperty;

            if (angular.isString(dateProperty) && input.length) {
                input.sort(function (a, b) {
                    var c = new Date(a[dateProperty]);
                    var d = new Date(b[dateProperty]);
                    return reverse ? d - c : c - d;
                });
            }
            return input;
        }
    });


//Uses: item in items | orderByDate: 'member_of_item' : 'member_of_item2'
    app.filter('orderByDateThenString', function () {
        return function (input, dateProperty, stringProperty) {
         
            input = input || [];

            var reverse = dateProperty.charAt(0) === '-';
            //if reverse: truncate '-' from dateProperty name
            dateProperty = reverse ? dateProperty.slice(1) : dateProperty;

            if (angular.isString(dateProperty) && angular.isString(stringProperty) && input.length) {
                input.sort(function (a, b) {
                    var c = new Date(a[dateProperty]);
                    var d = new Date(b[dateProperty]);
                    var alpha = a[stringProperty].toLowerCase() === b[stringProperty].toLowerCase() ? 0 : (a[stringProperty].toLowerCase() < b[stringProperty].toLowerCase() ? -1 : 1);
                    return (reverse ? d - c : c - d) || alpha;
                });
            }
            return input;
        }
    });