简体   繁体   中英

Angular JS - Filter multiple values by select option

I've gone through a lot of other StackOverflow answers and I can't seem to find the answer to my problem.

I have a select box at the top of my page that allows you to filter the contents in the json array by their "start_date". I can do this for one date using the code mentioned below, but I can't seem to do this for multiple dates or to:from dates.

So in an ideal world the code would enable a user to click the select dropdown and click "next 7 days" and the json array will be filtered to show all articles that have a "start_date" within the next 7 days.

My Code

-Select box code

<select class="js-date-trigger" ng-model="query.start_time">
      <option value=""> All dates</option>
      <option value="{{ Events.date(0) }}"> Today</option>
      <option value="{{ Events.date(1) }}"> Tomorrow</option>
      <option value="This weekend"> This weekend</option>
      <option value="{{Events.date(1) || Events.date(2)}}"> Next 7 days</option>
      <option class="trigger" value=" Specific date:"> Specific date:</option>
</select>

-Ng-repeat code

<div class="event block block--fullwidth" ng-repeat="event in filtered = (Events.events | filter:query:strict | orderBy:Events.orderEvent)">
...content repeated...
</div>

-Function in my controller

var vm = this;

        vm.date = function(daysFromNow){
            days=daysFromNow;
            myDate = new Date();
            myDate.setTime(myDate.getTime()+(days*24*60*60*1000));
            var dd = myDate.getDate();
            var mm = myDate.getMonth()+1; //January is 0!
            var yyyy = myDate.getFullYear();

            if(dd<10){
                dd='0'+dd
            }
            if(mm<10){
                mm='0'+mm
            }
            return yyyy+'-'+mm+'-'+dd;
        }

Thanks for any help, and let me know if you need more info as this is my first StackOverflow post.

For anyone else looking for the solution to this answer, below is the code I used.

I basically created a custom filter called myDateRange which contained all the logic to filter my results by date range.

.filter('myDateRange',['$filter',dateRange])
// depend on $filter to set the date
    function dateRange($filter){
        // Pass in the array, and custom from/to fields to my filter
        return function(events, from, to){
            var result = [];
            // if the events are loaded, iterate through each event in the JSON
            if (events && events.length > 0){
                $.each(events, function (index, event){
                    //Format event date to my format
                    var eventDate = new Date(event.start_time.replace(/-/g,"/"));
                    eventDate = $filter('date')(eventDate, "yyyy-MM-dd");

                    // Get tomorrows date and set to my format
                    var tomorrow = new Date();
                    tomorrow.setDate(tomorrow.getDate() + 1);
                    tomorrow = $filter('date')(tomorrow, "yyyy-MM-dd");

                    // If the to date is the same as tomorrows date then set from to the same date(this ensures from:tomorrow-to:tomorrow is set so only tomorrow events show)
                    if(to == tomorrow){
                        from = tomorrow;
                    }
                    // If events are within the date range set then push it to the array
                    if (eventDate >= from && eventDate <= to){
                        result.push(event);
                    }
                });
                // return the array back to the scope
                return result;
            }
        };
    }

I then set my ng-repeat to filter by my custom filter, also mapping the to and from to my models as below:

 <div class="event block block--fullwidth" ng-repeat="event in filtered = (Events.events | myDateRange:Events.dateFrom:Events.dateTo | orderBy:Events.orderEvent)">

In my controller, I set the default models/scope as below:

vm.dateFrom = vm.date(0);
vm.dateTo = vm.date(9999);

The vm.date is a custom function which returns the date of x many days from now so vm.date(1) will return tomorrow and vm.date(365) will return the date a year from now. If you are interested in the this function here is how it works.

vm.date = function(daysFromNow){
            days=daysFromNow;
            myDate = new Date();
            myDate.setTime(myDate.getTime()+(days*24*60*60*1000));
            var dd = myDate.getDate();
            var mm = myDate.getMonth()+1; //January is 0!
            var yyyy = myDate.getFullYear();

            if(dd<10){
                dd='0'+dd
            }
            if(mm<10){
                mm='0'+mm
            }
            return yyyy+'-'+mm+'-'+dd;
        }

Finally, I then map my dateTo to my select box, below:

<select class="js-date-trigger" ng-model="Events.dateTo">
      <option value="{{ Events.date(9999) }}"> All dates</option>
      <option value="{{ Events.date(0) }}"> Today</option>
      <option value="{{ Events.date(1) }}"> Tomorrow</option>              
      <option value="{{Events.date(7)}}"> Next 7 days</option>
</select>

And that pretty much gets date ranges working to how i'd like with my select box. If anyone is trying to do something similar, feel free to use my code. If you get stuck then feel free to post a response and i'll do my best to advise.

Thanks all.

您可以编写带有其他参数的自定义dateRange过滤器,然后像ng-repeat="event in filtered = (Events.events | dateRange:startDate:endDate)"一样调用它

use a filter

<div class="event block block--fullwidth" ng-repeat="event in Events.events | filter: myFilter ">

in your controller

vm.myFilter = function(event) {
   return Math.round((event.start_date-Date.now())/(1000*60*60*24)) <  DAYS_OPTION;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM