Reputation: 135
I want to filter data by event date. I have the following options to filter: current day, current month and current year. Below you can see what I have so far:
function dateCtrl($scope) {
var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth();
var curr_year = d.getFullYear();
$scope.dateToday = Date.parse(curr_month + "/" + curr_date + "/" + curr_year);
$scope.dateRange = "";
$scope.dataModels = [
{age:5,name:'John Lennon',eventDate:"1390524400000"},
{age:12,name:'Nick Young',eventDate:"1377500400000"},
{age:10,name:'Mike Johnson',eventDate:"1374044400000"},
{age:15,name:'Lisa Leslie',eventDate:"1335942000000"}
];
$scope.eventDateFilter = function(column) {
if(column === 'today') {
$scope.dateRange = $scope.dateToday;
} else if (column === 'currentWeek') {
//need logic
} else if (column === 'currnetMonth') {
//need logic
} else if (column === 'currnetYear') {
//need logic
}else {
$scope.dateRange = "";
}
}
}
and here I have the controller:
<div ng:controller="dateCtrl">
Date Filter
<ul class="inline">
<li><a href ng-click="eventDateFilter('all')">All</a></li>
<li><a href ng-click="eventDateFilter('today')">Today</a></li>
<li><a href ng-click="eventDateFilter('pastWeek')">Past Week</a></li>
<li><a href ng-click="eventDateFilter('pastMonth')">Past Month</a></li>
</ul>
<table class="table">
<tr>
<th>Name</th>
<th>Age</th>
<th>Event Date</th>
</tr>
<tr ng:repeat="data in dataModels | filter:dateRange">
<td>{{data.name}}</td>
<td>{{data.age}}</td>
<td>{{data.eventDate | date:medium}}</td>
</tr>
</table>
</div>
I have the entire code here : The code
Upvotes: 2
Views: 1787
Reputation: 672
To simplify the calculation you could use moment.js
function getCurrentDayRange() {
return {
from: moment().startOf('day'),
to: moment().endOf('day')
};
}
function getCurrentWeekRange() {
return {
from: moment().startOf('week'),
to: moment().endOf('week')
};
};
function getCurrentMonthRange() {
return {
from: moment().startOf('month'),
to: moment().endOf('month')
};
}
function getCurrentYearRange() {
return {
from: moment().startOf('year'),
to: moment().endOf('year')
};
}
Upvotes: 0
Reputation: 2771
First, let me paraphrase your question (to make sure I answer to what you asked), as I'm not 100% sure about it:
I have a list of
{age: <Number>, name: <String>, eventDate: <Timestamp>}
objects and I want to filter them by theireventDate
property. E.g. I want only objects with aeventDate
in the current week.
To achieve this you have to minimally reorder your Controller:
$scope.dateRanges = {
all: {from: 0, to: Number.MAX_VALUE},
// defining getCurrent[Week,Month,Year]Range() left open for you,
// https://stackoverflow.com/questions/8381427/ is a good start
week: getCurrentWeekRange(),
month: getCurrentMonthRange(),
year: getCurrentYearRange(),
};
$scope.currentDateRange = $scope.dateRanges.all; // as initial value
$scope.eventDateFilter = function(event) {
return $scope.currentDateRange.from <= event.eventDate
&& event.eventDate <= $scope.currentDateRange.to;
});
Then you can use it in the template as
<ul>
<li ng-click="currentDateRange = dateRanges.all">show all</li>
<li ng-click="currentDateRange = dateRanges.week">show week</li>
<li ng-click="currentDateRange = dateRanges.month">show month</li>
<li ng-click="currentDateRange = dateRanges.year">show year</li>
</ul>
<table>
<tr ng-repeat="data in dataModels | filter:eventDateFilter">
<td>{{data.name}}</td>
<td>{{data.age}}</td>
<td>{{data.eventDate | date:medium}}</td>
</tr>
</table>
The important difference is that you don't call functions on ng-click
ing your navigation, but just change the model (and let angular update the view).
This is what we were used to do (from jQuery & the likes) for years. But with angular you need a mind shift. The template views the model and updates automatically once the model changes. You don't have to initiate those updates yourself.
getCurrentDayRange()
As the question arose in the comments, here's how you create a range (e.g. for the current day). It is heavily inspired by this answer to the question I cited above.
function getCurrentDayRange() {
// new Date() returns the moment it is called by default
return {
// the day starts at 00:00:00.000
from: new Date().setHours(0, 0, 0, 0),
// it ends at 23:59:59.999
to: new Date().setHours(23, 59, 59, 999)
};
}
On the question when to call eventDateFilter
: it gets called by the AngularJS digest loop, you never call it yourself. See the Scope documentation for a deep-dive.
Upvotes: 2