Pawel
Pawel

Reputation: 162

AngularJS model filter with date range filter

I have in the view:

<tr dir-paginate="post in posts |orderBy:propertyName:reverse | filter: searchPost | itemsPerPage: pageSize">
<td>
        {{post.title}}
</td>
<td>
        {{post.content}}
</td>
<td>
        {{post.dateOfCreation | date:"medium"}}
</td>
</tr>

I also have filtering, which works on all the fields:

     <div>
        <input type="text" placeholder="Find by title..." ng-model="searchPost.title" />
    <div>
    <div>
        <input type="text" placeholder="Find by content..." ng-model="searchPost.content" />
    </div>

    <div>
        <input type="text" placeholder="Find by date..." ng-model="searchPost.dateOfCreation" />
    </div>

However, the date is filtered only when I type the date in format: yyyy-mm-dd in the textbox, so basically it works for only 1 date. My goal is to make possible for user to choose date range and show these values, however, I cannot make it work together with my searchPost filter... I am using angular-datepicker:

<input date-range-picker class="form-control date-picker" type="text" ng-model="someDate" options = "{locale: {format: 'YYYY-MM-DD'}}"/>

   $scope.someDate = { startDate: null, endDate: null };

Datepicker which I am using is: Angular Daterangepicker

Upvotes: 0

Views: 1688

Answers (1)

Piou
Piou

Reputation: 1066

You will need to implement a custom filter to do so.

The custom filter will take care of checking if the post creation date is between the start date and end date of the range selected.

In the end it will look like something like this:

// Setup the filter
var app = angular.module('testFilters', []);

app.controller('postsCtrl', ['$scope',function($scope){
  $scope.posts = [
    {title: 'test 2010', dateOfCreation: new Date(2010, 1, 1)},
    {title: 'test 2012', dateOfCreation: new Date(2012, 1, 1)},
    {title: 'test 2014', dateOfCreation: new Date(2014, 1, 1)},
    {title: 'test 2016', dateOfCreation: new Date(2016, 1, 1)}
  ];
  
  $scope.searchPost = {title: 'test', date: {startDate: new Date(2011, 1, 1), endDate: new Date(2015, 1, 1) } };
}]);

app.filter('postFilter', function() {

  // Create the return function and set the required parameter name to **input**
  return function(input, post) {

    var out = [];

    angular.forEach(input, function(p) {
      var filtered = true;
      
      // checking if we should check the title and cehcking
      // you may want to pass everything to lowercase for best search results
      if(post.title && p.title.indexOf(post.title) < 0){
        filtered = false;
      }
      
      // same for the content
      if(post.content && p.content.indexOf(post.content) < 0){
        filtered = false;
      }
      
      // checking the date of creation against the date range
      if(post.date && post.date.startDate && post.date.endDate){
        if(p.dateOfCreation < post.date.startDate || p.dateOfCreation > post.date.endDate){
          filtered = false
        }
      }
      
      // adding the post to the resulting array
      if(filtered){
        out.push(p);
      }
    });

    return out;
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="testFilters" ng-controller="postsCtrl">
  <h3>unfiltered posts:</h3>
  <div ng-repeat="post in posts">
    ----------------------------------------------------<br>
    Title: {{post.title}}<br>
    Content: {{post.content}}<br>
    Created: {{post.dateOfCreation | date:'MM/dd/yyyy'}}<br>
  </div>
  <hr>
  <br>
  <h3>filtering post:</h3>
  <div>
    Title: {{searchPost.title}}<br>
    Content: {{searchPost.content}}<br>
    Range: {{searchPost.date.startDate | date:'MM/dd/yyyy'}} - {{searchPost.date.endDate| date:'MM/dd/yyyy'}}<br>
  </div>
  <hr>
  <br>
  <h3>filtered posts:</h3>
  <div ng-repeat="post in posts | postFilter:searchPost">
    ----------------------------------------------------<br>
    Title: {{post.title}}<br>
    Content: {{post.content}}<br>
    Created: {{post.dateOfCreation | date:'MM/dd/yyyy'}}<br>
  </div>
</div>

Upvotes: 1

Related Questions