Paginate By Week - AngularJS

1.7k Views Asked by At

I am trying to paginate a list of events (using ng-repeat) by week in AngularJS. I have a custom filter working that only displays the events within the current week, but I am trying to add functionality to look at future and past weeks.

Here is the filter I am using for the event lists -

$scope.week = function(item) {
    var weekStart = moment().startOf('week');
    var weekEnd = moment().endOf('week');
    var eventTime = moment(item.jsdatetime);
        if (eventTime >= weekStart && eventTime <= weekEnd) return true; 
            return false;
};

I have tried using ng-click to call a function that uses moment.js to .add(7, 'days'); to the weekStart and weekEnd variables but can't seem to get it to work.

Any help would be appreciated.

Here's a CodePen with the basic functionality going on - http://codepen.io/drewbietron/pen/xbKNdK

2

There are 2 best solutions below

3
On BEST ANSWER

The moment() always return the current date/time.

You need to store a reference to it to a variable, and then use that for manipulations.
(and since you have other variables depending on it, i would create a function that sets all those variables at once)

So in the controller i changed the top part to

var currentDate,
    weekStart,
    weekEnd,
    shortWeekFormat = 'MMMM Do';

function setCurrentDate(aMoment){
  currentDate = aMoment,
  weekStart = currentDate.clone().startOf('week'),
  weekEnd = currentDate.clone().endOf('week')
}

// initialize with current date
setCurrentDate(moment());

// use these methods for displaying 
$scope.currentWeek = function(){ return currentDate.format(shortWeekFormat); }; 
$scope.currentWeekStart = function(){ return weekStart.format(shortWeekFormat); };
$scope.currentWeekEnd = function(){ return weekEnd.format(shortWeekFormat); };

Then create two methods for going to next/previous week

$scope.nextWeek = function(){
  setCurrentDate(currentDate.add(7,'days'));
};
$scope.prevWeek = function(){
  setCurrentDate(currentDate.subtract(7,'days'));
};

(moment.js implements valueOf so you do direct comparisons)
And finally change your week filter to actually compare the dates (using .isSame(), .isBefore() and .isAfter()) instead of the moment objects (which was wrong as you cannot do direct comparisons on custom objects)

$scope.week = function(item) {
    var eventTime = moment(item.jsdatetime);

    if ((eventTime.isSame(weekStart) || eventTime.isAfter(weekStart))&& 
        (eventTime.isSame(weekEnd) || eventTime.isBefore(weekEnd))) return true; 

    return false;
};

$scope.week = function(item) {
    var eventTime = moment(item.jsdatetime);

    return (eventTime >= weekStart && eventTime <= weekEnd);
};

(you also, most likely, want the ng-repeat on the li elements and not the ul)

Demo at http://codepen.io/gpetrioli/pen/QwLRQB

4
On

The weekStart and weekEnd variables don't exist outside of the scope of week(item). If you're using ngClick to call a function that tries to modify those variables, it'll just return undefined. I don't know how your layout is but I would pull those two variables outside of the week function and make them $scope variables.

Additionally, I would have ngClick call a function that would change the two $scope variables (either adds 7 or subtracts 7 depending on which direction you want to go in).

$scope.weekStart = moment().startOf('week');
$scope.weekEnd = moment().endOf('week');

$scope.week = function(item) {
    var eventTime = moment(item.jsdatetime);
    if (eventTime >= $scope.weekStart && eventTime <= $scope.weekEnd) return true; 
      return false;
    };

$scope.update= function(direction) {
    $scope.weekStart.add(direction, 'days');
    $scope.weekEnd.add(direction, 'days');
}

And create two buttons in your view:

<a href="#" ng-click="update(-7)">Previous week</a>
<a href="#" ng-click="update(7)">Next week</a>