AngularJS使用ng-repeat筛选和显示日期范围

7

如果你是AngularJS或整个Web开发领域的新手,我不确定这是否可行或者我是否选择了最有效的路径,但目前我需要一种方法使用两个输入框来过滤日期范围。我使用jQuery日期选择器始终将日期格式化为“YYYY-MM-DD”。

所以,我有以下两个输入框:

<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" />

当然,我有一个使用 ng-repeat 指令的表格,并从本地 JSON 文件获取数据……只有 dueDate 被接收。
<tr> ng-repeat="dateItem in dateItems | filter:search:strict | filter:dateFilter" 
<td>{{dateItem.dueDate}}</td></tr>

我需要一种方法,比如说,
  • 如果用户仅在dueDate字段上选择一个日期,则ng-repeat列表将过滤并列出该日期及之后的所有日期。

  • 如果用户仅在toDate字段上选择一个日期,则ng-repeat列表将过滤并列出所有日期直到和包括该特定日期为止。

  • 如果用户在两个字段上都选择了日期,则该列表将显示这两个日期之间的所有日期。

我很困惑应该采取哪种方式,我一直在考虑是否必须编写自定义筛选函数,并使用if语句比较日期等等,但是我没有足够好的代码来说明问题...
任何帮助或指导都将不胜感激!
谢谢!
---------------------------------------------更新-------------------------------
所以最终我尝试尽我所能编写自定义筛选函数...但它不起作用.... ;( 如果我删除加粗的条件语句,它有点起作用...
$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;
  }      
};

为什么要使用jQuery而不是Angular的日期过滤器?http://docs.angularjs.org/api/ng.filter:date - m59
我原以为日期选择器界面会更友好,让用户只需点击即可自动填充日期...我还以为 Angular 的日期过滤器仅用于格式化?是否有类似的日期选择器小部件? - ZvKa
哦,我明白了。发布的答案有一个关于那个的有用链接。 - m59
你解决过这个问题吗?我正在疯狂地挣扎。 - haakym
我可以轻松地用JavaScript从头编写这个程序,但是当涉及到Angular时,我真的毫无头绪。我也在努力解决这个问题。 - Photonic
2个回答

4
您熟悉angular bootstrap UI吗? http://angular-ui.github.io/bootstrap/ 这里有一个可能符合您要求的扩展:http://eternicode.github.io/bootstrap-datepicker/。您可以使用日期选择器来显示可用日期,这样实现起来可能更容易。
另外,您可以编写一个日期范围过滤器来处理此功能。这是一个好的起点https://gist.github.com/Voles/5459410
使用方法:ng-repeat="... | daterage:start:end"
我目前正在使用手机,无法为您提供代码实现。其他用户也许能够帮到您。

嘿,马修 - 我之前也尝试过使用Bootstrap日期选择器,但我的问题不在于输入日期,而是使用Angular的ng-repeat指令来过滤和显示这些日期范围...除非我从你的建议中漏掉了什么。 - ZvKa
我的建议是在日期选择器上显示可用日期,而不是日期列表。你可以将其设置得更像日期显示。 - Matthew.Lothian
我明白了...我不能使用日期选择器来显示可用日期...我有一个表格列表,其中除了日期之外还有其他数据,我必须对其进行筛选并以列表视图向用户显示 :( - ZvKa
好的,我更新了一个在其他地方找到的示例过滤器。 - Matthew.Lothian

1

自定义过滤器用于从JSON或数组中显示在所选日期之间的日期。

 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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接