oded
oded

Reputation: 179

How to create filter by ng-model in ng-repeat

I have this code

    <div class="form-group">
      <label for="inputFood" class="col-sm-2 col-form-label">Component</label>
      <br>
      <div class="col-sm-9 col-xs-9">
        <input type="text" class="form-control" name="inputFood{{ $index + 1}}" id="inputFood{{$index+1}}" required ng-model="foodForm.inputFood[$index+1]" placeholder="Type a component" autocomplete="off" ng-keyup="doCheck($index+1)">
      </div>

    </div>
    <br>
    <div class="form-group col-xs-12">
      <ul ng-show="showListFood" class="foodList{{$index+1}}">
        <li ng-click="showFood(foodN.food_name, foodN.food_id)" ng-repeat="foodN in foodName| filter : foodForm.inputFood.$index+1">
          <span>{{ foodN.food_name}}</span>
        </li>
      </ul>
    </div>
  </fieldset>

And i'm trying to filter list by ng-model in ng-repeat, but sadly i don't succeed. I would be very thankful for some help.

This is the example jsFiddle

Upvotes: 1

Views: 1277

Answers (5)

Roh&#236;t J&#237;ndal
Roh&#236;t J&#237;ndal

Reputation: 27192

Working Demo :

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

myApp.controller('MyCtrl',function($scope) {
    $scope.showListFood = true;
    $scope.foodName = [
    {
      "food_name": "alpha"
    },
    {
      "food_name": "beta"
    }
    ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
      <div class="form-group">
      <label for="inputFood" class="col-sm-2 col-form-label">Component</label>
      <br>
      <div class="col-sm-9 col-xs-9">
        <input type="text" class="form-control" name="inputFood{{ $index + 1}}" id="inputFood{{$index+1}}" required ng-model="foodForm.inputFood" placeholder="Type a component" autocomplete="off" ng-keyup="doCheck($index+1)">
      </div>

    </div>
    <br>
    <div class="form-group col-xs-12">
      <ul ng-show="showListFood" class="foodList{{$index+1}}">
        <li ng-repeat="foodN in foodName | filter : foodForm.inputFood">
          <span>{{ foodN.food_name}}</span>
        </li>
      </ul>
    </div>
</div>

Upvotes: 0

Jenny
Jenny

Reputation: 663

You need to set showListFood to true initially and chnage filter syntax See this : fiddle

(1)  $scope.showListFood =true
(2)ng-repeat="foodN in foodName| filter : foodForm.inputFood[$index+1]"

Upvotes: 0

dowgwi
dowgwi

Reputation: 45

Filter does not work with ng-repeat in Angular 1.x based on this Angularjs doc https://docs.angularjs.org/api/ng/directive/ngRepeat

Please read the link above. I copy a couple of paragraphs from ngRepeat link:

*The built-in filters orderBy and filter do not work with objects, and will throw an error if used with one.

If you are hitting any of these limitations, the recommended workaround is to convert your object into an array that is sorted into the order that you prefer before providing it to ngRepeat. You could do this with a filter such as toArrayFilter or implement a $watch on the object yourself.*

So, one solution could be create a new sorted array of Foods before you use with ng-repeat. The other solution could be use toArrayFilter solution.

Upvotes: 0

Saurabh Agrawal
Saurabh Agrawal

Reputation: 7739

Try this

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

    app.controller('foodCtrl', function($scope, $http) {

        $scope.foodName = [];
        $scope.foodForm = [];
        $scope.foodsComponent = [{
            id: 'comp1',
            inputFood: ''
        }];


        $scope.foodName = [{
            "food_name": "egg"
        }, {
            "food_name": "bread"
        }, {
            "food_name": "apple"
        }];


        $scope.showListFood = true;
        $scope.isFood = false;

        $scope.doCheck = function(index) {

            $(function() {

                if ($scope.foodForm.inputFood.index != "" &&        $scope.foodForm.inputFood.index != undefined) {

                    $scope.showListFood = true;

                } else {

                    $scope.showListFood = false;
                    $scope.isFood = false;
                }

            });
        };


        $scope.addComponent = function() {

            var newItemNo1 = $scope.foodsComponent.length + 1;
            $scope.foodsComponent.push({
                id: 'comp' + newItemNo1,
                inputFood: ''
            });

        };
    });

</script>

        <button class="btn btn-primary" ng-click="addComponent()">ADD</button>
        <div class="spacer"></div>


        <div ng-repeat="comp in foodsComponent">
            <fieldset>

                <div class="form-group">
                    <label for="inputFood" class="col-sm-2 col-form-label">Component</label>
                    <br>
                    <div class="col-sm-9 col-xs-9">
                        <input type="text" class="form-control" name="inputFood{{ $index + 1}}" id="inputFood{{$index+1}}" required ng-model="foodForm.inputFood[$index+1]" placeholder="Type a component" autocomplete="off" ng-keyup="doCheck($index+1)">
                    </div> 
                </div>
                <br>
                <div class="form-group col-xs-12">
                    <ul ng-show="showListFood" class="foodList{{$index+1}}">
                        <li ng-click="showFood(foodN.food_name, foodN.food_id)" ng-repeat="foodN in foodName| filter : foodForm.inputFood[$index+1]">
                            <span>{{ foodN.food_name}}</span>
                        </li>
                    </ul>
                </div>
            </fieldset>
        </div>
    </div>

</div>

Upvotes: 1

Sachila Ranawaka
Sachila Ranawaka

Reputation: 41377

change the filter like this filter : foodForm.inputFood[$index+1]"

<li ng-click="showFood(foodN.food_name, foodN.food_id)" ng-repeat="foodN in foodName| filter : foodForm.inputFood[$index+1]">

Demo

Upvotes: 0

Related Questions