Angular Show All When No Filter Is Supplied

245 Views Asked by At

I have been working on trying to get my Angular application to show all results if no filter is selected. I have looked at similar questions on here, but their answers did not work for my application for some strange reason.

I have it working initially, but after a filter is applied, and removed, no data is displayed.

My working demo is at the following JS Fiddle

My HTML

<div ng-controller="MyCtrl">
<h4>Industries</h4>
<div ng-init="group = (industries | groupBy:'industry_id')" style="width:100%">
    <div ng-repeat="ind in industries"   style="width:100px; float:left;">
        <b><input type="checkbox" ng-model="useIndustries[$index]"/>{{ind.industry_name}}</b>
    </div>
</div>
<br>
<h4>Types</h4>
<div ng-init="group2 = (types | groupBy:'industry_type_id')" style="width:100%">
    <div ng-repeat="type in types" style="width:100px;float:left;">
        <b><input type="checkbox" ng-model="useTypes[$index]"/>{{type.type_name}}</b>
    </div>
</div>
<div style="clear:both;"></div>
<div>
    <ul>
        <li  ng-repeat="est in establishments | filter:(!!filterIndustries() || undefined) && filterIndustries()"><p><b>{{est.est_name}} - {{est.industry_id}} - {{est.industry_type_id}}</b></p></li>
    </ul>    
</div>

My JS

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

function MyCtrl($scope, filterFilter) {
    $scope.useIndustries = [];
    $scope.useTypes = [];

    $scope.filterIndustries = function () {

        return function (p) {

            if ($scope.useIndustries.length > 0) {

                for (var i in $scope.useIndustries) {
                    if ((p.industry_id == $scope.group[i] && $scope.useIndustries[i])) {
                        return true;
                    }
                }
            }
            if ($scope.useTypes.length > 0) {

                for (var i in $scope.useTypes) {
                    if (p.industry_type_id == $scope.group2[i] && $scope.useTypes[i]) {
                        return true;
                    }
                }
            }

        };

    };

    $scope.industries = [
        { industry_name: "Italian", industry_id: 1}, 
        { industry_name: "Indian", industry_id: 2}, 
        { industry_name: "Spanish", industry_id: 3} 

    ];



    $scope.types = [
        { type_name: "Eat-In", industry_type_id: 1}, 
        { type_name: "Fast Food", industry_type_id: 2}, 
        { type_name: "Takeout", industry_type_id: 3}
    ];

    $scope.establishments = [
        {est_name: 'Luigis Pizza Kitchen', industry_id: 1, industry_type_id:2},
        {est_name: 'Pizza Plus', industry_id: 1, industry_type_id:1},
        {est_name: 'Authentic Mexican Grill', industry_id: 3, industry_type_id:1},
        {est_name: 'Tacos R Us', industry_id: 3, industry_type_id:3},
        {est_name: 'Taste Of India', industry_id: 2, industry_type_id:1},
        {est_name: 'Indian Food Emporium', industry_id: 2, industry_type_id:3}
    ];    
}


var uniqueItems = function (data, key) {
    var result = new Array();
    for (var i = 0; i < data.length; i++) {
        var value = data[i][key];

        if (result.indexOf(value) == -1) {
            result.push(value);
        }

    }
    return result;
};

myApp.filter('groupBy',
            function () {
                return function (collection, key) {
                    if (collection === null) return;
                    return uniqueItems(collection, key);
        };
    });

I have been working on this for a while, and am curious if anyone can see any glaring issues that are causing this not to function quite "right". I realize that it has to be an error on my part. My knowledge of Angular is minimal at best.

I would genuinely appreciate any help on this subject.

2

There are 2 best solutions below

1
On BEST ANSWER

You must return collection first and after you have to check whether is all items removed or not.

Filter

$scope.filterIndustries = function () {

    return function (p) {
        if ($scope.useIndustries.length == 0 && $scope.useTypes.length == 0) {
            return p;
        }
        var isShowAll = true;
        if ($scope.useIndustries.length > 0) {
            for (var i in $scope.useIndustries) {
                if ((p.industry_id == $scope.group[i] && $scope.useIndustries[i])) {
                    return true;
                }
                if($scope.useIndustries[i]){
                    isShowAll = false;
                }

            }
        }
        if ($scope.useTypes.length > 0) {

            for (var i in $scope.useTypes) {
                if (p.industry_type_id == $scope.group2[i] && $scope.useTypes[i]) {
                    return true;
                }
                if($scope.useTypes[i]){
                    isShowAll = false;
                }
            }

        }
        if(isShowAll)
         return p;

    };

};

JSFiddle

4
On

As you are returning array while they got match criteria by using return true, But if there is no any filter selected then you have to return whole array by adding the condition on top before applying crieteria.

Filter

$scope.filterIndustries = function () {
    return function (p) {
        if ($scope.useIndustries.length == 0 && $scope.useTypes.length == 0) return p;
        if ($scope.useIndustries.length > 0) {
            for (var i in $scope.useIndustries) {
                if ((p.industry_id == $scope.group[i] && $scope.useIndustries[i])) {
                    return true;
                }
            }
        }
        if ($scope.useTypes.length > 0) {

            for (var i in $scope.useTypes) {
                if (p.industry_type_id == $scope.group2[i] && $scope.useTypes[i]) {
                    return true;
                }
            }
        }
    };
};

JSFiddle