2

I have an array of objects with multiple properties. All of these objects have a object.comment property, but in some is filled with a string ('comment' : 'comment text'), and the others are empty ('comment' : '').

I list the results with an ng-repeat like so:

<div class="row msf-row" 
     ng-repeat="record in filteredRecords = (recordlist | filter:dateFilter | filter: search )" 
>

What I'm trying to accomplish is to add a checkbox filter to show only the results which object.comment property is filled when the checkbox is checked, and all results when is unchecked.

Here's how my filter looks so far:

<form role="form">
            <div class="form-group col-md-3">
              <input type='daterange' 
              placeholder="Date range" 
              class="form-control"
              format="DD/MM/YYYY" 
              ng-model="dates"
              ranges="ranges" />
            </div>

            <div class="form-group col-md-1">
              <input class="form-control" placeholder="Time" ng-model="search.time">
            </div>

            <div class="form-group col-md-1">
              <input class="form-control" placeholder="Car" ng-model="search.car">
            </div>

            <div class="form-group col-md-2">
              <input class="form-control" placeholder="Driver" ng-model="search.driver">
            </div>

            <div class="form-group col-md-2">
              <input class="form-control" placeholder="From" ng-model="search.from">
            </div>

            <div class="form-group col-md-2">
              <input class="form-control" placeholder="Destination" ng-model="search.destination">
            </div>

            <div class="form-group col-md-1">
              <input class="form-control" placeholder="Pax" ng-model="search.pax">
            </div>

            <div class="col-md-1">
              <div class="checkbox">
                <label>
                  <input type="checkbox" 
                         ng-model="search.cancelled" 
                         ng-change="search.cancelled = search.cancelled ? true : undefined"
                  > Cancelled 
                </label>
              </div>
            </div> 

            <div class="col-md-2">
              <div class="checkbox">
                <label>
                  <input type="checkbox" 
                         ng-model="search.comment" 
                         ng-change="search.comment = search.comment ? true : undefined"
                  > Commented records
                </label>
              </div>
            </div>

</form>

As you can see, I already have a filter that works on whether the object.cancelled is true or false, but I didn't manage to do the same for when the object.comment is empty or has a string.

Any pointers?

2 Answers 2

2

You can create custom filter please see demo below

app.filter('emptyString', [
  function() {
    return function(input, param) {
      if (!param) return input

      var ret = [];
      if (!angular.isDefined(param)) param = true;


      if (param) {
        angular.forEach(input, function(v) {
          if (angular.isDefined(v.comment) && v.comment) {
            v.comment = v.comment.replace(/^\s*/g, '');
            ret.push(v);
          }

        });
      }



      return ret;
    };
  }
])

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

app.controller('homeCtrl', function($scope) {

  $scope.recordlist = [{
      time: "10/11/2014",
      comment: "super"
    }, {
      time: "10/11/20004",
      comment: ""
    }, {
      time: "10/11/2005",
      comment: ""
    }, {
      time: "11/1/2014",
      comment: "that was ok"
    }


  ];


});

app.filter('emptyString', [
  function() {
    return function(input, param) {
      if (!param) return input

      var ret = [];
      if (!angular.isDefined(param)) param = true;


      if (param) {
        angular.forEach(input, function(v) {
          if (angular.isDefined(v.comment) && v.comment) {
            v.comment = v.comment.replace(/^\s*/g, '');
            ret.push(v);
          }

        });
      }



      return ret;
    };
  }
])
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" type="text/css" />

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>



<div ng-app="app">
  <div ng-controller="homeCtrl">
    <form role="form">
      <div class="form-group col-md-3">
        <input type='daterange' placeholder="Date range" class="form-control" format="DD/MM/YYYY" ng-model="dates" ranges="ranges" />
      </div>

      <div class="form-group col-md-1">
        <input class="form-control" placeholder="Time" ng-model="search.time">
      </div>

      <div class="form-group col-md-1">
        <input class="form-control" placeholder="Car" ng-model="search.car">
      </div>

      <div class="form-group col-md-2">
        <input class="form-control" placeholder="Driver" ng-model="search.driver">
      </div>

      <div class="form-group col-md-2">
        <input class="form-control" placeholder="From" ng-model="search.from">
      </div>

      <div class="form-group col-md-2">
        <input class="form-control" placeholder="Destination" ng-model="search.destination">
      </div>

      <div class="form-group col-md-1">
        <input class="form-control" placeholder="Pax" ng-model="search.pax">
      </div>

      <div class="col-md-1">
        <div class="checkbox">
          <label>
            <input type="checkbox" ng-model="search.cancelled" ng-change="search.cancelled = search.cancelled ? true : undefined">Cancelled
          </label>
        </div>
      </div>

      <div class="col-md-2">
        <div class="checkbox">
          <label>
            <input type="checkbox" ng-model="search.comment">Commented records
          </label>
        </div>
      </div>

    </form>
    <div class="container">
      <div class="row " ng-repeat="record in filteredRecords = (recordlist |  emptyString : search.comment   )">
        <div class="col-xs-12" <span class="label">{{record.time}} <span> <strong>{{record.comment}}</strong></p> </div>
    </div>
    </div>
  </div>

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

Comments

1

A simple solution is to use the ng-hide directive:

<div class="row"
    ng-repeat="record in filteredRecords"
    ng-hide="search.comment && (!record.comment || record.comment === '')">
</div>

What it says is: Hide this element if search.comment is checked and the record.comment is undefined or empty.

Check out this plunker: http://plnkr.co/edit/m8rA0rVxqgWS0NWukJdf?p=preview

Is this the intended behavior?

5 Comments

If I do ng-hide="record.comment === ''", it will work and show only the ones with comment, but I can't get it working with the search.comment toggle using the checkbox!
@EricMitjans Did you use the whole condition? I mean, ng-hide="search.comment && (record.comment || record.comment === '')"
Yes! It filters all results out! : /
@EricMitjans Ok, I found an error, check the updated answer and plunker.
Now it works! I realized I cannot use it, but is for another reason. If I use a filter, it takes much more resources and its slower, but I can create a new array with the filtered results (e.g: ng-repeat="record in filteredRecords = (recordlist | filter: search )". I need to do this as I am calculating the .length of the resulting array (filteredRecords) and even downloading the filtered results, so ng-hide doesn't work for me (it filters the results visually, but not in the new array), but is a very nice solution anyways! I'll use it in other ng-repeats!

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.