2

Angular ng-repeat with filter works this way (I just discovered it by observing DOM in Chrome's developer tools):

It actually removes the nodes which don't satisfy filter condition and re-renders everything.

See this fiddle example. If you look at the DOM, and see what happens there, you can understand what I mean.

<div ng-app>
  <h2>Instant Search</h2>
  <div ng-controller="SearchCtrl">
    <input type="text" ng-model="filterText" />
    <ul>
      <li ng-repeat="state in states | filter:filterText">
        <label>
            <input type="checkbox" ng-model="state.abbreviation">
            {{state.name}}
        </label>
      </li>
    </ul>
  </div>
</div>

What I need now, is to make angular js hide nodes, not remove them. In other words, when I filter nodes, for example I want to make those nodes which don't satisfy filter condition to have a class of hidden, and I'll hide them via CSS.

0

5 Answers 5

4

ng-show placed on the repeating element will cause them to be hidden: Fiddle http://jsfiddle.net/NAumK/19/

http://docs.angularjs.org/api/ng.directive:ngShow

<div ng-app>
  <h2>Todo</h2>
  <div ng-controller="TodoCtrl">
    <input type="text" ng-model="filterText" />
    <ul>
      <li ng-repeat="state in states" ng-show="state.name.indexOf(filterText) != -1">
        <label>
            <input type="checkbox" ng-model="state.abbreviation">
            {{state.name}}
        </label>
      </li>
    </ul>
    <input type="text" ng-model="textFilter" />
  </div>
</div>

Filters remove elements as does the ng-if and ng-switch directives. You can also use css coupled with the ng-class directive to hide the elements however I recommend sticking with the ng-show for clarity. One further note of caution, hiding as opposed to removing elements makes the test cases harder to prove. You can have collisions with classes that display incorrectly but still pass (Selenium) tests.

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

1 Comment

thanks Emmentaler I just update code. I dont really know why the downvote for this good answer
1

You can use ng-show or ng-hide instead of filters.

Comments

1

You cannot use filter in ng-repeat because it filters the actual array that ng-repeat receives. You'll have to implement your own "filtering" logic.

I'd do it using a conditional ng-class, like this:

<li ng-repeat="state in states" ng-class="{'hidden': isHidden(state)}">
    <label>
        <input type="checkbox" ng-model="state.abbreviation">
        {{state.name}}
    </label>
</li>

$scope.isHidden = function(state) {
    if(state.name.toLowerCase().indexOf($scope.filterText.toLowerCase()) < 0) {
        return true;
    }

    return false;
}

Comments

1

I thinks that one answer would be like this

<div ng-app>
  <h2>Instance Search</h2>
  <div ng-controller="SearchCtrl">
    <input type="text" ng-model="filterText" />
    <ul>
      <li ng-repeat="state in states" 
          ng-show="state.name.tolowerCase().indexOf(filterText.toLowerCase()) != -1">
        <label>
            <input type="checkbox" ng-model="state.selected">
            {{state.name}}
        </label>
      </li>
    </ul>
  </div>
</div>

3 Comments

filter on ng-repeat is case insensitive, your code breaks that. Also it does not add a hidden class, it uses display: none;.
by adding a toLowerCase() first issue resolved and. do you have any soloution for second issur?
Yes, use ng-class, as I specified in my answer below.
0

Just replace filter with:

ng-show="([state] | filter:filterText).length > 0"

Comments

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.