3

I have a table tr with an ng-repeat where I colored the background of the row based on time. The colorClassFilter returns a class value based on the time passed in:

<tr ng-repeat="object in objects" class={{object.time | colorClassFilter}}>
    <td>...
    <td>...
</tr>

That worked great, but now I want to add a checkbox that allows the user to turn on/off the coloring, bound to a Boolean called useRowColors. I want to use the ng-class conditionally but not sure how to do that. This is what I tried and it doesn't work.

<tr ng-repeat="object in objects" ng-class="{ object.time | colorClassFilter : useRowColors }">

EDIT: After reading response by jitch_it (which didn't work), it led me to try this:

<tr ng-repeat="object in objects" ng-class="{'{{object.time | colorClassFilter}}' : useRowColors}">

This is what it produces in the DOM for useRowColors true:

<tr class="ng-scope ''" ng-class="{'rowColorBlue' : useRowColors}" ng-repeat="object in objects" >

Instead of this (which is what I would expect to see):

<tr class="rowColorBlue" ng-class="{'rowColorBlue' : useRowColors}" ng-repeat="object in objects" >

I'm guessing I need another level of compiling thru angular somehow?? What am I missing?

user3920421
  • 85
  • 1
  • 6

4 Answers4

1

You cannot use filter easily with ng-class attribute. However you can implement the wanted functionality like you did before, with plain class attribute:

<tr ng-repeat="object in objects" class="{{useRowColor && (object.time | colorClassFilter) || ''}}">
  <td>...</td>
  <td>...</td>
</tr>

There is related answer explaining a bit more when to use class instead ng-class How can I use AngularJS filter in ngClass?

Community
  • 1
  • 1
Mikael Lepistö
  • 18,909
  • 3
  • 68
  • 70
  • I didn't go back to try this (since this is two years old and I'm not working on that project any more) but it seems to me this answer makes sense and would work. – user3920421 May 03 '16 at 18:41
0

That seems over complicated to me... I suggest using a combination between css and a helper class in the table tag.

I've set up this plunker to demonstrate it: http://plnkr.co/edit/28gP1GcnCdPMZWXxYegZ?p=preview

<input type="checkbox" ng-model="coloured"/> Coloured?

<table ng-class="{colouredTable: coloured}">
  <tr ng-repeat="item in items" ng-class="{evenrow: $index % 2 == 0}">
    <td>{{item.someValue}}</td>
  </tr>
</table>

Hope that helps

Fedaykin
  • 4,482
  • 3
  • 22
  • 32
0

Not sure if it is a good practice to change the type of an object in the filter (date to class). However, here is a solution to your main problem.

First define a switch in your current scope.

Then in your filter function pass a 3rd parameter which is a switch for deciding whether the filter should work or not.

Then inside your filter check the switch if it is off, simply return the input. This will return the whole list you are passing to it if the switch is off.

In your html attribute just append : followed by the name of the switch at the end of the filter and it should work just fine/

I did not have your filter code so I created a sample filter myself which has an on/off switch. Here is the provided an example in plnkr:

http://plnkr.co/edit/kc2j8aquHn2cqMDlcRQm?p=preview

Here is how I use the filter in html. Notice the use of filterSwitchOn at the end of the filter.

<li ng-repeat="item in items | searchFilter:filterText:filterSwitchOn">{{item.name}}

Below segment will bind two elements in html to set the switch and the filtering text:

<p>
  <input type="checkbox" ng-model="filterSwitchOn">Switch Filter On</input>
</p>
<input type="text" ng-model="filterText" />

Finally, this is simplified angular app which provides the filter:

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

app.filter('searchFilter', function() {
  return function(input, expected, filterSwitchOn) {
    if (!filterSwitchOn)
      return input;
    else {
      var out = [];
      for (var i = 0; i < input.length; i++) {
        for (var key in input[i]) {
          if (key !== undefined) {
            var fieldValue = input[i][key];
            if (String(fieldValue).indexOf(expected) >= 0) {
              out.push(input[i]);
              break;
            }
          }
        }
      }
      return out;
    }
  };
});
app.controller('MainCtrl', function($scope, $attrs) {
  $scope.items = [{
    name: "One",
    tester: true
  }, {
    name: "Two",
    tester: false
  }, {
    name: "Three",
    tester: true
  }, {
    name: "Four",
    tester: false
  }, {
    name: "Five",
    tester: true
  }, {
    name: "Six",
    tester: false
  }, ];

  $scope.filterText = 'o';
  $scope.filterSwitchOn = true;
});

You can easy adapt this idea to your filter. Hope that helps.

Ali Motevallian
  • 1,250
  • 10
  • 15
0

You can use a ternary operator to test for the value of useRowColors.

<tr ng-repeat="object in objects" ng-class="{useRowColors ? '{{object.time | colorClassFilter}}' : ''}">
jitch_it
  • 9
  • 1
  • This is along the lines of what I'd like to do, though it didn't work. I did try something else based on this (still didn't work) but see my edited original post. Thanks! – user3920421 Aug 08 '14 at 16:37
  • Can you provide a jsfiddle or plunker of your code? – jitch_it Aug 13 '14 at 03:14