Column Sizing

After setting the initial column size, this section describes how to change the column width dynamically.

Live example

Column Sizing live example.

Column width

When you define a column, this column will have an initial value for the width property.

If width property is not defined, the default value will be 200. The with's unit is pixels.

Changing the column width through the UI

Minimum and Maximum column width

If you want to change the width of a column, you must provide the minWidth and maxWidth properties.

If you do not provide the minWidth and maxWidth properties, they will take the value of the width property.

If you want the user to change the column width through the UI, mark the column as resizable.

To see these properties in action, consider the following initial configuration:

<dike-grid id="grid-col-sizing" height="500px"
    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    [verticalRowLines]="gridProperties.verticalRowLines"
    
    (gridColumnDefInstance)="onColumnDefInstance($event)"
    [datasource]="dkgDataSource">

    <dike-grid-column
        fieldName="employeeId"
        headerText="Employee Id"
        dataType="Text"
        order="0">
    </dike-grid-column>

    <dike-grid-column
        fieldName="firstName"
        headerText="Name"
        dataType="Text"
        width="150"
        order="2"
        resizable>
    </dike-grid-column>

    <dike-grid-column
        fieldName="lastName"
        headerText="Surname"
        dataType="Text"
        width="150"
        minWidth="50"
        maxWidth="300"
        order="1"
        resizable>
    </dike-grid-column>

</dike-grid>

With the initial configuration, we have the following:

  1. The Employee Id column does not define its width nor its resizable property.

  2. You can change the Surname column width through the UI because the configuration sets the resizable property and the minWidth and maxWidth properties have a different value of width property.

  3. The Name column is resizable, and the minWidth and maxWidth properties will take the same value as the width property because this configuration does not set their values. Therefore, you will not be able to change the Name column width.

  4. Finally, for the Email column, only the width property is set.

As you can see in the following gif, you can only change the Surname column width but not for the Name column.

When a column is resizable, the cursor changes to col-resize, and when you start resizing it, the DikeGrid draws a vertical line. The color of the line will be the accent color.

Changing the width through the vertical row lines

If the vertical lines per row are visible, you can resize a column using them.

Let us make the vertical lines per row visible. First, open the Floating Configuration Panel, then check the Vertical Row Lines checkbox from the Appearance group.

In the following gif, you can see how dragging a vertical line changes the size of the column.

Remember, columns displayed in the left or center panel have their gutter-line at their right. See the Grid Structure - Gutters section.

Columns in the right panel

Columns displayed in the right panel have their gutter-line at their left. Therefore, these columns change their size in an inverse direction compared to columns displayed in the left or center panel.

When you resize a column in the right panel to increase its width, you must move its gutter-line to the left.

If you want to decrease the column width, move the gutter-line to the right.

Let us create two more columns in the right panel, Hire Date and Age columns.

<dike-grid id="grid-col-sizing" height="500px"
    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    [verticalRowLines]="gridProperties.verticalRowLines"

    (gridColumnDefInstance)="onColumnDefInstance($event)"
    [datasource]="dkgDataSource">
    
    <dike-grid-column
        fieldName="hireDate"
        headerText="Hire Date"
        dataType="Date"
        minWidth="50"
        maxWidth="300"
        order="1"
        resizable
        panel="rightPanel">
    </dike-grid-column>

</dike-grid>

Dragging the panel division line

When you drag the line that divides two adjacent panels, all columns resize evenly. The resizing operation finishes until all columns reach their minimum or maximum width.

The same occurs for columns displayed in the left panel.

You can change the width of the panel division line when the panel is being resized by providing an Injection Token called DIVISION_PANEL_LINE_WIDTH_RESIZING. By default, the width is 5 pixels in width.

DikeGrid Column API

You can change the size properties using the API from the DikeGridColumnDefservice instance.

In the Column Definition section, see how to grab the DikeGridColumnDef instance from the corresponding DikeGridComponent.

Employee Id column

Since the Employee Id column is not resizable and its width property is not defined, let us add the UI controls and the corresponding code to change its width using the DikeGrid API.

column-sizing.component.html
<div class="p-4 leading-6 text-secondary"><strong>Employee Id</strong></div>
<form [formGroup]="columnSizingForm"
    class="flex flex-col p-4 overflow-hidden">
    <div class="flex flex-row flex-wrap items-center">
        <mat-form-field class="flex-auto pr-3">
            <mat-label>Width</mat-label>
            <input matInput
                type="number"
                formControlName="width">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('width') as widthControl">
                <div *ngIf="widthControl.errors?.['required']">Required</div>
                <div *ngIf="widthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="widthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <mat-form-field class="flex-auto pr-3">
            <mat-label>Min width</mat-label>
            <input matInput
                type="number"
                formControlName="minWidth">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('minWidth') as minWidthControl">
                <div *ngIf="minWidthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="minWidthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <mat-form-field class="flex-auto pr-3">
            <mat-label>Max width</mat-label>
            <input matInput
                type="number"
                formControlName="maxWidth">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('maxWidth') as maxWidthControl">
                <div *ngIf="maxWidthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="maxWidthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <div class="flex-auto flex flex-row justify-around items-center">
            <button mat-raised-button
                class="w-32"
                color="primary"
                [disabled]="!columnSizingForm.valid"
                (click)="onChangeColumnSize()">Apply
            </button>
            <mat-checkbox class="w-24"
                formControlName="resizable"
                (change)="onResizableChange($event)">Resizable
            </mat-checkbox>
        </div>
    </div>
