1

How can I store the selected values of checkboxes and select elements and use a combination of these to filter a results array? e.g. think filtering by category Id, or displaying all results in the last X months.

After much research and trial and error I've got as far as this:

View Plunker or see the code below:

HTML within the 'refine' directive

<div class="filters">
    <div class="filter">
        <label for="maxage">Show results from</label>
        <select name="maxage" id="maxage" 
                ng-options="option.name for option in refine.maxAge.options track by option.id" 
                ng-model="refine.maxAge.selected"
                ng-change="filterResults()">
        </select>
    </div>
    <div class="filter">
        <div class="status-filter" ng-repeat="status in refine.statuses">
            <label for="statusId{{ status.id }}">{{ status.name }}</label>
            <input type="checkbox" name="status" value="{{ status.id }}" ng-change="filterResults()">
        </div>
    </div>
</div>

HTML of main page

<body ng-app="app">
    <div ng-controller="ListCtrl" data-county-parish-id="1478">
        ...
            <main class="page-content columns medium-9 medium-push-3">
                    ...
                    <spinner name="planningSpinner" show="true">
                        <div class="loadingPanel block"></div>
                    </spinner>

                    <div class="planning">
                        <div class="no-results ng-hide" ng-show="filteredResults.length === 0">
                            <p>No results.</p>
                        </div>
                        <h4>Number of records: {{ filteredResults.length }}</h4>
                        <div ng-repeat="appl in filteredResults">
                            <hf-application info="appl"></hf-application>
                        </div>
                    </div>
                    ...
            </main>
            <aside class="sidebar columns medium-3 medium-pull-9">
                ...
                <div hf-refine-results info="refine"></div>
            </aside>
        ...
    </div>
</body>

JS

var app = angular.module('app', []);

// results filter
angular.module('app').filter('results', ['$filter', function($filter) {
    return function (input, refine) {
        var filterParams = {};
        // start off filtering with the outsideBoundary parameter
        filterParams.outsideBoundary = refine.outsideBoundary;

        // add 'show results from' filter
        //var adjustedDate = new Date();
        //adjustedDate.setMonth(adjustedDate.getMonth() - refine.maxAge.selected.id);
        //filterParams.receivedDate = $filter('date')(adjustedDate, 'yyyy/MM/dd');

        return $filter('filter')(input, filterParams);
    }
}]);

// Controller
angular.module('app').controller('ListCtrl',
        ['$scope', '$filter', '$attrs', 'appService', 'resultsFilter', function ($scope, $filter, $attrs, appService, resultsFilter) {

    $scope.applications = [];
    $scope.refine = {
        statuses: {
            options: [
                { id: 1, name: 'Unknown' },
                ...
                { id: 6, name: 'Appealed' }
            ],
            selected: [2, 3]
        },
        maxAge: {
            options: [
                { id: '1', name: 'Last month' },
                ... // 1 to 12 months
                { id: '12', name: 'Last 12 months' }
            ],
            selected: { id: '6', name: 'Last 6 months' }
        },
        ...
    };

    $scope.filterResults = function () {
        $scope.filteredResults = resultsFilter($scope.applications, $scope.refine);
    };

    /* get data from appService */
    appService.getApplications({
        status: 3,
        countyparish: parseInt($attrs.countyParishId),
        postcode: '',
        distance: 5,
        pagesize: 100
    })
    .then(function (data) {
        $scope.applications = data;
        $scope.filteredResults = resultsFilter(data, $scope.refine);
    });
}]);

I appreciate this question has been asked many times, however I haven't found an answer for my question(s) since most examples are very simple expressions within ng-repeat.

