Filtrado de cuadrícula jerárquica Angular

    El componente IgniteUI para Angular Hierarchical 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 jerárquica.

    Angular Hierarchical Grid Filtering Example

    El siguiente ejemplo demuestra la experiencia de usuario de filtrado rápido de Hierarchical Grid.

    Setup

    Para especificar si el filtrado está habilitado y qué modo de filtrado se debe utilizar, la cuadrícula jerárquica 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-hierarchical-grid #grid1 [data]="data" [autoGenerate]="false" [allowFiltering]="true">
        <igx-column field="ProductName"></igx-column>
        <igx-column field="Price" [dataType]="'number'" [filterable]="false">
    </igx-hierarchical-grid>
    

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

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

    Puede habilitar tanto quickFilter / excelStyleFilter como las interfaces de usuario de filtrado avanzado en la cuadrícula jerárquica. Ambas interfaces de usuario de filtrado funcionarán de forma independiente. El resultado final filtrado en la Cuadrícula Jerárquica 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, la cuadrícula jerárquica 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 Cuadrícula jerárquica estableciendo 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-hierarchical-grid [data]="localdata" [autoGenerate]="false" [allowFiltering]="true">
        <igx-column field="Artist" [filterable]="true"></igx-column>
        <igx-column field="Photo" [filterable]="false">
    </igx-hierarchical-grid>
    
    Note

    Si una string de tipo de datos Date utiliza valores de tipo cadena, la cuadrícula jerárquica 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 cuadrícula jerárquica. La cuadrícula jerárquica 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.hierarchicalGrid.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 de la Cuadrícula Jerárquica.

    // 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.hierarchicalGrid.filteringExpressionsTree = gridFilteringExpressionsTree;
    
    • filterGlobal: borra todos los filtros existentes y aplica la nueva condición de filtrado a todas las columnas de la cuadrícula jerárquica.
    // Filter all cells for a value which contains `myproduct`
    this.hierarchicalGrid.filteringLogic = FilteringLogic.Or;
    this.hierarchicalGrid.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.hierarchicalGrid.clearFilter('ProductName');
    
    // Clears the filtering state from all columns
    this.hierarchicalGrid.clearFilter();
    

    Initial filtered state

    Para establecer el estado de filtrado inicial de la cuadrícula jerárquica, establezca la propiedad filteringExpressionsTree IgxHierarchicalGridComponent 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.hierarchicalGrid.filteringExpressionsTree = gridFilteringExpressionsTree;
        this.cdr.detectChanges();
    }
    

    Filtering logic

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

    import { FilteringLogic } from 'igniteui-angular';
    // import { FilteringLogic } from '@infragistics/igniteui-angular'; for licensed package
    ...
    
    this.hierarchicalGrid.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.

    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]
            ];
        }
    }
    
    <!-- hierarchical-grid-custom-filtering.component.html -->
    
    <igx-hierarchical-grid [data]="localdata" [autoGenerate]="false" [allowFiltering]="true">
        <igx-column field="Artist" [filterable]='true' [filters]="caseSensitiveFilteringOperand"></igx-column>
        <igx-column field="HasGrammyAward" [filterable]='true' [dataType]="'boolean'" [filters]="booleanFilteringOperand">
            <ng-template igxCell let-cell="cell" let-val>
                <img *ngIf="val" src="https://es.infragistics.com/angular-demos/assets/images/grid/active.png" title="True" alt="True" />
                <img *ngIf="!val" src="https://es.infragistics.com/angular-demos/assets/images/grid/expired.png" title="False" alt="False" />
            </ng-template>
        </igx-column>
    </igx-hierarchical-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.

    API References

    Additional Resources

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