Search code examples
javascriptangularjsbindingcomponentsangularjs-filter

Filter between two components AngularJS


I know I can filter like this:

<input type="search" ng-model="searchTable">
<table>
  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="row in $ctrl.rows | filter: searchTable">
      <td>{{ row.firstName }}</td>
      <td>{{ row.lastName }}</td>
    </tr>
  </tbody>
</table>

How do I filter if the <input type="search" ng-model="searchTable"> and <tr ng-repeat="row in $ctrl.rows | filter: searchTable"> are in separate components?

Here's a simple fiddle.

From what I understand I'll need to add an $onChanges() and expression binding bindings: { onChange: '&' } to the searchComponent, but don't fully understand how to implement it.

Thanks


Solution

  • Here is the working fiddle. You store the search term in parent component and pass it to both child components.

    var app = angular.module('app', []);
    
    app.controller('appController', function() {
    	this.search = "";
    });
    
    app.component('searchComponent', {
    	template: `
      	<h4>{{ $ctrl.title }}</h4>
        <label>Search table</label>
        <input type="search" ng-model="$ctrl.search">
      `,
      controller: function() {
      	this.title = 'Search Component';
      },
      bindings: {
      	search: "="
      }
    });
    
    app.component('tableComponent', {
    	template: `
      	<h4>{{ $ctrl.title }}</h4>
        <!-- <p>This works</p> 
        <label>Search table</label>
        <input type="search" ng-model="searchTable"> -->
        <table>
        	<thead>
          	<tr>
            	<th>First Name</th>
              <th>Last Name</th>
            </tr>
          </thead>
        	<tbody>
          	<tr ng-repeat="row in $ctrl.rows | filter: $ctrl.search">
            	<td>{{ row.firstName }}</td>
              <td>{{ row.lastName }}</td>
            </tr>
          </tbody>
        </table>
      `,
      controller: function() {
     		this.title = 'Table Component';
        
        this.rows = [
        	{firstName: 'Zulu', lastName: 'Apple'},
          {firstName: 'Alice', lastName: 'xRay'},
          {firstName: 'Fred', lastName: 'Rogers'}
        ];
      },
      bindings: {
      	search: "<"
      }
    });
    body {
      font-family: 'Arial', sans-serif;
    }
    table {
      border-collapse: collapse;
    }
    td, th {
      border: 1px solid grey;
      padding: 5px;
    }
    label {
      display: block;
    }
    input {
      margin-bottom: 10px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.0/angular.min.js"></script>
    <div ng-app="app">
      <div ng-controller="appController">
        <h3>Filter Between Components</h3>
        <search-component search="search"></search-component>
        <table-component search="search"></table-component>
      </div>
    </div>