javascript - 根据选定的复选框和选择字段过滤数组

标签 javascript angularjs angularjs-ng-repeat angularjs-filter

如何存储复选框的选定值和选择元素并使用它们的组合来过滤结果数组?例如考虑按类别 ID 进行过滤,或显示过去 X 个月内的所有结果。

经过大量研究和反复试验,我得到了这样的结果:

查看 Plunker 或查看下面的代码:

“refine”指令中的 HTML

<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

<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);
    });
}]);

我很高兴这个问题已经被问了很多次,但是我还没有找到我的问题的答案,因为大多数示例都是 ng-repeat 中非常简单的表达式。

最佳答案

此示例适用于多个复选框。对于使用外部选择进行过滤,请使用相同的逻辑。看看

'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>

关于javascript - 根据选定的复选框和选择字段过滤数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33241437/

相关文章:

javascript - 如何使用 Angular 更新 ng-repeat 中的列表?

javascript - ngInfiniteScroll 被调用的次数超出了其需要的次数

php - 用户如何在其他人发帖后发帖?

javascript - 如何获得 360 度圆的度数,其中 12 点钟位置为 0 度或 360 度?

angularjs - 如何在 angular2 中添加过滤器?

javascript - 重复和插入指令

javascript - Angularjs禁用过滤器

javascript - For 循环生成 URL 不起作用

javascript - ng-model 无法绑定(bind)到向导应用程序中的范围

angularjs - 登录后让用户返回上一页( Node )