Search code examples
angularjscheckboxangularjs-ng-repeatangular-ngmodelangularjs-filter

ng-model into ng-repeat Angularjs


I'm asking if is possible to do something as that in angular

<div ng-app="app">
<div  ng-controller="mainController">
    <ul ng-repeat="movie in movies |searchFilter:Filter.genre  | searchFilter:Filter.name |searchFilter:Filter.pic  ">
        <li>{{movie.name}}</li>
    </ul>
    <h2>genre</h2>
    <div>
     <label>Comedy </label><input  type="checkbox" ng-model="Filter.genre.Comedy" ng-true-value="Comedy"  data-ng-false-value=''/><br/>
    </div>

    <h2>PIC</h2>
    <label>aa</label><input  type="checkbox" ng-model="Filter.pic.aa" ng-true-value="ciao"  data-ng-false-value=''/><br/>
<h2>Name</h2>
      <label>Shrek</label><input  type="checkbox" ng-model="Filter.name.Shrek" ng-true-value="The God"  data-ng-false-value=''/><br/>
</div>
</div>

i'm creating a checkbox for filter on different fields (size,name,genre) ill have a list of avaible sizes,names and genres . The issue is on ng-model and i tried to write it as "Filter.genre.genre.name" or "Filter["genre"+genre.name]" and also "Filter.genre[genre.name]" but still not work . the js.file is

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

app.controller('mainController', function($scope) {
    $scope.movies = [{name:'Shrek', genre:'Comedy',pic:"cc"},
                     {name:'Die Hard', genre:'Comedy',pic:"aa"},
                     {name:'The Godfather', genre:'Drama',pic:"ciao"},
                     {name:'The Godher', genre:'Comedy',pic:"lel"}];

    $scope.genres = [{name:"Comedy"},{name:"Action"},{name:"Drama"}];



});


app.filter('searchFilter',function($filter) {
        return function(items,searchfilter) {
             var isSearchFilterEmpty = true;
            //searchfilter darf nicht leer sein 
              angular.forEach(searchfilter, function(searchstring) {   
                  if(searchstring !=null && searchstring !=""){
                      isSearchFilterEmpty= false;
                  }
              });

        if(!isSearchFilterEmpty){
                var result = [];  

                angular.forEach(items, function(item) {  
                    var isFound = false;
                     angular.forEach(item, function(term,key) {                         
                         if(term != null &&  !isFound){
                             term = term.toLowerCase();
                                angular.forEach(searchfilter, function(searchstring) {      
                                    searchstring = searchstring.toLowerCase();
                                    if(searchstring !="" && term.indexOf(searchstring) !=-1 && !isFound){
                                       result.push(item);
                                        isFound = true;
                                        // console.log(key,term);
                                    }
                                });
                         }
                            });
                       });
            return result;
        }else{
        return items;
        }
    }
  });

if i make 3 different labels for the field Comedy, Action and Drama with ng-models called as

ng-model="Filter.genre.Comedy" ; ng-model="Filter.genre.Action" and ng-model="Filter.genre.Drama"

it work but it doesnt work if i try to write it into ng-repeat . I hope to have been clearer


Solution

  • In this sample i try to handle your question by change the Model of your page.

    we have:

    • list of movies array => $scope.movies = []
    • dynamic filters array => $scope.genres = [], $scope.years = [] or more

    our target:

    Create a dynamic filters to search in movies

    what we do

    • $scope.filterHandler = function (key, value) {}

    Run when user start searching on input or select, this function help us to create a filter as object by sending key and value which result is {key:value}

    • $scope.searchTypeHandler = function (type, dependTo) {}

    Run when our filters has some array for example genre has genres as dropdown select, this function help us to return the array which depend to the filter.

    var app = angular.module("app", []);
    
    app.controller("ctrl", [
      "$scope",
      function($scope) {
        //your options
        $scope.movies = [{
            name: 'Shrek',
            genre: 'Comedy',
            year: 2000
          },
          {
            name: 'Die Hard',
            genre: 'Action',
            year: 2000
          },
          {
            name: 'The Godfather',
            genre: 'Drama',
            year: 2015
          },
          {
            name: 'The Godher',
            genre: 'Comedy',
            year: 2017
          }
        ];
    
        $scope.genres = [{
            name: "Comedy"
          },
          {
            name: "Action"
          },
          {
            name: "Drama"
          }
        ];
    
        $scope.years = [{
            name: 2000
          },
          {
            name: 2015
          },
          {
            name: 2017
          }
        ];
        //
    
        $scope.filter = {}
    
        $scope.filterHandler = function(key, value) {
          var object = {};
          object[key] = value;
    
          $scope.filter["find"] = object;
        };
    
        $scope.searchTypeHandler = function(type, dependTo) {
          $scope.filter = {};
          $scope.filter.searchType = type;
          $scope.filter.options = undefined;
          if (dependTo != null) {
            $scope.filter.options = $scope[dependTo];
          }
        };
    
    
        //default
        $scope.searchTypeHandler("name");
    
    
      }
    ]);
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    
    
    <div class="container" ng-app="app" ng-controller="ctrl">
      <div class="page-header">
        <div class="row">
          <div class="col-lg-12">
            <div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
              <h4>Movies</h4>
            </div>
            <div class="col-lg-6 col-md-6 col-sm-6 col-xs-6 pull-right">
              <div class="input-group">
                <div class="input-group-btn">
                  <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                    By {{filter.searchType}}
                                    <span class="caret"></span>
                                </button>
                  <ul class="dropdown-menu dropdown-menu-left">
                    <li><a ng-click="searchTypeHandler('genre', 'genres')">Filter By Genre</a></li>
                    <li><a ng-click="searchTypeHandler('name', null)">Filter By Name</a></li>
                    <li><a ng-click="searchTypeHandler('year', 'years')">Filter By Year</a></li>
                  </ul>
                </div>
                <input ng-hide="filter.options" type="text" class="form-control" ng-model="filter.query" ng-change="filterHandler(filter.searchType, filter.query)">
    
                <select ng-show="filter.options" class="form-control" ng-model="filter.option" ng-change="filterHandler(filter.searchType, filter.option)" ng-options="option.name as option.name for option in filter.options"></select>
              </div>
              <!-- /input-group -->
            </div>
          </div>
        </div>
      </div>
      <ul class="list-group">
        <li class="list-group-item" ng-repeat="movie in movies | filter: filter.find">
          {{movie.name}} - <label class="label label-info">Ggenre: {{movie.genre}}</label> - <label class="label label-default">Year: {{movie.year}}</label>
        </li>
      </ul>
    
    </div>