4
  • Whats is resultsFilter? Commented Oct 20, 2015 at 17:19
  • It's the 'results' filter at the top of the JS snippet. As per AngularJS docs: "You can also use filters in controllers, services, and directives. For this, inject a dependency with the name <filterName>Filter to your controller/service/directive. E.g. using the dependency numberFilter will inject the number filter" Commented Oct 20, 2015 at 17:59
  • Post code this please! Commented Oct 20, 2015 at 18:11
  • The code is there? The 'results' filter starts with this line angular.module('app').filter('results', ... which is injected as resultsFilter Commented Oct 20, 2015 at 18:15

1 Answer 1

1

This example work with multi checkbox. For filtering with outher select use same logic. Look

'use strict';
var App = angular.module('clientApp', ['ngResource', 'App.filters']);
App.controller('ClientCtrl', ['$scope', function ($scope) {
    $scope.selectedCompany = [];
    $scope.companyList = [{
        id: 1,
        name: 'Apple'
    }, {
        id: 2,
        name: 'Facebook'
    }, {
        id: 3,
        name: 'Google'
    }];

    $scope.clients = [{
        name: 'Brett',
        designation: 'Software Engineer',
        company: {
            id: 1,
            name: 'Apple'
        }
    }, {
        name: 'Steven',
        designation: 'Database Administrator',
        company: {
            id: 3,
            name: 'Google'
        }
    }, {
        name: 'Jim',
        designation: 'Designer',
        company: {
            id: 2,
            name: 'Facebook'
        }
    }, {
        name: 'Michael',
        designation: 'Front-End Developer',
        company: {
            id: 1,
            name: 'Apple'
        }
    }, {
        name: 'Josh',
        designation: 'Network Engineer',
        company: {
            id: 3,
            name: 'Google'
        }
    }, {
        name: 'Ellie',
        designation: 'Internet Marketing Engineer',
        company: {
            id: 1,
            name: 'Apple'
        }
    }];

    $scope.setSelectedClient = function () {
        var id = this.company.id;
        if (_.contains($scope.selectedCompany, id)) {
            $scope.selectedCompany = _.without($scope.selectedCompany, id);
        } else {
            $scope.selectedCompany.push(id);
        }
        return false;
    };

    $scope.isChecked = function (id) {
        if (_.contains($scope.selectedCompany, id)) {
            return 'icon-ok pull-right';
        }
        return false;
    };

    $scope.checkAll = function () {
        $scope.selectedCompany = _.pluck($scope.companyList, 'id');
    };
}]);

angular.module('App.filters', []).filter('companyFilter', [function () {
    return function (clients, selectedCompany) {
        if (!angular.isUndefined(clients) && !angular.isUndefined(selectedCompany) && selectedCompany.length > 0) {
            var tempClients = [];
            angular.forEach(selectedCompany, function (id) {
                angular.forEach(clients, function (client) {
                    if (angular.equals(client.company.id, id)) {
                        tempClients.push(client);
                    }
                });
            });
            return tempClients;
        } else {
            return clients;
        }
    };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular-resource.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css">


<div ng-app="clientApp" data-ng-controller="ClientCtrl">
    <ul class="inline">
        <li>
            <div class="alert alert-info">
                 <h4>Total Filtered Client: {{filtered.length}}</h4>

            </div>
        </li>
        <li>
            <div class="btn-group" data-ng-class="{open: open}">
                <button class="btn">Filter by Company</button>
                <button class="btn dropdown-toggle" data-ng-click="open=!open"><span class="caret"></span>

                </button>
                <ul class="dropdown-menu" aria-labelledby="dropdownMenu">
                    <li><a data-ng-click="checkAll()"><i class="icon-ok-sign"></i>  Check All</a>

                    </li>
                    <li><a data-ng-click="selectedCompany=[];"><i class="icon-remove-sign"></i>  Uncheck All</a>

                    </li>
                    <li class="divider"></li>
                    <li data-ng-repeat="company in companyList"> <a data-ng-click="setSelectedClient()">{{company.name}}<span data-ng-class="isChecked(company.id)"></span></a>

                    </li>
                </ul>
            </div>
        </li>
    </ul>
    <hr/>
     <h3>Clients Table:</h3>

    <table class="table table-hover table-striped">
        <thead>
            <tr>
                <th style="width:10%">#</th>
                <th style="width:20%">Name</th>
                <th style="width:40%">Designation</th>
                <th style="width:30%">Company</th>
            </tr>
        </thead>
        <tbody>
            <tr data-ng-repeat="client in filtered = (clients | companyFilter:selectedCompany)">
                <td>{{$index + 1}}</td>
                <td><em>{{client.name}}</em>

                </td>
                <td>{{client.designation}}</td>
                <td>{{client.company.name}}</td>
            </tr>
        </tbody>
    </table>
</div>

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

1 Comment

Although you didn't use my code in your example, there was enough in there to see where I was going wrong and I now have my code working - thanks.

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.