Angular filter and order elements on click

All we need is an easy explanation of the problem, so here it is.

I’m trying to filter a list of items (grabbed from JSON) onclick. I pull the data once from the server then would like to filter/order the elements using Angular.

Here is my plunker: http://plnkr.co/edit/glSz1qytmdZ9BQfGbmVo?p=preview

  1. Tabs — How could I filter/sort the items onclick? “Recent” would be sorted by date and “Popular” would be sorted by views.
  2. Categories — I’m using ng-click to grab the category value although not sure how to update the filter dynamically (using the value passed onclick).

Thanks

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I would wrap the entire functionality inside a parent controller with the tab change and category select functions inside that parent controller (the child scopes will inherit this) so that the scope variables can be shared down for the filters and order By:

Reading Materials on Controller Inheritance: http://docs.angularjs.org/guide/dev_guide.mvc.understanding_controller

Demo: http://plnkr.co/edit/rh3wGYhuoHSHJEa4PoQi?p=preview

HTML:

<div ng-controller="ListController">
<div class="categories" ng-controller="CategoryController">
  <ul ng-repeat="category in categories">  
    <li ng-click="sendCategory(category)">{{category.name}}</li>
  </ul>
</div>

<div class="tabs" ng-controller="tabsController">
  <ul>
      <li ng-click="tab(1)">Recent items</li>
      <li ng-click="tab(2)">Popular items</li>
  </ul>
</div>

<div class="container">
  <div class="left" ng-controller="ItemController">
    <div class="itemList">
        <div class="item" ng-repeat="item in items | filter:search | orderBy:sort"> 
            <h3 ng-click="viewDetail(item)">{{item.title}} - {{item.date}}</h3>
            <p>{{item.description}}</p>
        <a ng-click="viewDetail(item)">View full item details</a>
        </div>
    </div>
  </div>
</div>
</div>

Here is the parent controller:

myApp.controller('ListController', function($scope, $route, $location, $http, Categories){

 $scope.sort = function(item) {
   if (  $scope.orderProp == 'date') {
        return new Date(item.date);
    }
    return item[$scope.orderProp];
  }

  $scope.sendCategory = function(category) {
    // How can I pass this value to ItemController?
     $scope.search =category.name;
  };

   $scope.orderProp='date';

    $scope.tab = function (tabIndex) {
     //Sort by date
      if (tabIndex == 1){
        //alert(tabIndex);
        $scope.orderProp='date';

      }   
      //Sort by views 
      if (tabIndex == 2){
        $scope.orderProp = 'views';
      }

   };

})

** Update **

I’ve updated the controller to sort the dates correctly since they need to be parsed first.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply