title: Angular: Filtering content of a table with a search input and specific filter options
body: <p>This is what I'm working on right now. I have a datatable with some options to filter his content:</p>
  
  <p><a href="https://i.stack.imgur.com/uFFWP.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/uFFWP.gif" alt="Animated GIF"></a></p>
  
  <p>The HTML component:</p>
  
  <pre><code>&lt;div class="row topbuffer-20"&gt;
    &lt;div class="col"&gt;
      &lt;h3&gt;Thief: The Dark Project&lt;/h3&gt;
      &lt;p&gt;There are &lt;span *ngIf="fanmissions"&gt;&lt;strong&gt;{{fanmissions.length}}&lt;/strong&gt;&lt;/span&gt; available Fan Missions. The last released is &lt;strong&gt;Veniam in Sunt Pariatur&lt;/strong&gt; and the last updated is &lt;strong&gt;Ullamco Ad in Elit&lt;/strong&gt;.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="row"&gt;
    &lt;div class="col"&gt;
      &lt;form&gt;
        &lt;div class="input-group"&gt;
          &lt;span class="input-group-addon"&gt;&lt;i class="fa fa-search fa-fw"&gt;&lt;/i&gt;&lt;/span&gt;
          &lt;input class="form-control" [(ngModel)]="searchinput" name="searchinput" placeholder="Search a Fan Mission..." type="text"&gt;
        &lt;/div&gt;
      &lt;/form&gt;
    &lt;/div&gt;
    &lt;div class="col"&gt;
      &lt;div class="btn-group"&gt;
        &lt;span class="btn-group-addon"&gt;&lt;i class="fa fa-filter fa-fw"&gt;&lt;/i&gt;&lt;/span&gt;
        &lt;button type="button" class="btn btn-secondary" data-game-short="tdp"&gt;Thief: The Dark Project&lt;/button&gt;
        &lt;button type="button" class="btn btn-secondary" data-game-short="tg"&gt;Thief Gold&lt;/button&gt;
        &lt;button type="button" class="btn btn-secondary" data-game-short="tma"&gt;Thief II: The Metal Age&lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="row topbuffer-20"&gt;
    &lt;div class="col"&gt;
      &lt;table class="table table-hover table-bordered table-sm"&gt;
        &lt;thead class="thead-default"&gt;
          &lt;tr&gt;
            &lt;th class="align-middle text-center"&gt;#&lt;/th&gt;
            &lt;th class="align-middle"&gt;Fan Mission&lt;/th&gt;
            &lt;th class="align-middle text-center"&gt;Game&lt;/th&gt;
            &lt;th class="align-middle text-center"&gt;Version&lt;/th&gt;
            &lt;th class="align-middle text-center"&gt;NewDark&lt;/th&gt;
            &lt;th class="align-middle text-center"&gt;First release&lt;/th&gt;
            &lt;th class="align-middle text-center"&gt;Last update&lt;/th&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
          &lt;tr class="ectm-listedfanmission" *ngFor="let fanmission of fanmissions | EctmOrderFMsBy: 'name' | EctmFilterFMsBySearch: searchinput; let i = index"&gt;
            &lt;td class="align-middle text-center" scope="row"&gt;{{fanmission.index}}&lt;/td&gt;
            &lt;th class="align-middle text-capitalize"&gt;
              &lt;small&gt;{{fanmission.details.author.join(', ')}}&lt;/small&gt;&lt;br&gt;
              {{fanmission.name}}
            &lt;/th&gt;
            &lt;td class="align-middle text-center" title="{{fanmission.details.game.name}}"&gt;&lt;small&gt;{{fanmission.details.game.short}}&lt;/small&gt;&lt;/td&gt;
            &lt;td class="align-middle text-center"&gt;&lt;small&gt;{{fanmission.details.version}}&lt;/small&gt;&lt;/td&gt;
            &lt;td class="align-middle text-center" *ngIf="fanmission.details.isNewdark; else newdarknotrequired"&gt;&lt;i class="fa fa-check text-success"&gt;&lt;/i&gt;&lt;/td&gt;
            &lt;ng-template #newdarknotrequired&gt;&lt;td class="align-middle text-center"&gt;&lt;i class="fa fa-times text-danger"&gt;&lt;/i&gt;&lt;/td&gt;&lt;/ng-template&gt;
            &lt;td class="align-middle text-center"&gt;&lt;small&gt;{{fanmission.details.firstreleasedate | date:'yyyy/MM/dd'}}&lt;/small&gt;&lt;/td&gt;
            &lt;td class="align-middle text-center"&gt;&lt;small&gt;{{fanmission.details.lastupdatedate | date:'yyyy/MM/dd'}}&lt;/small&gt;&lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>What I have to do:</p>
  
  <ol>
  <li><strong>Filter items writing a value in the search input</strong>. The filter has to be able to filter by <strong>ID</strong> <em>(fanmission.index):number</em>, <strong>Name</strong> <em>(fanmission.name):string</em>, <strong>Author</strong> <em>(fanmission.details.author):string[]</em>, <strong>Game abbr</strong> <em>(fanmission.details.game.short):string</em>, <strong>Game fullname</strong> <em>(fanmission.details.game.name):string</em>, <strong>Version</strong> <em>(fanmission.details.version):string</em>, <strong>First release date</strong> <em>(fanmission.details.firstreleasedate):Date</em> and <strong>Last release date</strong> <em>(fanmission.details.lastupdatedate):Date</em>.</li>
  <li><strong>Filter items clicking on one of the three filter options</strong>. <strong>Thief: The Dark Project</strong> <em>("fanmission.details.game.short": "tdp")</em>; <strong>Thief Gold</strong> <em>("fanmission.details.game.short": "tg")</em> and <strong>Thief II: The Metal Age</strong> <em>("fanmission.details.game.short": "tma")</em>. When I click on <strong>Thief: The Metal Age</strong>, only items which have TDP in Game column should be visible. <strong>Only ONE</strong> option can be active at once. When I click on an active option, it has to be inactive and stop to filter the datatable.</li>
  <li><strong>Big heading at the top have to change and take the fullname of the game when one of the three filter options (buttons) is active</strong>. When I click on one of the these buttons (ex. <em>Thief: The Dark Project</em>), the items are filtered by game fullname and the big heading shows the game fullname (<em>Thief: The Dark Project</em>).</li>
  <li><strong>The paragraph below the big heading (game/filter title) have to be updated when using filter options.</strong> When I don't use any filter, the paragraph has to return the total amount of items in my database, the last published (this one which has the most recent date) and the last updated (this one which has the most last update date). When I search an item (search input), the amount of available itmes have to be present in this paragraph. The latest updated and the first item visible also have to be indicated in the paragraph with his respective name.</li>
  <li><strong>Each table head order the datatable content ASC/DESC</strong>. When I click on one of the the head columns, this one has to order the items present in the database ASC/DESC.</li>
  <li><strong>When there is no result searching by specific word (search input) the table has to indicate : No result found</strong>.</li>
  </ol>
  
  <p>I need to create custom Pipes and apply them to my <strong>ectm-list.component</strong>.</p>
  
  <p>Please, consider to see my project on GitHub in order to have an idea how it is structured: <a href="http://www.github.com/jonathanlinat/enhanced-cheapthiefmissions/" rel="nofollow noreferrer">http://www.github.com/jonathanlinat/enhanced-cheapthiefmissions/</a></p>
  
  <p>Can someone help me to achieve this big task?</p>
  
  <hr>
  
  <h1>1. Filter items writing a value in the search input</h1>
  
  <p>At this moment, I can only filter by <strong>NAME</strong>. This is my Pipe:</p>
  
  <pre><code>@Pipe({
    name: 'EctmFilterFMsBySearch'
  })
  export class EctmFilterFMsBySearchPipe implements PipeTransform {
  
    transform(value: any, arg: any): any {
      if (value != null &amp;&amp; arg != null) {
        var filteredfanmissions = value.filter((fanmission) =&gt; fanmission.name.search(new RegExp(arg, "i")) &gt;= 0);
        if (filteredfanmissions != 0) {
          return filteredfanmissions;
        }
      } else {
        return value;
      }
    }
  
  }
  </code></pre>
  
  <p>As you can see here...</p>
  
  <pre><code>value.filter((fanmission) =&gt; fanmission.name.search(new RegExp(arg, "i")) &gt;= 0);
  </code></pre>
  
  <p>...I need to change <em>fanmission.name</em> by applying the listed ones at the top of my post. How can I achieve that? Do I need to use a loop?</p>