2
votes

Comment afficher les filtres enregistrés dans les en-têtes avec PrimeNG?

Je peux enregistrer les filtres localement en utilisant stateStorage = "local" stateKey = "myKey" . Ainsi, lorsque l'utilisateur quitte le composant et retourne, les données sont toujours filtrées en fonction des filtres définis.

Le problème est que l'utilisateur n'a plus aucune idée de ce sur quoi il filtre, car les en-têtes de filtre ne leur montrent plus rien, juste l'étiquette par défaut. Je peux accéder aux filtres via le stockage local et les supprimer en utilisant localStorage.removeItem ("myKey"); , mais je ne peux pas pour la vie de moi comprendre comment obtenir ces informations de filtre à afficher dans le en-têtes de filtre. Nous n'utilisons pas lazyLoad, comme suggéré dans une autre réponse. On pourrait penser que cela serait construit à chaque fois qu'un filtre est enregistré, car ne pas savoir sur quoi vous filtrez semble être un défaut majeur.

Pour plus de clarté, j'ai joint la documentation de primeFaces ci-dessous. Si vous sélectionnez «Rouge», «Blanc» et «Vert» dans la liste déroulante à sélection multiple, le filtre sélectionné s'affichera dans l'en-tête (Rouge, Blanc, Vert) ci-dessus. J'ai besoin de ces informations pour les afficher à chaque fois que l'utilisateur entre dans le composant s'il a des filtres enregistrés (à la fois avec la saisie de texte et avec les listes déroulantes).

https://www.primefaces.org/primeng/#/table/filter

J'utilise la sélection multiple filtres déroulants, saisie de texte et filtres de calendrier. Voici un extrait du code HTML, qui comprend des exemples de ces trois types de filtres:

    <th *ngFor="let col of columns" [ngSwitch]="col.field">                                               
      <input *ngSwitchCase="'userID'" pInputText type="text" size="12" placeholder="contains" (input)="table.filter($event.target.value, col.field, col.filterMatchMode)" [value]="table.filters['userID'] ? table.filters['userID'].value : ''">       
      <div class="ui-g ui-fluid">
        <p-calendar #calendar1 class="ui-fluid" *ngSwitchCase="'myDate'" [monthNavigator]="true" [showOnFocus]="false" [yearNavigator]="true" yearRange="2010:2060" [showIcon]="true" 
          [showOtherMonths]="false" [showButtonBar]="true" [appendTo]="attach"  [style]="{'overflow': 'visible'}" 
          [(ngModel)]="calendar1Filter" 
          (ngModelChange)="table.filter($event, 'myDate', calendar1Option)"                                                                                 
          (onSelect)="table.filter($event, 'myDate', calendar1Option)">
            <p-footer>  
                <div class="ui-grid-row">
                    <div class="ui-grid-col-3"><label style="font-weight: bold; color: #337ab7">Mode:</label></div>                     
                    <div class="ui-grid-col-6"><p-dropdown [options]="calendar1Options" [style]="{'width':'60px', 'padding-top': '0px'}" [(ngModel)]="calendar1Option" (onChange)="onChangeModCalOpt(calendar1, 1)" ></p-dropdown> </div>
                </div>
             </p-footer>
         </p-calendar>   
       </div>                                  
      <div class="ui-fluid">
        <p-multiSelect *ngSwitchCase="'myDropdown'" appendTo="body" [options]="dropdownOptions" pInputText type="text" size="12" [style]="{'width':'100%'}" defaultLabel="All" [(ngModel)]="myDropdownFilter" (onChange)="table.filter($event.value, col.field, 'in')"></p-multiSelect>
      </div>
     </th>


2 commentaires

Pouvez-vous fournir le component.html du tableau? Les filtres sont-ils dans l'entrée d'en-tête, dans la zone de sélection ou dans les deux?


Ajout d'un exemple des filtres que j'utilise. C'est une boîte de sélection et une entrée ainsi que des calendriers.


3 Réponses :


0
votes

Je l'ai fait il y a presque un an; cela impliquait un code délicat, comme vous le verrez ci-dessous, car l'élément de table était sous une directive * ngIf . Je ne sais pas si votre cas est le même, mais si c'est le cas, voici ce que j'ai dû faire pour que cela fonctionne. Dans l'exemple, j'ai un fooTable qui a un filtre personnalisé sur la colonne status .

foo.component.ts : p>

<ng-container *ngIf="showFooTable">
    <div id="filters">
        <p-checkbox [(ngModel)]="statusFilter" value="up"      (onChange)="fooTable.filter(statusFilter, 'status', 'in')"></p-checkbox> Up
        <p-checkbox [(ngModel)]="statusFilter" value="down"    (onChange)="fooTable.filter(statusFilter, 'status', 'in')"></p-checkbox> Down
        <p-checkbox [(ngModel)]="statusFilter" value="unknown" (onChange)="fooTable.filter(statusFilter, 'status', 'in')"></p-checkbox> Unknown
    </div>

    <p-table #fooTable
             stateStorage="session"
             stateKey="foo-table-state">
    </p-table>
</ng-container>

foo.component.html :

import { ChangeDetectorRef, Component, ViewChild } from "@angular/core";

@Component({
    selector    : 'foo',
    templateUrl : 'foo.component.html'
})
export class FooComponent {
    // members /////////////////////////////////////////////////////////////////////////////////////////////////////////
    showFooTable: boolean  = true;
    statusFilter: string[] = [];

    // constructor(s) //////////////////////////////////////////////////////////////////////////////////////////////////
    constructor(private cd: ChangeDetectorRef) { }

    // getters and setters /////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * Due to the Angular lifecycle, we have to do some tricky things here to pull the filters from the session,
     * if they are present. The workarounds done in this function are as follows:
     *
     * 1) Wait until the element is accessible. This is not until the *ngIf is rendered, which is the second call to
     *    this function. The first call is simply 'undefined', which is why we check for that and ignore it.
     * 2) Check and see if the filters for this object are even part of the template. If not, just skip this step.
     * 3) If we find the filters in the session, then change this object's filters model to equal it and call the change
     *    detection manually to prevent Angular from throwing an ExpressionChangedAfterItHasBeenCheckedError error
     * @param fooTable the reference to the foo table template
     */
    @ViewChild('fooTable') set fooTable(fooTable: any) {
        if(fooTable != undefined) {
            let filters = fooTable.filters['status'];
            if (filters != undefined && filters.value != undefined) {
                this.statusFilter = filters.value;
            }
            this.cd.detectChanges();
        }
    }
}


0 commentaires

0
votes

Les filtres de tables Turbo peuvent être accédés comme ça. table.filters ['maColonne'] ?. valeur . Vous aurez besoin de définir les valeurs d'entrée dans l'en-tête, [value ="table.filters[col.field ?.value"

...
<tr>
    <th *ngFor="let col of columns" [ngSwitch]="col.field" class="ui-fluid">
        <input pInputText 
               type="text"
               (input)="table.filter($event.target.value, col.field, col.filterMatchMode)"
               [value]="table.filters[col.field]?.value">
    </th>
</tr>
...

https://www.primefaces.org/primeng/#/table/state p>


0 commentaires

0
votes

Je viens juste de comprendre. Ce que j'ai fini par faire, c'est d'attacher l'étiquette par défaut à un modèle comme ceci:

<p-multiSelect [defaultLabel]="table.filters[col.field]?.value || 'All'">

Si la table a la valeur de filtre dans son état, elle remplira l'étiquette par défaut à «Tous».


0 commentaires