简体   繁体   中英

angularjs filter ng-model key value

Pretty new to angularjs and fairly impressed I have made it this far with this app, thanks to the Stack community. So I have this issue. I am trying to create the correct filter.

I have my controller which does three things,

  1. It splits the array into groups alphabetically, and the displays the objects withing each group.
  2. I've also set it to filter the groups by new, all, etc... using a directive on my buttons in the view.
  3. Now I am trying to create a filter using ng-model, where i am stuck is this...

My current version filters the emails in the current view ie(new, all, etc) this was pretty straight forward.

  1. However it does not filter the object keys, meaning its not filtering the alphabetical index key I have created.

  2. I would rather have it search the whole object rather then just the pre-filtered view that they are in. So basically if the are searching we want it to search everything.

I hope I explained this well enough.

Here is the relevant code...

Controller:

app.controller('emailController', function($scope, Emails) {
    Emails.getItems().then(function(response) {
        $scope.emails = response.data;
        $scope.grouped = group($scope.emails);

        function group(arr) {
          var grouped = {};
          arr.forEach(item => {
            var grp = item.sender_email[0]
            grouped[grp] = grouped[grp] || [];
            grouped[grp].push(item);
          })
          return grouped;
        }

        function is_new(arr) {
          return arr.filter(function(evl) {
            return evl.is_new;
          });
        }

        function inbox(arr) {
          return arr.filter(function(evl) {
            return !evl.shielded;
          });
        }

        function shield(arr) {
          return arr.filter(function(evl) {
            return evl.shielded;
          });
        }

        $scope.filter_emails = function(category, element) {
            if (category === "inbox") {
                $scope.grouped = group(inbox($scope.emails));
            } else if (category === "shielded") {
                $scope.grouped = group(shield($scope.emails));
            } else if (category === "new") {
                $scope.grouped = group(is_new($scope.emails));
            } else {
                $scope.grouped = group($scope.emails);
            }
        }
    })
});

directive:

app.directive('filterGroup', function() {
   return {
      scope: true,
      link: function(scope, element, attrs) {
         element.bind('click', function() {
            element.parent().children().addClass('btn-outline-primary');               
            element.parent().children().removeClass('btn-primary'); 
            element.addClass('btn-primary');
            element.removeClass('btn-outline-primary');              
         })
      }
   }
});

view:

<div class="row">
    <div class="col-md-12 text-center mb-5">
        <div class="btn-group">
            <button class="btn btn-primary" ng-click="filter_emails()" filter-group><span class="ion-home mr-2"></span>All</button>
            <button class="btn btn-outline-primary" ng-click="filter_emails('new')" filter-group><span class="ion-plus-circled mr-2"></span>New</button>
            <button class="btn btn-outline-primary" ng-click="filter_emails('inbox')" filter-group><span class="ion-archive mr-2"></span>Inbox</button>
            <button class="btn btn-outline-primary" ng-click="filter_emails('shielded')" filter-group><span class="ion-paper-airplane align-middle mr-2"></span>Shielded</button>
        </div>
    </div>
</div>
<div class="row justify-content-center">
    <div class="col-sm-6 mb-5">
        <input type="text" ng-model="search" class="form-control form-control-lg" placeholder="Type to search all emails">
    </div>
</div>
<div class="row" ng-repeat="(key, value) in grouped">
    <div class="col-sm-1">
        <h1 class="rolodex">{{key | uppercase}}</h1>
    </div>
    <div class="col-sm-11">
        <div class="row">
            <div class="col-sm-6 mb-3" ng-repeat="item in value | filter : search | orderBy : 'sender_email'">
                <div class="card">
                    <div class="card-body row">
                        <div class="col-sm-2" ng-switch on="item.favicon">
                            <img class="list-favicon" ng-switch-when="null" ng-src="images/airplane.svg" title="Site Favicon" />
                            <img class="list-favicon" ng-switch-default ng-src="{{item.favicon}}" title="Site Favicon" />
                        </div>
                        <div class="col-sm-10">
                            <span><strong>{{item.sender_email}}</strong></span>
                            <span class="float-right"><small><em>{{item.created | date:'medium'}}</em></small></span>
                            <br>
                            <span><a href="//{{item.email_domain}}" target="_blank">{{item.email_domain}}</a>
                            <br>
                            <span ng-switch on="item.sender_name">
                                <span ng-switch-when="null"><small><em>Sender Name Unknown</em></small></span>
                                <span ng-switch-default><small><em>{{item.sender_name}}</em></small></span>     
                            </span>
                        </div>
                    </div>
                    <div class="card-footer text-center">
                        <div class="btn-group">
                            <button class="btn btn-outline-secondary"><span class="ion-archive mr-2"></span>Move To Inbox</button>
                            <button class="btn btn-success"><span class="ion-paper-airplane align-middle mr-2"></span>Shielded</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

For point 1 you can add

ng-focus="filter_emails()"

on you search input box so that each time user try to search it is taken to "All" tab and then search will be working on all tabs.

For point 2 you need to add your filterKey on each item because angular "filter" only works on Array not object. For each item you can do following and filtering will work on filterKey also. (Try filtering "J" in working plunker)

item.filterKey = grp;

To remove the Key you need to add

ng-repeat="item in filtered = (value | filter : search | orderBy : 'sender_email')"

and ng-if="filtered.length>0" on the Key

Updated Plunker: https://plnkr.co/edit/kl7gYZkA6aCx0L2anO7q?p=preview

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