Descripción general del componente Angular Query Builder

    Angular Query Builder es parte de nuestros componentes Angular y proporciona una interfaz de usuario completa que permite a los desarrolladores crear consultas de filtrado de datos complejas para un conjunto de datos específico. Con este componente, pueden crear un árbol de expresiones y establecer condiciones AND/OR entre ellas con editores y listas de condiciones determinadas por el tipo de datos de cada campo. El árbol de expresiones se puede transformar fácilmente en una consulta en el formato que admita el backend.

    The IgxQueryBuilderComponent component provides a way to build complex queries through the UI. By specifying AND/OR operators, conditions and values the user creates an expression tree which describes the query.

    Angular Query Builder Example

    Hemos creado este ejemplo de Angular Query Builder para mostrarle las funcionalidades predeterminadas del componente Angular Query Builder. Haga clic en el botón más para agregar condiciones, el grupo "y" y el grupo "o". La agrupación o desagrupación de expresiones, así como el reordenamiento, se pueden lograr a través de la funcionalidad de arrastrar y soltar.

    Getting Started with Ignite UI for Angular Query Builder

    Para empezar a utilizar el componente Ignite UI for Angular Query Builder, primero debe instalar Ignite UI for Angular. En una aplicación Angular existente, escriba el siguiente comando:

    ng add igniteui-angular
    

    Para obtener una introducción completa al Ignite UI for Angular, lea el tema de introducción.

    El siguiente paso es importar elIgxQueryBuilderModule archivo en el app.module.ts.

    // app.module.ts
    
    import { IgxQueryBuilderModule } from 'igniteui-angular';
    // import { IgxQueryBuilderModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [..., IgxQueryBuilderModule],
        ...
    })
    export class AppModule {}
    

    Alternativamente,16.0.0 puedes importarlosIgxQueryBuilderComponent como una dependencia independiente, o usar elIGX_QUERY_BUILDER_DIRECTIVES token para importar el componente y todos sus componentes y directivas de soporte.

    // home.component.ts
    
    import { IGX_QUERY_BUILDER_DIRECTIVES, FilteringExpressionsTree, FieldType } from 'igniteui-angular';
    // import { IGX_QUERY_BUILDER_DIRECTIVES, FilteringExpressionsTree, FieldType } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({
        selector: 'app-home',
        template: `
        <igx-query-builder #queryBuilder
            [entities]="entities"
            [(expressionTree)]="expressionTree"
            (expressionTreeChange)="onExpressionTreeChange()">
        </igx-query-builder>
        `,
        styleUrls: ['home.component.scss'],
        standalone: true,
        imports: [IGX_QUERY_BUILDER_DIRECTIVES]
        /* or imports: [IgxQueryBuilderComponent] */
    })
    export class HomeComponent {
        public expressionTree: FilteringExpressionsTree;
        public entities: Array<any>;
    
        public onExpressionTreeChange() {
            ...
        }
    }
    

    Now that you have the Ignite UI for Angular Query Builder module or directives imported, you can start using the igx-query-builder component.

    Using the Angular Query Builder

    Si no se establece inicialmente ningún árbol de expresión, comience eligiendo una entidad y cuáles de sus campos debe devolver la consulta. Después de eso, se pueden agregar condiciones o subgrupos.

    In order to add a condition you select a field, an operand based on the field data type and a value if the operand is not unary. The operands In and Not In will allow you to create an inner query with conditions for a different entity instead of simply providing a value. Once the condition is committed, a chip with the condition information appears. By clicking or hovering the chip, you have the options to modify it or add another condition or group right after it.

    Clicking on the (AND or OR) button placed above each group, will open a menu with options to change the group type or ungroup the conditions inside.

    Since every condition is related to a specific field from a particular entity changing the entity will lead to resetting all preset conditions and groups. When selecting a new entity a confirmation dialog will be shown, unless the showEntityChangeDialog input property is set to false.

    You can start using the component by setting the entities property to an array describing the entity name and an array of its fields, where each field is defined by its name and data type. Once a field is selected it will automatically assign the corresponding operands based on the data type. The Query Builder has the expressionTree input property. You could use it to set an initial state of the control and access the user-specified filtering logic.

    ngAfterViewInit(): void {
        const innerTree = new FilteringExpressionsTree(FilteringLogic.And, undefined, 'Companies', ['ID']);
        innerTree.filteringOperands.push({
            fieldName: 'Employees',
            condition: IgxNumberFilteringOperand.instance().condition('greaterThan'),
            conditionName: 'greaterThan',
            searchVal: 100
        });
        innerTree.filteringOperands.push({
            fieldName: 'Contact',
            condition: IgxBooleanFilteringOperand.instance().condition('true'),
            conditionName: 'true'
        });
    
        const tree = new FilteringExpressionsTree(FilteringLogic.And, undefined, 'Orders', ['*']);
        tree.filteringOperands.push({
            fieldName: 'CompanyID',
            condition: IgxStringFilteringOperand.instance().condition('inQuery'),
            conditionName: 'inQuery',
            searchTree: innerTree
        });
        tree.filteringOperands.push({
            fieldName: 'OrderDate',
            condition: IgxDateFilteringOperand.instance().condition('before'),
            conditionName: 'before',
            searchVal: new Date('2024-01-01T00:00:00.000Z')
        });
        tree.filteringOperands.push({
            fieldName: 'ShippedDate',
            condition: IgxDateFilteringOperand.instance().condition('null'),
            conditionName: 'null'
        });
    
        this.queryBuilder.expressionTree = tree;
    }
    

    The expressionTree is a two-way bindable property which means a corresponding expressionTreeChange output is implemented that emits when the end-user changes the UI by creating, editing or removing conditions. It can also be subscribed separately to receive notifications and react to such changes.

    <igx-query-builder #queryBuilder
        [entities]="entities"
        [(expressionTree)]="expressionTree"
        (expressionTreeChange)="onExpressionTreeChange()">
    </igx-query-builder>
    

    Expressions Dragging

    Los chips de condición se pueden reposicionar fácilmente utilizando los enfoques de reordenamiento de arrastrar y soltar del mouse o del teclado. Con ellos, los usuarios pueden ajustar su lógica de consulta de forma dinámica.

    • Arrastrar una ficha no modifica su condición/contenido, solo su posición.
    • El chip también se puede arrastrar a lo largo de grupos y subgrupos. Por ejemplo, la agrupación/desagrupación de expresiones se logra a través de la funcionalidad de arrastre de expresiones. Para agrupar las condiciones ya existentes, primero debe agregar un nuevo grupo a través del botón 'agregar' grupo. Luego, mediante el arrastre, las expresiones requeridas se pueden mover a ese grupo. Para desagrupar, puede arrastrar todas las condiciones fuera de su grupo actual y una vez que se elimine la última condición, el grupo se eliminará.
    Note

    Las fichas de un árbol de consulta no se pueden arrastrar en otro, por ejemplo, del padre al interno y viceversa.

    Keyboard interaction

    Combinaciones de teclas

    • Tab / Shift + Tab- navega al chip siguiente/anterior, indicador de arrastre, botón de eliminación, botón de expresión 'agregar'.
    • Arrow Down / Arrow Up- Cuando el indicador de arrastre del chip está enfocado, el chip se puede mover hacia arriba / abajo.
    • Space / Enter- La expresión enfocada entra en el modo de edición. Si se ha movido la ficha, esto confirma su nueva posición.
    • Esc- El reordenamiento de Chip se cancela y vuelve a su posición original.
    Note

    El reordenamiento del teclado proporciona la misma funcionalidad que la función de arrastrar y soltar del ratón. Una vez que se mueve una ficha, el usuario debe confirmar la nueva posición o cancelar el reorden.

    Templating

    El componente Generador de consultas de Ignite UI for Angular permite definir plantillas para el encabezado del componente y el valor de búsqueda utilizando los siguientes nombres de referencia predefinidos:

    Plantilla de encabezado

    By default the IgxQueryBuilderComponent header would not be displayed. In order to define such, the IgxQueryBuilderHeaderComponent should be added inside of the igx-query-builder.

    Then, for setting the header title could be used the title input and passing content inside of the igx-query-builder-header allows templating the query builder header.

    El siguiente fragmento de código ilustra cómo hacerlo:

    <igx-query-builder #queryBuilder [entities]="this.entities">
            <igx-query-builder-header [title]="'Query Builder Template Sample'">  
            </igx-query-builder-header>
    </igx-query-builder>
    

    Search value

    The search value of a condition can be templated using the igxQueryBuilderSearchValue directive, applied to an <ng-template> inside of the igx-query-builder's body:

    <igx-query-builder #queryBuilder
        [entities]="entities"
        [expressionTree]="expressionTree">
        <ng-template #searchValueTemplate
                    igxQueryBuilderSearchValue 
                    let-searchValue
                    let-selectedField = "selectedField" 
                    let-selectedCondition = "selectedCondition"
                    let-defaultSearchValueTemplate = "defaultSearchValueTemplate">
            @if (
                selectedField?.field === 'Region' &&
                (selectedCondition === 'equals' || selectedCondition === 'doesNotEqual')
                ){
                <igx-select [placeholder]="'Select region'" [(ngModel)]="searchValue.value">
                    <igx-select-item *ngFor="let reg of regionOptions" [value]="reg">
                        {{ reg.text }}
                    </igx-select-item>
                </igx-select>
            } 
            @else if (
                selectedField?.field === 'OrderStatus' &&
                (selectedCondition === 'equals' || selectedCondition === 'doesNotEqual')
                ){
                <igx-radio-group>
                    <igx-radio class="radio-sample"
                               *ngFor="let stat of statusOptions"
                               value="{{stat.value}}"
                               [(ngModel)]="searchValue.value">
                        {{stat.text}}
                    </igx-radio>
                </igx-radio-group>
            }
                @else {  
                <ng-container #defaultTemplate *ngTemplateOutlet="defaultSearchValueTemplate"></ng-container>
            }
        </ng-template>
    </igx-query-builder>
    

    Formatter

    Para cambiar la apariencia del valor de búsqueda en el chip que se muestra cuando una condición no está en modo de edición, puede establecer una función de formateador en la matriz de campos. El valor de búsqueda y la condición seleccionada se pueden acceder a través de los argumentos value y rowData de la siguiente manera:

    this.ordersFields = [
        { field: "CompanyID", dataType: "string" },
        { field: "OrderID", dataType: "number" },
        { field: "EmployeeId", dataType: "number" },
        { field: "OrderDate", dataType: "date" },
        { field: "RequiredDate", dataType: "date" },
        { field: "ShippedDate", dataType: "date" },
        { field: "ShipVia", dataType: "number" },
        { field: "Freight", dataType: "number" },
        { field: "ShipName", dataType: "string" },
        { field: "ShipCity", dataType: "string" },
        { field: "ShipPostalCode", dataType: "string" },
        { field: "ShipCountry", dataType: "string" },
        { field: "Region", dataType: "string", formatter: (value: any, rowData: any) => rowData === 'equals' || rowData === 'doesNotEqual' ? `${value.value}` : value }},
        { field: "OrderStatus", dataType: "number" }
    ];
    

    Demo

    Hemos creado este ejemplo de Angular Query Builder para mostrarle las funcionalidades de plantillas y formateador para el encabezado y el valor de búsqueda del componente Angular Query Builder.

    Estilismo

    To get started with styling the Query Builder, we need to import the index file, where all the theme functions and component mixins live:

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

    The Query Builder takes its background color from the its theme, using the background parameter. In order to change the background we need to create a custom theme:

    
    $custom-query-builder: query-builder-theme(
      $schema: $dark-material-schema,
      $background: #292826,
      ...
    );
    

    Dado que tenemos otros componentes dentro del Generador de consultas, como botones, chips, menús desplegables y entradas, necesitamos crear un tema separado para cada uno:

    $custom-button: flat-button-theme(
      $schema: $dark-material-schema,
      $foreground: #ffcd0f,
    );
    
    $custom-input-group: input-group-theme(
      $schema: $dark-material-schema,
      $focused-secondary-color: #ffcd0f
    );
    
    $custom-chip: chip-theme(
      $schema: $dark-material-schema,
      $background: #ffcd0f,
    );
    
    $custom-icon-button: outlined-icon-button-theme(
      $schema: $dark-material-schema,
      $foreground: #ffcd0f,
    );
    

    In this example we only changed some of the parameters for the listed components, but the button-theme, chip-theme, drop-down-theme, input-group-theme themes provide way more parameters to control their respective styling.

    Note

    En lugar de codificar los valores de color como acabamos de hacer, podemos lograr mayor flexibilidad en cuanto a colores usando laspalette funciones ycolor. Por favor, consulta elPalettes tema para obtener una guía detallada sobre cómo utilizarlos.

    The last step is to include the new component themes using the css-vars mixin.

    @include css-vars($custom-query-builder);
    
    :host {
      ::ng-deep {
        @include css-vars($custom-input-group);
        @include css-vars($custom-chip);
        @include css-vars($custom-icon-button);
    
        .igx-filter-tree__buttons {
          @include css-vars($custom-button);
        }
      }
    }
    
    Note

    If the component is using an Emulated ViewEncapsulation, it is necessary to penetrate this encapsulation using ::ng-deep to style the components inside the query builder component (button, chip, drop-down ...etc).

    Demo

    Note

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

    También puede optimizar el desarrollo de su aplicación Angular utilizando WYSIWYG App Builder ™ con componentes de interfaz de usuario reales.

    API References

    Additional Resources

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