Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS filter and display range of dates using ng-repeat

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;
  }      
};
like image 432
ZvKa Avatar asked Jan 17 '14 01:01

ZvKa


People also ask

How do you put filters on NG-repeat?

The ng-repeat values can be filtered according to the ng-model in AngularJS by using the value of the input field as an expression in a filter. We can set the ng-model directive on an input field to filter ng-repeat values.

How do you condition in NG-repeat?

You can add condition using ng-if also and this is effective too. You can apply any condition to your list using ng-if attribute. In below example, I have put condition where Age > 20 and IsActive is true. ng-repeat will fetch all records which full fill this scenario.

How do I get the index of an element in NG-repeat?

Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.

How do you use NG-repeat in a table?

Definition and UsageThe ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item.


2 Answers

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.

like image 78
Matthew.Lothian Avatar answered Sep 29 '22 12:09

Matthew.Lothian



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>
like image 44
Srinivasan N Avatar answered Sep 29 '22 12:09

Srinivasan N