</form>

The previous form is added above the dike-grid selector generating the following output:

Now, you can change the Employee Id column's width, min-width, and max-width. If you click on the checkbox next to the Apply button, you can mark the Employee Id column as resizable.

Changing the width using the API

Consider the following code:

<div class="flex-auto flex flex-row justify-around items-center">
    <button mat-raised-button
        class="w-32"
        color="primary"
        [disabled]="!columnSizingForm.valid"
        (click)="onChangeColumnSize()">Apply
    </button>
    <mat-checkbox class="w-24"
        formControlName="resizable"
        (change)="onResizableChange($event)">Resizable
    </mat-checkbox>
</div>

Once the input elements pass the validators, the button can invoke the callback method. Inside the callback definition:

  1. Firstly, you must find the column to be modified.

  2. Notice how the found column instance is narrowing to a reference of type DikeDataColumnDef, due to the findColumn() method returns a reference of type DikeColumnDef.

  3. The code uses the changeColumnWidth() method to pass the column instance and the size properties, where only the width is mandatory.

Internally, the DikeGridComponent validates the width, minWidth, and maxWidth arguments. For instance, if minWidth is greater than the width, the width value is assigned to minWidth.

Despite the resizable property for the Employee Id column is not set, the size properties of the column can be changed using the API.

Setting the resizable property

Remember that the resizable property allows the user to change the width of a column or column group.

The following code snippet is the callback attached to the checkbox change Event.

column-sizing.component.ts
onResizableChange(value: MatCheckboxChange): void {
  // Search the employeeId column:
  const targetColumn = this.columnDef.findColumn(column => column.fieldName === 'employeeId');

  if (!!targetColumn) {
    // If the column is found, change its resizable property:
    this.columnDef.setColumnResizable(targetColumn, value.checked);
  }
}

Once again, the target column must be found, in this case. The method setColumnResizable() marks the Employee Id column as resizable.

The previous output shows how the Employee Id column is resized after setting it as resizable. We must have changed the minWidth, or maxWidth properties as well.

Even though a column is marked as resizable, if the minWidth and maxWidth properties have the same value as the width property, the column will not resize using the UI.

Column Sizing Event

If you notice, the last output reports the changes in the width property of the Employee Id column when this one is being resized.

The DikeGridComponent emits an Event called columnSizeChange. This event is emitted every time a data column changes its size.

The DikeGridColumnDefservice also emits the columnSizeChange event.

<dike-grid id="grid-col-sizing" height="500px"
    (columnSizeChange)="onColumnSizeChange($event)">
</dike-grid>

Since the columnSizeChange event sends any column that has changed in width, the if statement gives us the Employee Id column.

Resizing Groups

By definition, a column group's width equals the sum of its child columns' width. Therefore, a column group does not have a width property.

All descendant columns, marked as resizable, will change in width when resizing a group.

The columnSizeChange event does not send the group itself nor the descendant groups. Instead, it only sends the descendant data columns.

Let us define the following configuration:

  1. Firstly, We have a primary group named Personal Info.

  2. Under the Personal Info group, we have the Complete Name column group, the Gender and Age columns.

  3. Finally, we have Name and Surname columns under the Complete Name group.

  4. Except for the Complete Name group, all columns and column groups are resizable.

column-sizing.component.ts
<dike-grid id="grid-col-sizing" height="500px">
    <dike-grid-column
        fieldName="personalInfoGroup"
        headerText="Personal Info"
        order="0"
        resizable>
    
        <dike-grid-column
            fieldName="completeNameGroup"
            headerText="Complete Name">
    
            <dike-grid-column
                fieldName="firstName"
                headerText="Name"
                dataType="Text"
                width="150"
                minWidth="50"
                maxWidth="300"
                resizable>
            </dike-grid-column>
    
            <dike-grid-column
                fieldName="lastName"
                headerText="Surname"
                dataType="Text"
                width="150"
                minWidth="50"
                maxWidth="300"
                resizable>
            </dike-grid-column>
        </dike-grid-column>
    
        <dike-grid-column
            fieldName="gender"
            headerText="Gender"
            dataType="Binary"
            width="110"
            minWidth="50"
            maxWidth="200"
            resizable>
        </dike-grid-column>
    
        <dike-grid-column
            fieldName="age"
            headerText="Age"
            dataType="Numeric"
            contentAlign="center"
            width="85"
            minWidth="50"
            maxWidth="120"
            resizable>
        </dike-grid-column>
    </dike-grid-column>
