AngularJS filter and display range of dates using ng-repeat

12,869

Solution 1

Are you familiar with angular bootstrap UI? http://angular-ui.github.io/bootstrap/

There is an extension that might be what you are looking for here: http://eternicode.github.io/bootstrap-datepicker/

Instead of using a repeated list of dates you could use a date picker to display the available dates. As I think it might be easier to implament.

Edit:

Otherwise you could write a date range filter to handle this functionality. This might be a good place to start https://gist.github.com/Voles/5459410

useage: ng-repeat="... | daterage:start:end"

I am on my phone so am unable to give you an implementation at this time. Another user may be able to oblige.

Solution 2


Custom filter used to display dates between the selected dates from json or array


	var app = angular.module("myApp",[])
	.directive("datepicker1",function(){
		return{
			restrict:"A",
			link:function(scope,el,attr){
				el.datepicker({
					dateFormat:'yy-mm-dd'
				});
			}
		};
	})
	.directive("datepicker2",function(){
		return{
			restrict:"A",
			link:function(scope,el,attr){
				el.datepicker({
					dateFormat:'yy-mm-dd'
				});
			}
		};
	})
	.filter('myFilter',function(){
		return function(items, fromdate,todate){
			var arrayReturn = [];
			items.forEach(function(val,i){
				var a = new Date(items[i].cdet.cdate.date);
				console.log(a)
				console.log(fromdate)
				//var yy = a.getFullYear();
				//var mm = a.getMonth()+1;
				//var dd = a.getDate();
				var myDate = a;
				var fr = new Date(fromdate);
				var to = new Date(todate);
				if(myDate >= fr && myDate <= to){
					arrayReturn.push(items[i]);
				}
			});
			return arrayReturn;
		}
	})
	.controller('myCtrl',function($scope){
		$scope.startdate = "2017-10-18";
		$scope.enddate = "2019-1-28"
		$scope.names = [
			{
				"cname" : "A",
				"cdet":{
					cdate:{
						date:"2018-5-15"
					}
				}
			},
			{
				"cname" : "B",
				"cdet":{
					cdate:{
						date:"2017-5-20"
					}
				}
			},
			{
				"cname" : "C",
				"cdet":{
					cdate:{
						date:"2019-5-13"
					}
				}
			},
			{
				"cname" : "D",
				"cdet":{
					cdate:{
						date:"2018-10-2"
					}
				}
			},
			{
				"cname" : "E",
				"cdet":{
					cdate:{
						date:"2018-12-8"
					}
				}
			}			
		];
	});
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.min.css" rel="stylesheet"/>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.9/angular.min.js"></script>


<div ng-app="myApp" ng-controller="myCtrl">	
	From Date:<input type="text" datepicker1 ng-model="startdate"/>
	To Date:<input type="text" datepicker2 ng-model="enddate"/>
	<ul ng-repeat="name in names | myFilter:startdate:enddate">
		<li><span>{{ name.cname }}</span> | <span>{{ name.cdet.cdate.date }}</span></li>
	</ul>
</div>
Share:
12,869
ZvKa
Author by

ZvKa

BY DAY: Web Developer

Updated on June 15, 2022

Comments

  • ZvKa
    ZvKa almost 2 years

    new to AngularJS- or the whole web development scene,

    I am not even sure if this is possible or I am taking the most efficient path but I'm currently in need of a way to filter the range of dates using two input boxes, I'm using a jquery datepicker to always format the date to be "YYYY-MM-DD".

    So, I have the following two input boxes,

    <label class="" for="DateFromFilter">
              Date From:
    </label>
     <input date-picker type="text" id="DateFromFilter" 
        class="form-control" 
        title="Please enter in YYYY-MM-DD format."
        ng-model="search.dueDate" />
    
     <label class="" for="DateToFilter">
               Date To:
     </label>
      <input date-picker type="text" id="DateToFilter" 
         class="form-control"
         title="Please enter in YYYY-MM-DD format."
         ng-model="search.toDate" />
    

    And of course I have a table with a ng-repeat directive, getting its data from a local JSON file...only the dueDate is received.

    <tr> ng-repeat="dateItem in dateItems | filter:search:strict | filter:dateFilter" 
    <td>{{dateItem.dueDate}}</td></tr>
    

    I need a way to let's say,

    • if the user selects a date on the dueDate field ONLY, the ng-repeat list will filter and list all the dates FROM that date and onwards.

    • if the user selects a date on the toDate field ONLY, the ng-repeat
      list will filter and list all the dates UP TO and including that
      certain date.

    • if the user selects dates on both fields, the list will display all
      the dates between those two dates.

    I'm so lost on which route to take, I've been thinking I have to write a custom filter function and compare the dates with if statements and so on but I don't have a decent enough of a code to illustrate here...

    any help or guidance will be greatly appreciated!

    Thank you!

    ---------------------------------------------UPDATE-------------------------------

    So I ended up trying to write a custom filter function to the best of my abilities..it does not work though....;( It kinda works if I take out the bolded conditional statements...

    $scope.dateFilter = function (item) {
    
      /*
       * When the display starts, the inputs are undefined. also need to
       * account for when the inputs are empty to return everything.
       */
    if ((!angular.isUndefined($scope.dueDate) && $scope.dueDate != "" ) **&&
          (angular.isUndefined($scope.toDate) || $scope.toDate == "" )**)
      {          
        var inputDate = new Date($scope.dueDate);
        var incomingDate = new Date(item.dueDate);
        if (inputDate <= incomingDate) 
        {
         return true;
        }
        else
        {
         return false;
        }
      }
    else if ((!angular.isUndefined($scope.toDate) && $scope.toDate != "")**&&
              (angular.isUndefined($scope.dueDate) || $scope.dueDate == "" )**)
      {
        var inputDate = new Date($scope.toDate);
        var incomingDate = new Date(item.dueDate);
        if (inputDate >= incomingDate)
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    else if ((!angular.isUndefined($scope.dueDate) && $scope.dueDate != "" )&&
              (!angular.isUndefined($scope.toDate) && $scope.toDate != ""))
      {
        var inputDueDate = new Date($scope.dueDate);
        var inputToDate = new Date($scope.toDate);
        if (inputDueDate < item.dueDate && inputToDate > item.dueDate )
        {
          return true;
        }
        else
        {
         return false;
        }
      }
    else
      {
       return true;
      }      
    };