Filtrado de cuadrícula Angular

    El componente IgniteUI para Angular Grid proporciona tres tipos de filtrado diferentes: filtrado rápido, filtrado de estilo Excel y filtrado avanzado que le permiten mostrar solo los registros que cumplen con los criterios especificados. El componente de cuadrícula Material UI en Ignite UI proporciona capacidades de filtro angular y una API de filtrado extensa a través del contenedor de datos al que está vinculada la cuadrícula.

    Angular Grid Filtering Example

    El siguiente ejemplo demuestra la experiencia de usuario de filtrado rápido de Grid. El método API filter() se utiliza para aplicar la condición de contenido en la columna ProductName a través del componente externo igxInputGroup.

    Setup

    Para especificar si el filtrado está habilitado y qué modo de filtrado se debe utilizar, Grid expone las siguientes propiedades booleanas: allowFiltering, allowAdvancedFiltering, filterMode y filterable.

    La propiedad enableFiltering le permite especificar las siguientes opciones:

    • falso: se desactivará el filtrado de la cuadrícula correspondiente; /valor por defecto/
    • verdadero: se habilitará el filtrado para la cuadrícula correspondiente;

    La propiedad enableAdvancedFiltering le permite especificar las siguientes opciones:

    • falso: se desactivará el filtrado avanzado para la cuadrícula correspondiente; /valor por defecto/
    • verdadero: se habilitará el filtrado avanzado para la cuadrícula correspondiente;

    La propiedad filterMode le permite especificar las siguientes opciones:

    • QuickFilter: una interfaz de usuario de filtrado simplista; /valor por defecto/
    • excelStyleFilter: una interfaz de usuario de filtrado similar a Excel;

    La propiedad filtrable le permite especificar las siguientes opciones:

    • verdadero: se habilitará el filtrado para la columna correspondiente; /valor por defecto/
    • falso: se desactivará el filtrado de la columna correspondiente;
    <igx-grid #grid1 [data]="data" [autoGenerate]="false" [allowFiltering]="true">
        <igx-column field="ProductName"></igx-column>
        <igx-column field="Price" [dataType]="'number'" [filterable]="false">
    </igx-grid>
    

    Sin embargo, para habilitar el filtrado avanzado, debe establecer las propiedades de entrada allowAdvancedFiltering en true.

    <igx-grid [data]="data" [autoGenerate]="true" [allowAdvancedFiltering]="true">
    </igx-grid>
    
    Note

    Puede habilitar tanto quickFilter / excelStyleFilter como las interfaces de usuario de filtrado avanzado en Grid. Ambas interfaces de usuario de filtrado funcionarán de forma independiente. El resultado final filtrado en la Cuadrícula es la intersección entre los resultados de los dos filtros.

    Interaction

    Para abrir la fila de filtro para una columna en particular, se debe hacer clic en el chip 'Filtro' debajo de su encabezado. Para agregar condiciones, debe elegir el operando de filtro usando el menú desplegable a la izquierda de la entrada e ingresar el valor. Para las columnas number y date, se selecciona "Igual" de forma predeterminada, para string, "Contiene" y para boolean, "Todos". Al presionar 'Entrar' se confirma la condición y ahora podrá agregar otra. Hay un menú desplegable entre los chips de 'condición', que determina el operador lógico entre ellos; 'Y' está seleccionado de forma predeterminada. Para eliminar una condición, puede hacer clic en el botón 'X' del chip y, para editarla, debe seleccionar el chip y la entrada se completará con los datos del chip. Mientras la fila de filtro está abierta, puede hacer clic en el encabezado de cualquier columna filtrable para seleccionarla y poder agregarle condiciones de filtro.

    Si bien se han aplicado algunas condiciones de filtrado a una columna y la fila de filtro está cerrada, puede eliminar las condiciones haciendo clic en el botón de cerrar del chip o puede abrir la fila de filtro seleccionando cualquiera de los chips. Cuando no hay suficiente espacio para mostrar todas las condiciones, se muestra un ícono de filtro con una insignia que indica cuántas condiciones más hay. También se puede hacer clic en él para abrir la fila de filtro.

    Usage

    Hay una estrategia de filtrado predeterminada que se proporciona lista para usar, así como todas las condiciones de filtrado estándar, que el desarrollador puede reemplazar con su propia implementación. Además, proporcionamos una manera de conectar fácilmente sus propias condiciones de filtrado personalizadas. Actualmente, Grid proporciona no solo una interfaz de usuario de filtrado simplista, sino también opciones de filtrado más complejas. Dependiendo del dataType establecido de la columna, el conjunto correcto de operaciones de filtrado se carga dentro del menú desplegable de la interfaz de usuario del filtro. Además, puede configurar las propiedades ignoreCase y de condition inicial.

    La función de filtrado se habilita para el componente Grid configurando la entrada allowFiltering en true. El filterMode predeterminado es quickFilter y no se puede cambiar en tiempo de ejecución. Para deshabilitar esta función para una determinada columna, establezca la entrada filterable en false.

    <igx-grid [data]="data" [autoGenerate]="false" [allowFiltering]="true">
        <igx-column field="ProductName"></igx-column>
        <igx-column field="Price" dataType="number"></igx-column>
        <igx-column field="Discontinued" [dataType]="'boolean'" [filterable]="false">
    </igx-grid>
    
    Note

    Si una string de tipo de datos Date utiliza valores de tipo cadena, Grid no los analizará en objetos Date y no será posible utilizar condiciones de filtrado. Si desea utilizar objetos string, se debe implementar una lógica adicional en el nivel de la aplicación para analizar los valores en objetos Date.

    Puede filtrar cualquier columna o una combinación de columnas a través de la API de Grid. El Grid expone varios métodos para esta tarea: filter, filterGlobal y clearFilter.

    • filter: filtra una sola columna o una combinación de columnas.

    Hay cinco clases de operandos de filtrado expuestas:

    // Single column filtering
    
    // Filter the `ProductName` column for values which `contains` the `myproduct` substring, ignoring case
    this.grid.filter('ProductName', 'myproduct', IgxStringFilteringOperand.instance().condition('contains'), true);
    

    Los únicos parámetros obligatorios son la clave del campo de la columna y el término de filtrado. Tanto la condición como la distinción entre mayúsculas y minúsculas se deducirán de las propiedades de la columna si no se proporcionan. En el caso de filtrado múltiple, el método acepta una serie de expresiones de filtrado.

    Note

    La operación de filtrado NO cambia la fuente de datos subyacente del Grid.

    // Multi column filtering
    
    const gridFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And);
    const productFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
    const productExpression = {
        condition: IgxStringFilteringOperand.instance().condition('contains'),
        fieldName: 'ProductName',
        ignoreCase: true,
        searchVal: 'ch'
    };
    productFilteringExpressionsTree.filteringOperands.push(productExpression);
    gridFilteringExpressionsTree.filteringOperands.push(productFilteringExpressionsTree);
    
    const priceFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'Price');
    const priceExpression = {
        condition: IgxNumberFilteringOperand.instance().condition('greaterThan'),
        fieldName: 'UnitPrice',
        ignoreCase: true,
        searchVal: 20
    };
    priceFilteringExpressionsTree.filteringOperands.push(priceExpression);
    gridFilteringExpressionsTree.filteringOperands.push(priceFilteringExpressionsTree);
    
    this.grid.filteringExpressionsTree = gridFilteringExpressionsTree;
    
    • filterGlobal: borra todos los filtros existentes y aplica la nueva condición de filtrado a todas las columnas de Grid.
    // Filter all cells for a value which contains `myproduct`
    this.grid.filteringLogic = FilteringLogic.Or;
    this.grid.filterGlobal('myproduct', IgxStringFilteringOperand.instance().condition('contains'), false);
    
    • clearFilter: elimina cualquier filtrado aplicado a la columna de destino. Si se llama sin argumentos, borrará el filtrado de todas las columnas.
    // Remove the filtering state from the ProductName column
    this.grid.clearFilter('ProductName');
    
    // Clears the filtering state from all columns
    this.grid.clearFilter();
    

    Initial filtered state

    Para establecer el estado de filtrado inicial de Grid, establezca la propiedad filteringExpressionsTree IgxGridComponent en una matriz de IFilteringExpressionsTree para cada columna que se va a filtrar.

    constructor(private cdr: ChangeDetectorRef) { }
    
    public ngAfterViewInit() {
        const gridFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And);
        const productFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
        const productExpression = {
            condition: IgxStringFilteringOperand.instance().condition('contains'),
            fieldName: 'ProductName',
            ignoreCase: true,
            searchVal: 'c'
        };
        productFilteringExpressionsTree.filteringOperands.push(productExpression);
        gridFilteringExpressionsTree.filteringOperands.push(productFilteringExpressionsTree);
    
        this.grid.filteringExpressionsTree = gridFilteringExpressionsTree;
        this.cdr.detectChanges();
    }
    

    Filtering logic

    La propiedad filteringLogic de Grid controla cómo se resolverá el filtrado de varias columnas en Grid. Puede cambiarlo en cualquier momento a través de la API de Grid o mediante la propiedad de entrada de Grid.

    import { FilteringLogic } from 'igniteui-angular';
    // import { FilteringLogic } from '@infragistics/igniteui-angular'; for licensed package
    ...
    
    this.grid.filteringLogic = FilteringLogic.OR;
    

    El valor predeterminado de AND devuelve solo las filas que coinciden con todas las expresiones de filtrado aplicadas actualmente. Siguiendo el ejemplo anterior, se devolverá una fila cuando el valor de la celda 'NombreProducto' contenga 'miproducto' y el valor de la celda 'Precio' sea mayor que 55.

    Cuando se establece en OR, se devolverá una fila cuando el valor de la celda 'NombreProducto' contenga 'miproducto' o el valor de la celda 'Precio' sea mayor que 55.

    Remote Filtering

    Grid admite el filtrado remoto, que se demuestra en el tema Grid Remote Data Operations.

    Custom Filtering Operands

    Puede personalizar el menú de filtrado agregando, eliminando o modificando los operandos de filtrado. De forma predeterminada, el menú de filtrado contiene ciertos operandos basados en el tipo de datos de la columna (IgxBooleanFilteringOperand, IgxDateFilteringOperand, IgxNumberFilteringOperand e IgxStringFilteringOperand). Puede ampliar estas clases o su clase base IgxFilteringOperand para cambiar el comportamiento de los elementos del menú de filtrado.

    En el siguiente ejemplo, inspeccione los menús de filtros de las columnas "Nombre del producto" y "Discontinuado". Para el filtro de columna "Descontinuado", hemos limitado el número de operandos a Todos, Verdadero y Falso. Para el filtro de columna "Nombre del producto", hemos modificado la lógica de operandos Contiene y No contiene para realizar una búsqueda que distinga entre mayúsculas y minúsculas y también agregamos operandos vacíos y no vacíos.

    Para hacer eso, extienda IgxStringFilteringOperand e IgxBooleanFilteringOperand, modifique las operaciones y su lógica y establezca la entrada filters de columna en los nuevos operandos.

    // grid-custom-filtering.component.ts
    
    export class GridCustomFilteringComponent {
        public caseSensitiveFilteringOperand = CaseSensitiveFilteringOperand.instance();
        public booleanFilteringOperand = BooleanFilteringOperand.instance();
    }
    
    export class CaseSensitiveFilteringOperand extends IgxStringFilteringOperand {
        private constructor() {
            super();
            const customOperations = [
                {
                    iconName: 'contains',
                    isUnary: false,
                    logic: (target: string, searchVal: string, ignoreCase?: boolean) => {
                        ignoreCase = false;
                        const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase);
                        target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase);
                        return target.indexOf(search) !== -1;
                    },
                    name: 'Contains (case sensitive)'
                },
                {
                    iconName: 'does_not_contain',
                    isUnary: false,
                    logic: (target: string, searchVal: string, ignoreCase?: boolean) => {
                        ignoreCase = false;
                        const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase);
                        target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase);
                        return target.indexOf(search) === -1;
                    },
                    name: 'Does Not Contain (case sensitive)'
                }
            ];
    
            const emptyOperators = [
                // 'Empty'
                this.operations[6],
                // 'Not Empty'
                this.operations[7]
            ];
    
            this.operations = customOperations.concat(emptyOperators);
        }
    }
    
    export class BooleanFilteringOperand extends IgxBooleanFilteringOperand {
        private constructor() {
            super();
            this.operations = [
                // 'All'
                this.operations[0],
                // 'TRUE'
                this.operations[1],
                // 'FALSE'
                this.operations[2]
            ];
        }
    }
    
    <!-- grid-custom-filtering.component.html -->
    
    <igx-grid [data]="data" [autoGenerate]="false" [allowFiltering]="true">
        <igx-column field="ProductName" header="Product Name" [filters]="caseSensitiveFilteringOperand"></igx-column>
        <igx-column field="Discontinued" header="Discontinued" [dataType]="'boolean'" [filters]="booleanFilteringOperand">
            <ng-template igxCell let-cell="cell" let-val>
                <img *ngIf="val" src="assets/images/grid/active.png" title="Delivered" alt="Delivered" />
                <img *ngIf="!val" src="assets/images/grid/expired.png" title="Undelivered" alt="Undelivered" />
            </ng-template>
        </igx-column>
    </igx-grid>
    

    Re-templating filter cell

    Puede agregar una plantilla marcada con igxFilterCellTemplate para volver a crear la plantilla de la celda del filtro. En el siguiente ejemplo, se agrega una entrada para las columnas de cadena y IgxDatePicker para la columna de fecha. Cuando el usuario escribe o selecciona un valor, se aplica un filtro con el operador contiene para las columnas de cadena y el operador igual para las columnas de fecha mediante la API pública de grid.

    Estilismo

    Para comenzar a diseñar la fila de filtrado, necesitamos importar el archivo index, donde se encuentran todas las funciones del tema y los mixins de componentes:

    @use "igniteui-angular/theming" as *;
    
    // IMPORTANT: Prior to Ignite UI for Angular version 13 use:
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    

    Siguiendo el enfoque más simple, creamos un nuevo tema que amplía la grid-theme y acepta la $filtering-row-text-color, $filtering-row-background, $filtering-header-text-color y el $filtering-header-background parámetros.

    $custom-grid: grid-theme(
        $filtering-row-text-color: #292826,
        $filtering-row-background: #FFCD0F,
        $filtering-header-text-color: #292826,
        $filtering-header-background: #FFCD0F
    );
    

    Como se ve, el grid-theme solo controla los colores de la fila de filtrado y el encabezado de columna respectivo que se está filtrando. Obviamente tenemos muchos más componentes dentro de la fila de filtrado, como un grupo de entrada, chips, botones y otros. Para darles estilo, necesitamos crear un tema separado para cada uno, así que creemos un nuevo tema de grupo de entrada y un nuevo tema de botón:

    $dark-input-group: input-group-theme(
        $box-background: #FFCD0F,
        $idle-text-color: #292826,
        $focused-text-color: #292826,
        $filled-text-color: #292826
    );
    
    $dark-button: button-theme(
        $flat-background: #FFCD0F,
        $flat-text-color: #292826,
        $flat-hover-background: #292826,
        $flat-hover-text-color: #FFCD0F
    );
    

    En este ejemplo solo cambiamos algunos de los parámetros para el grupo de entrada y el botón, pero el input-group-theme y el button-theme proporcionan muchos más parámetros para controlar su estilo respectivo.

    El último paso es incluir los mixins de componentes, cada uno con su respectiva temática. También estableceremos la propiedad de color para el marcador de posición de la entrada.

    @include grid($custom-grid);
    .igx-grid__filtering-row {
        @include button($dark-button);
        @include input-group($dark-input-group);
    
        .igx-input-group__input::placeholder {
            color: #FFCD0F;
        }
    }
    
    Note

    Ajustamos el alcance de los mixins igx-button y igx-input-group dentro de.igx-grid__filtering-row, de modo que solo se apliquen estilos a los botones de la fila de filtrado y su grupo de entrada. De lo contrario, otros botones y grupos de entrada de la cuadrícula también se verían afectados.

    Note

    Si el componente utiliza una ViewEncapsulation Emulated, es necesario penetrate esta encapsulación usando::ng-deep:

    :host {
         ::ng-deep {
            @include grid($custom-grid);
            .igx-grid__filtering-row {
                @include button($dark-button);
                @include input-group($dark-input-group);
    
                .igx-input-group__input::placeholder {
                    color: #FFCD0F;
                }
            }
        }
    }
    

    Defining a color palette

    En lugar de codificar los valores de color como acabamos de hacer, podemos lograr una mayor flexibilidad en términos de colores utilizando las funciones igx-palette e igx-color.

    igx-palette genera una paleta de colores basada en los colores primarios y secundarios que se pasan:

    $yellow-color: #FFCD0F;
    $black-color: #292826;
    
    $dark-palette: palette($primary: $black-color, $secondary: $yellow-color);
    

    Y luego con igx-color podemos recuperar fácilmente el color de la paleta.

    $custom-grid: grid-theme(
        $filtering-row-text-color: color($dark-palette, "primary", 400),
        $filtering-row-background: color($dark-palette, "secondary", 400),
        $filtering-header-text-color: color($dark-palette, "primary", 400),
        $filtering-header-background: color($dark-palette, "secondary", 400)
    );
    
    $dark-input-group: input-group-theme(
        $box-background: color($dark-palette, "secondary", 400),
        $idle-text-color: color($dark-palette, "primary", 400),
        $focused-text-color: color($dark-palette, "primary", 400),
        $filled-text-color: color($dark-palette, "primary", 400)
    );
    
    $dark-button: button-theme(
        $flat-background: color($dark-palette, "secondary", 400),
        $flat-text-color: color($dark-palette, "primary", 400),
        $flat-hover-background: color($dark-palette, "primary", 400),
        $flat-hover-text-color: color($dark-palette, "secondary", 400)
    );
    
    Note

    igx-color e igx-palette son funciones potentes para generar y recuperar colores. Consulte el tema Palettes para obtener orientación detallada sobre cómo utilizarlas.

    Using Schemas

    Yendo más allá con el motor de temas, puede crear una estructura sólida y flexible que se beneficie de los esquemas. Un esquema es una receta de un tema.

    Amplíe uno de los dos esquemas predefinidos, que se proporcionan para cada componente, en este caso: esquemas light-grid, light-input-group y light-button:

    // Extending the light grid schema
    $custom-grid-schema: extend($_light-grid,
        (
            filtering-row-text-color:(
               color: ("primary", 400)
            ),
            filtering-row-background:(
               color: ("secondary", 400)
            ),
            filtering-header-text-color:(
               color: ("primary", 400)
            ),
            filtering-header-background:(
               color: ("secondary", 400)
            )
        )
    );
    
    // Extending the light input group schema
    $custom-input-group-schema: extend($_light-input-group,
        (
            box-background:(
               color: ("secondary", 400)
            ),
            idle-text-color:(
               color: ("primary", 400)
            ),
            focused-text-color:(
               color: ("primary", 400)
            ),
            filled-text-color:(
               color: ("primary", 400)
            )
        )
    );
    
    // Extending the light button schema
    $custom-button-schema: extend($_light-button,
        (
            flat-background:(
               color: ("secondary", 400)
            ),
            flat-text-color:(
               color: ("primary", 400)
            ),
            flat-hover-background:(
               color: ("primary", 400)
            ),
            flat-hover-text-color:(
               color: ("secondary", 400)
            )
        )
    );
    

    Para aplicar nuestros esquemas personalizados, tenemos que extender uno de los globales (light u dark), que básicamente señala los componentes con un esquema personalizado, y luego agregarlo a los respectivos temas de los componentes:

    // Extending the global light-schema
    $custom-light-schema: extend($light-schema,(
        igx-grid: $custom-grid-schema,
        igx-input-group: $custom-input-group-schema,
        igx-button: $custom-button-schema
    ));
    
    // Defining grid-theme with the global light schema
    $custom-grid: grid-theme(
      $palette: $dark-palette,
      $schema: $custom-light-schema
    );
    
    // Defining button-theme with the global light schema
    $custom-button: button-theme(
      $palette: $dark-palette,
      $schema: $custom-light-schema
    );
    
    // Defining input-group-theme with the global light schema
    $custom-input-group: input-group-theme(
      $palette: $dark-palette,
      $schema: $custom-light-schema
    );
    

    No olvide incluir los temas de la misma manera que se demostró anteriormente.

    Demo

    Note

    La muestra no se verá afectada por el tema global seleccionado en Change Theme.

    Known Limitations

    Note

    Algunos navegadores, como Firefox, no analizan los separadores decimales específicos de una región al considerarlos como separadores de agrupación, lo que hace que no sean válidos. Al ingresar dichos valores para un valor de filtro de columna numérica, solo se aplicará la parte válida del número a la expresión de filtrado. Para obtener más información, consulte el problema de Firefox.

    Breaking Changes in 6.1.0

    • Se elimina la propiedad IgxGrid filteringExpressions. Utilice filteringExpressionsTree en su lugar.
    • Se elimina el método filter_multiple. Utilice el método filter y la propiedad filteringExpressionsTree en su lugar.
    • El método filter tiene una nueva firma. Ahora acepta los siguientes parámetros:
      • name: el nombre de la columna que se va a filtrar.
      • value: el valor que se utilizará para el filtrado.
      • conditionOrExpressionTree (opcional): este parámetro acepta objetos de tipo IFilteringOperation o IFilteringExpressionsTree. Si sólo se necesita un filtrado simple, se podría pasar una operación de filtrado como argumento. En el caso de filtrado avanzado, se podría pasar como argumento un árbol de expresiones que contenga una lógica de filtrado compleja.
      • ignoreCase (opcional): si el filtrado distingue entre mayúsculas y minúsculas o no.
    • El evento filteringDone ahora tiene solo un parámetro de tipo IFilteringExpressionsTree que contiene el estado de filtrado de la columna filtrada.
    • Operandos de filtrado: la propiedad de condición IFilteringExpression ya no es una referencia directa a un método de condición de filtrado, sino que es una referencia a IFilteringOperation.
    • IgxColumnComponent ahora expone una propiedad filters, que toma una referencia de clase IgxFilteringOperand.
    • Se pueden proporcionar filtros personalizados a las columnas de Grid completando la propiedad operations de IgxFilteringOperand con operaciones de tipo IFilteringOperation.

    API References

    Additional Resources

    Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.