</dike-grid>

Column groups marked as resizable can change in width only from the UI.

As you can see in the previous output:

  1. When resizing the Personal Info group, the operation draws a vertical line with an accent color until the columns.

  2. The resize process draws the line only into the column's boundary for the Surname column.

Remember, for resizing a column or a group, you must grab the gutter-line for the column. See the Grid Structure - Gutters section for more details.

Summary

Once you define a column at the creation phase, you can change its width at execution time, either from the UI or the API. Columns that are resizing through the UI must be resizable.

The DikeGrid instance only sends the changed data columns when the resizing operation occurs, not column groups.

Complete code for this section

<div class="p-4 leading-6 text-secondary"><strong>Employee Id</strong></div>
<form [formGroup]="columnSizingForm"
    class="flex flex-col p-4 overflow-hidden">
    <div class="flex flex-row flex-wrap items-center">
        <mat-form-field class="flex-auto pr-3">
            <mat-label>Width</mat-label>
            <input matInput
                type="number"
                formControlName="width">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('width') as widthControl">
                <div *ngIf="widthControl.errors?.['required']">Required</div>
                <div *ngIf="widthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="widthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <mat-form-field class="flex-auto pr-3">
            <mat-label>Min width</mat-label>
            <input matInput
                type="number"
                formControlName="minWidth">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('minWidth') as minWidthControl">
                <div *ngIf="minWidthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="minWidthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <mat-form-field class="flex-auto pr-3">
            <mat-label>Max width</mat-label>
            <input matInput
                type="number"
                formControlName="maxWidth">

            <mat-hint align="end">Numeric value</mat-hint>
            <mat-error *ngIf="getControl('maxWidth') as maxWidthControl">
                <div *ngIf="maxWidthControl.errors?.['min']">Min value 25</div>
                <div *ngIf="maxWidthControl.errors?.['max']">Max value 600</div>
            </mat-error>
        </mat-form-field>

        <div class="flex-auto flex flex-row justify-around items-center">
            <button mat-raised-button
                class="w-32"
                color="primary"
                [disabled]="!columnSizingForm.valid"
                (click)="onChangeColumnSize()">Apply
            </button>
            <mat-checkbox class="w-24"
                formControlName="resizable"
                (change)="onResizableChange($event)">Resizable
            </mat-checkbox>
        </div>
    </div>
</form>

<dike-grid id="grid-col-sizing" height="500px"
    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    [verticalRowLines]="gridProperties.verticalRowLines"

    (gridColumnDefInstance)="onColumnDefInstance($event)"
    (columnSizeChange)="onColumnSizeChange($event)"
    [datasource]="dkgDataSource">

    <dike-grid-column
        fieldName="employeeId"
        headerText="Employee Id"
        dataType="Text"
        order="0">
    </dike-grid-column>

    <dike-grid-column
        fieldName="firstName"
        headerText="Name"
        dataType="Text"
        width="150"
        order="2"
        resizable>
    </dike-grid-column>

    <dike-grid-column
        fieldName="lastName"
        headerText="Surname"
        dataType="Text"
        width="150"
        minWidth="50"
        maxWidth="300"
        order="1"
        resizable>
    </dike-grid-column>

    <dike-grid-column
        fieldName="personalInfoGroup"
        headerText="Personal Info"
        order="0"
        resizable>

        <dike-grid-column
            fieldName="completeNameGroup"
            headerText="Complete Name">

            <dike-grid-column
                fieldName="firstName"
                headerText="Name"
                dataType="Text"
                width="150"
                minWidth="50"
                maxWidth="300"
                resizable>
            </dike-grid-column>

            <dike-grid-column
                fieldName="lastName"
                headerText="Surname"
                dataType="Text"
                width="150"
                minWidth="50"
                maxWidth="300"
                resizable>
            </dike-grid-column>
        </dike-grid-column>

        <dike-grid-column
            fieldName="gender"
            headerText="Gender"
            dataType="Binary"
            width="110"
            minWidth="50"
            maxWidth="200"
            resizable>
        </dike-grid-column>

        <dike-grid-column
            fieldName="age"
            headerText="Age"
            dataType="Numeric"
            contentAlign="center"
            width="85"
            minWidth="50"
            maxWidth="120"
            resizable>
        </dike-grid-column>
    </dike-grid-column>

    <dike-grid-column
        fieldName="hireDate"
        headerText="Hire Date"
        dataType="Date"
        minWidth="50"
        maxWidth="300"
        order="1"
        resizable
        panel="rightPanel">
    </dike-grid-column>
</dike-grid>

Last updated