javascript - Filtro global personalizado en PrimeNG (FilterService)
Me estaba enfrentando a un problema al filtrar la p-table en PrimeNG. Escenario:
tabla que contiene: John Kelvin Doe
Clave de búsqueda: John Doe
esperado: 1 fila, estaba obteniendo 0 filas usando filtros incorporados;
Intenté los filtros integrados, pero estaba obteniendo 0 registros.
He creado un Filtro Global Personalizado que verifica si la entrada tiene dos palabras y luego comprueba los filtros startsWith y endsWith.
onGlobalFilter(table: Table, event: Event) {
table.filterGlobal((event.target as HTMLInputElement).value, 'customContains');
}
private configureFilter () {
// build-in filter
let containsFilter = this.filterService.filters['contains'];
let startsWithFilter = this.filterService.filters['startsWith'];
let endsWithFilter = this.filterService.filters['endsWith'];
// register custom filter
this.filterService.register("customContains", (value, filter): boolean => {
if (filter === undefined || filter === null || filter.trim() === '') {
return true;
}
if (value === undefined || value === null) {
return false;
}
const str = filter.trim().split(" ");
if (str.length === 2 ) {
console.log(filter)
return startsWithFilter(value, str[0]) && endsWithFilter(value, str[1]);
} else {
return containsFilter(value, filter);
}
});
}
Escenario 2: clave de búsqueda: john man doe entradas de la tabla: john man doe han
El filtro de arriba no está funcionando.
Estoy buscando una solución que dé el resultado correcto para N número de palabras.
Respuesta #1
John Kelvin Doe
no contiene
John Doe
Contiene John y contiene Doe, pero no contiene John Doe. Si quieres encontrar entradas que contengan ambas palabras, entonces necesitarás buscar un filtro de contiene para ambas y poner un && entre ellas.
john hombre doe han
comienza con
john hombre doe
pero no termina con
john hombre doe
Por lo tanto, no es cierto que comience con john man doe Y termine con ello. Así que, en lugar de tu
const str = filter.trim().split(" ");
if (str.length === 2 ) {
console.log(filter)
return startsWithFilter(value, str[0]) && endsWithFilter(value, str[1]);
} else {
return containsFilter(value, filter);
}
Yo recomiendo
const str = filter.trim().split(" ");
for (let f of filter) {
if (!containsFilter(value, f)) return false;
}
return true;
como la solución. Básicamente, dividimos el filtro por espacios y recorremos los elementos y verificamos para cada uno si están contenidos en value.
Respuesta #2
No estoy seguro si esto coincide con la última tabla de PrimeNG.
<p-table
...
[globalFilterFields]="['column_name']">
<button (click)="table.filterGlobal(['ValueOne', 'ValueTwo'], 'in')"></button>
<button (click)="table.filterGlobal('ValueOne', 'contains')"></button>
La clave es la "restricción" in y contains. Vea las otras restricciones del servicio de filtros
