Hierarchical Grid Column Reordering & Moving

    The Hierarchical Grid component in Ignite UI for Angular provides the Column Moving feature to allow columns reordering via standard drag/drop mouse or touch gestures, or by using the Column Moving API. Column moving works both with pinned and unpinned columns and with Multi-column Headers. Moving a column into the pinned area pins the column and vice versa, moving a column outside of the pinned area unpins the column.

    Note

    Reordering between columns and column groups is allowed only when they are at the same level in the hierarchy and both are in the same group. Moving is allowed between columns/column-groups, if they are top level columns.

    Note

    If a column header is templated and the Column Moving is enabled or the corresponding column is groupable, then the templated elements need to have the draggable attribute set to false! This allows to attach handlers for any event emitted by the element, otherwise the event is consumed by the igxDrag directive.

    Note

    If the pinned area exceeds its maximum allowed width (80% of the total Hierarchical Grid width), a visual clue notifies the end user that the drop operation is forbidden and pinning is not possible. This means you won't be allowed to drop a column in the pinned area.

    <ng-template igxHeader>
        <igx-icon [attr.draggable]="false" (click)="onClick()"></igx-icon>
    </ng-template>
    

    Angular Hierarchical Grid Column Moving Overview Example

    Overview

    Column moving feature is enabled on a per-grid level, meaning that the igx-hierarchical-grid could have either movable or immovable columns. This is done via the moving input of the igx-grid.

    <igx-hierarchical-grid [moving]="true">
        ...
        <igx-row-island [moving]="true"></igx-row-island>
    </igx-hierarchical-grid>
    

    API

    In addition to the drag and drop functionality, the Column Moving feature also provides two API methods to allow moving a column/reordering columns programmatically:

    moveColumn - Moves a column before or after another column (a target). The first parameter is the column to be moved, and the second parameter is the target column. Also accepts an optional third parameter position (representing a DropPosition value), which determines whether to place the column before or after the target column.

    // Move the ID column after the Name column
    const idColumn = grid.getColumnByName("ID");
    const nameColumn = grid.getColumnByName("Name");
    
    grid.moveColumn(idColumn, nameColumn, DropPosition.AfterDropTarget);
    

    move - Moves a column to a specified visible index. If the passed index parameter is invalid (is negative, or exceeds the number of columns), or if the column is not allowed to move to this index (if inside another group), no operation is performed.

    // Move the ID column at 3rd position.
    const idColumn = grid.getColumnByName("ID");
    idColumn.move(3);
    

    Note that when using the API, only the columnMovingEnd event will be emitted, if the operation was successful. Also note that in comparison to the drag and drop functionality, using the API does not require setting the moving property to true.

    Events

    There are several events related to the column moving to provide a means for tapping into the columns' drag and drop operations. These are columnMovingStart, columnMoving and columnMovingEnd. You can subscribe to the columnMovingEnd event of the igx-hierarchical-grid to implement some custom logic when a column is dropped to a new position. For example, you can cancel dropping the Category after the Change On Year(%) column.

    <igx-hierarchical-grid #hierarchicalGrid [data]="data" [autoGenerate]="false" [moving]="true" (columnMovingEnd)="onColumnMovingEnd($event)">
        <igx-column [field]="'Country'"></igx-column>
        <igx-column [field]="'Phone'" [dataType]="'number'"></igx-column>
    </igx-hierarchical-grid>
    
    public onColumnMovingEnd(event) {
        if (event.source.field === "Phone" && event.target.field === "Country") {
            event.cancel = true;
        }
    }
    

    Styling

    To get started with styling the Hierarchical Grid column moving headers, 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';
    

    Following the simplest approach, we create a new theme that extends the grid-theme and accepts the $ghost-header-background, $ghost-header-text-color and the $ghost-header-icon-color parameters.

    // Define dark theme for the column moving
    $dark-grid-column-moving-theme: grid-theme(
        $ghost-header-text-color: #F4D45C,
        $ghost-header-background: #575757,
        $ghost-header-icon-color: #f4bb5c
    );
    

    The last step is to include the component mixins with its respective theme:

    @include grid($dark-grid-column-moving-theme);
    
    Note

    Depending on the component View Encapsulation strategy, it may be necessary to penetrate this encapsulation using ::ng-deep

    :host {
        ::ng-deep {
            @include grid($dark-grid-column-moving-theme);
        }
    }
    

    Defining a color palette

    Instead of hardcoding the color values like we just did, we can achieve greater flexibility in terms of colors by using the igx-palette and igx-color functions.

    igx-palette generates a color palette based on the primary and secondary colors that are passed:

    $yellow-color: #F4D45C;
    $black-color: #575757;
    
    $dark-palette: palette($primary: $yellow-color, $secondary: $black-color);
    

    And then with igx-color we can easily retrieve color from the pallete.

    $dark-grid-column-moving-theme: grid-theme(
        $palette: $dark-palette,
        $ghost-header-text-color: color($dark-palette, "primary", 400),
        $ghost-header-background: color($dark-palette, "secondary", 200),
        $ghost-header-icon-color: color($dark-palette, "primary", 500)
    );
    
    Note

    The color and palette are powerful functions for generating and retrieving colors. Please refer to Palettes topic for detailed guidance on how to use them.

    Using Schemas

    Going further with the theming engine, you can build a robust and flexible structure that benefits from schemas. A schema is a recipe of a theme.

    Extend one of the two predefined schemas, that are provided for every component, in this case - light-grid.

    // Extending the dark grid schema
    $dark-grid-column-moving-schema: extend($_light-grid,
            (
                ghost-header-text-color:(
                   color: ("primary", 400)
                ),
                ghost-header-background:(
                   color: ("secondary", 200)
                ),
                ghost-header-icon-color:(
                   color:( "primary", 500)
                )
            )
    );
    

    In order to apply our custom schema we have to extend one of the globals (light or dark), which is basically pointing out the components with a custom schema, and after that add it to the respective component theme:

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

    Don't forget to include the theme in the same way as it was demonstrated above.

    Demo

    Note

    The sample will not be affected by the selected global theme from Change Theme.

    API References

    Additional Resources

    Our community is active and always welcoming to new ideas.