0

I have a list of items which I want to filter with radio buttons, here's an example of my array:

$scope.items = [
  {
    "name":"person 1",
    "section":"one",
    "job":false
  },
  {
    "name":"person 2",
    "section":"two",
    "job":true
  },
  {
    "name":"person 3",
    "section":"one",
    "job":false
  },
  {
    "name":"person 4",
    "section":"one",
    "job":true
  }
];

In my HTML, I have an ng-repeat list which I want to filter with radio buttons:

<div class="menu">
   <label>
      <input type="radio" ng-model="filteradio.section" value="">
      <p>All</p>
   </label>

   <label>
      <input type="radio" ng-model="filteradio.section" value="one">
      <p>Section 1</p>
   </label>

   <label>
      <input type="radio" ng-model="filteradio.section" value="two">
      <p>Section 2</p>
   </label>

   <label>
      <input type="radio" ng-model="filteradio.job" value="true">
      <p>People with job</p>
   </label>
</div>

<table>
   <tr>
      <td>Name</td>
      <td>Section</td>
      <td>Job</td>
   </tr>
   <tr ng-repeat="item in items | filter:filteradio:strict">
      <td>{{item.name}}</td>
      <td>{{item.section}}</td>
      <td ng-if="item.job">yes</td>
   </tr>
</table>

The problem is that the last radio button won't work, because when I select the buttons with "filteradio.section" they work fine, but once I click in the "filteradio.job" the other radio buttons stay checked!
I tried adding the same "name atribute" to all radio buttons but this way once I click "filteradio.job" all items dissapear.
How can I filter them all by "section" and also by "if they have a job or not"? Is there an easier way to approach this?

1 Answer 1

1

I've included a working example below, but I'll go through some noteworthy points:

  • All your radio inputs should bind to the same ng-model if the options aren't mutually exclusive, otherwise you can end up in states where multiple radio inputs are selected
  • To implement the filtering you need on the table:
    • Keep track of a filter structure that stores the item property and value to filter by
    • Use ng-change to update this filter structure as necessary
    • Use a custom filter comparator that draws upon the filter structure
  • Take note some radio inputs use ng-value instead of value, the latter values will always be interpreted as string literals

angular
  .module('app', [])
  .controller('ctrl', function ($scope) {
    var radioFilter = {
      prop: 'section',
      value: null,
    };
    $scope.items = [
      {
        name: 'person 1',
        section: 'one',
        job: false,
      },
      {
        name: 'person 2',
        section: 'two',
        job: true,
      },
      {
        name: 'person 3',
        section: 'one',
        job: false,
      },
      {
        name: 'person 4',
        section: 'one',
        job: true,
      }
    ];
    $scope.radio = null;
    $scope.radioChanged = function (prop) {
      radioFilter = {
        prop: prop,
        value: $scope.radio,
      };
    };
    $scope.filterByRadio = function (item) {
      return $scope.radio === null || item[radioFilter.prop] === $scope.radio;
    };
  });
<div ng-app="app" ng-controller="ctrl">
  <div>
     <label>
        <input type="radio" ng-model="radio" ng-change="radioChanged('section')" ng-value="null"> All
     </label>
     <label>
        <input type="radio" ng-model="radio" ng-change="radioChanged('section')" value="one"> Section 1
     </label>
     <label>
        <input type="radio" ng-model="radio" ng-change="radioChanged('section')" value="two"> Section 2
     </label>
     <label>
        <input type="radio" ng-model="radio" ng-change="radioChanged('job')" ng-value="true"> People with job
     </label>
  </div>
  <table>
    <tr>
      <td>Name</td>
      <td>Section</td>
      <td>Job</td>
    </tr>
    <tr ng-repeat="item in items | filter:filterByRadio">
      <td>{{ item.name }}</td>
      <td>{{ item.section }}</td>
      <td>{{ item.job ? "yes" : "" }}</td>
    </tr>
  </table>
</div>
<script src="https://unpkg.com/[email protected]/angular.min.js"></script>

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

1 Comment

Amazing dude, just amazing! Thank you a lot, I'm still kinda new with Angular and you just saved me, this works pretty well!

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.