2

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

6
  • sorry but I did not quite what your question is. Can you clarify? Commented Feb 3, 2015 at 9:22
  • I updated the question now. I hope is clearer Commented Feb 3, 2015 at 9:31
  • Your question doesn't make any sense if you don't show us how you are trying to use the filter. Please add the relevant view HTML to your question. Commented Feb 3, 2015 at 9:42
  • I have added a link at the bottom : jsfiddle.net/c6BfQ/164 Commented Feb 3, 2015 at 9:52
  • @AhmedHMehiny I can see that, but all relevant information should be in your question, not on an external site. Commented Feb 3, 2015 at 9:53

2 Answers 2

2

Original Answer

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 their eventDate property. E.g. I want only objects with a eventDate 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-clicking 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.


Edit: 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.

Sign up to request clarification or add additional context in comments.

2 Comments

So for the scope all I have to do is define the ranges...Can you show me how it will be for the current day. Just to understand the concept. If you use the eventDataFilter for all the events , when I call it for only today example how it will be ?? Sorry, its hard to understand it
I updated my answer. Does this make it clear? You never call eventDataFilter, the ng-repeat that uses it gets updated every time $scope.currentDateRange changes (what it does when you click a link).
0

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') 
    };
}    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.