Filter in my table created with Ngfor

Asked

Viewed 1,227 times

0

I created a table with Ngfor (actually, my whole project uses ngFor structures as default), I saw that there is an Ngrepeat and there is a filter for it. In order to avoid migrating my ngFor project, there is some way to filter my table?

I would use a text field and the entered value would be filtered (can be either by specific field or generalist)

I have tried using Pipetransform, but without success.

Html:

<div>
<table class="table table-striped">
    <thead>
      <tr>
        <th scope = "col">PID            </th>
        <th scope = "col">CODIGO        </th>
        <th scope = "col">CLIENTE       </th>
        <th scope = "col">SIGLA_RM      </th>
        <th scope = "col">SIGLA_PORTAL  </th>
        <th scope = "col">COMERCIAL     </th>
        <th scope = "col">ATENDIMENTO   </th>
        <th scope = "col">AUDITORIA     </th>
        <th scope = "col">PERIODICIDADE </th>
        <th scope = "col">ENTREGA       </th>
        <th scope = "col">RESPONSAVEL   </th>
        <th scope = "col">Comando       </th>
      </tr>
    </thead>

<tbody>

<tr *ngFor = 'let planilha of planilha '>
      <td>
        {{planilha.ID}}
      </td>
      <td>
          {{planilha.CODIGO}}
      </td>
      <td>
          {{planilha.CLIENTE}}
      </td>
      <td>
          {{planilha.SIGLA_RM}}
      </td>

      <td>
          {{planilha.SIGLA_PORTAL}}
      </td>

      <td>
          {{planilha.AUDITORIA}}
      </td>

      <td>
          {{planilha.PERIODICIDADE}}
      </td>

      <td>
          {{planilha.ENTREGA}}
      </td>
      <td>
          {{planilha.RESPONSAVEL}}
      </td>
      <td>
          {{planilha.LAYOUT}}
      </td>

      <td>
          {{planilha.ODS}}
      </td>
      <td scope = "col">
        <img src="assets/Detalhes.png" [routerLink]="['/detalhes/',planilha.PID]" width="25px"/>
        <img src="assets/excluir.png" (click)="deletaProd(planilha.PID)" width="25px"/>
      </td>

</tr>
</tbody>
</table>
</div>

Typescript:

import { Component, OnInit,Input, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-planilhaweb',
  templateUrl: './planilhaweb.component.html',
  styleUrls: ['./planilhaweb.component.css']
})
export class PlanilhawebComponent implements OnInit, OnDestroy {
  @Input('planilha') public planilha
  public xmlHttp = new XMLHttpRequest();
  public detalhes: boolean = true
  public detalhesId: number

  constructor() { 
    this.dao();
  }


  ngOnDestroy(){

  }

  ngOnInit() {
  }

   public deletaProd(id){
    function reqListener () {
      console.log('tentou excluir ',id)

    };

    var oReq = new XMLHttpRequest();
    oReq.onload = reqListener;
    oReq.open("DELETE", "http://localhost:51230/api/logs/deletar/plan/"+id+"", true);
    oReq.send();
    this.dao();
    this.load();
  }


  public detalhesProd(id){
    this.detalhesId = id;
    this.detalhes = !this.detalhes;
    console.log(this.detalhesId)
  }

  dao(){
//CONEXAO COM A API
async function getPlanilha()
{
  const response = await fetch(`http://localhost:51230/api/logs/producao/plan/`);
  return await response.json();
}

//promisses
getPlanilha()
  .then((planilha) => this.planilha = planilha)
}

load() {
  //Session storage salva os dados como string

  (sessionStorage.refresh == 'true' || !sessionStorage.refresh) && location.reload();
  sessionStorage.refresh = true;

}


}

Updating:

exemplo

I was able to filter my vector (json), but the table does not change dynamically by following the filter, as this should be done?

2 answers

1


I believe that answer will help you

https://stackoverflow.com/questions/52739260/add-search-filter-to-angular-6-datatable

Just describing the resolution of the above answer

Just create an array that will contain the array data spreadsheet (Example spreadsheet), however filtered, and it will be used in ngFor and whenever you type something in the text field, it will call a function to update the created array (spreadsheet) from the array spreadsheet.

Example:

<input type="text" (keyup)='filtrar($event.target.value)'>

And in your file . ts

filtrar(value: string) {
   if(!value) {
      this.planilhaFilter = this.planilha;
   } else {
     this.planilhaFilter = this.planilha.filter(x => 
        x.CLIENTE.trim().toLowerCase().includes(value.trim().toLowerCase())
     );
   }
}

EDITED

If Voce is requesting some API after the data is filtered and wants to show only according to the filter, Voce can create a variable for filter input, define a ngModel and call the filter function on ngModelChange.

Example:

<input type="text" [(ngModel)]="filtro" (ngModelChange)='filtrar(filtro)'>

And add the variable in your file . ts

filtro: string = "";

And right after you take the API data, add this data to the spreadsheet variable and call the function filter passing the filter as a parameter.

Archive . ts

this.filtrar(this.filtro);
  • I was able to filter, however, how do I change the display according to the returned json? I’m having trouble fitting you into my asynchronous call. Thank you very much!

  • @Francogenaro edited the answer and added this resolution for what I understood of your question.

  • @Gabriel Ferreira, I added an issue, I think I expressed myself badly. Everything’s already going according to plan except the animation, I’m having a hard time finding content on that. I tried your code but it brought me a mistake: Can’t bind to 'ngModel' Since it isn’t a known Property of 'input'. ("<div> <input type="text" [ERROR ->][(ngModel)]="filter" (ngModelChange)='filter(filter)'> <table class="table table-Striped">

  • @Francogenaro this answer should help you: https://stackoverflow.com/questions/38892771/cant-bind-to-ngmodel-since-it-isnt-a-known-property-of-input

  • Not much ;( has no form on this page and nothing that behaves like a form that would doubt the link. I would need my TR to track my JSON changes, probably some change in ngfor...

  • I say on the issue of ngModel error, what is missing is just an import in your app.component.ts. In the link I gave you he says that. Otherwise just follow what I’ve given you that will probably work.

Show 1 more comment

0

Complementing the answer of @Gabryel, which was correct, in the implementation it was only necessary to apply this filter in the variable "Spreadsheet" and not in the "Filter Spreadsheet", after all, all my HTML was aimed at "Spreadsheet".

Follow the code of my filter:

filtrar(value: string) {
      this.planilha = this.planilhaFilter
    if(!value) {
       this.planilha = this.planilha;
    } else {
      this.planilha = this.planilha.filter(x => 
         x.ATENDIMENTO.trim().toLowerCase().includes(value.trim().toLowerCase())
      );
    }
 }

For those who apply, the line where I put this.spreadsheet = this.spreadsheetFilter, I use the variable "worksheet" as a guarantor of my total value, so I don’t need to send more requests to my bank, if you don’t do it this way, the variable will decrease to each filter applied, until no return.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.