0

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>
3
  • it would be helpful if you can provide some running example on jsfiddle or plunker Commented Nov 12, 2017 at 18:05
  • @NamanKheterpal plnkr.co/edit/MT0182RTJWbqKLeqdODS?p=preview Commented Nov 12, 2017 at 18:09
  • Also you are using directive in worst way I have ever seen. You should use "ng-class" and "ng-click" inbuilt directives instead Commented Nov 12, 2017 at 18:32

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

ok so what I am seeing is that when I filter J, the {{key | uppercase}} for E still appears, this is what I am trying to also avoid?
not even sure what i just learned, will take me a bit to digest all that, but THANK YOU!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.