Column Definitions

This section describes how to create columns in the component's HTML definition or in the TypeScript class file.

Live example

Column Definitions live example.

HTML definition

A column could be created in the HTML definition directly. Use the dike-grid-column selector just beneath the dike-grid selector.

In the following example three columns were defined using the DikeGridColumnComponent selector:

column-definitions.component.html
<dike-grid #grid="dkgGrid" id="grid-col-def" height="500px"
    [datasource]="dkgDataSource">

    <dike-grid-column
        fieldName="employeeId"
        headerText="Employee Id"
        dataType="Text"
        width="350">
    </dike-grid-column>
    
    <dike-grid-column
        fieldName="firstName"
        headerText="Name"
        dataType="Text"
        width="150">
    </dike-grid-column>
    
    <dike-grid-column
        fieldName="lastName"
        headerText="Surname"
        dataType="Text"
        width="150">
    </dike-grid-column>

</dike-grid>

As it was mentioned in the Quick Start Tutorial, the minimum number of properties to define a column are fieldName, headerText and dataType.

For a complete list of column properties, see the DikeGridColumnComponent definition.

TypeScript code definition

It is also possible to define a column in the TypeScript's component file.

DikeGrid Column API

In order to define a column in the TypeScript's component file, you must grab the corresponding column API of type DikeGridColumnDef from the DikeGridComponent instance you are defining columns.

There are two ways of grabbing this instance:

Querying the DikeGridComponent from the View

Every DikeGridComponent instance has its own DikeGridColumnDef instance. The instance is exposed as a public property called columnDef.

See the DikeGridComponent definition for a complete list of properties.

The following code snippet shows how the DikeGridComponent is retrieved and then, how Gender and Age columns are added using the column API.

<dike-grid #grid="dkgGrid" id="grid-col-def" height="500px"
    gridElevation
    striped
    [datasource]="dkgDataSource">

    <dike-grid-column
        fieldName="employeeId"
        headerText="Employee Id"
        dataType="Text"
        width="350"
        sortable>
    </dike-grid-column>

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

    <dike-grid-column
        fieldName="lastName"
        headerText="Surname"
        dataType="Text"
        width="150">
    </dike-grid-column>

</dike-grid>

Mixed Column Definition. Notice how three columns are defined in the HTML and the others are defined in code.

Retrieving the DikeGridColumnDef instance

The DikeGridColumnDef instance could be retrieved listening to the event called gridColumnDefInstance from the DikeGridComponent.

<dike-grid #grid="dkgGrid" id="grid-col-def" height="500px"
    gridElevation
    striped
    (gridColumnDefInstance)="onColumnDefInstance($event)"
    [datasource]="dkgDataSource">

    <dike-grid-column
        fieldName="employeeId"
        headerText="Employee Id"
        dataType="Text"
        width="350"
        sortable>
    </dike-grid-column>

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

    <dike-grid-column
        fieldName="lastName"
        headerText="Surname"
        dataType="Text"
        width="150">
    </dike-grid-column>

</dike-grid>

As you can see in the previous code snippet, the gridColumnDefInstance is attached to the onColumnDefInstance() method. In the method definition, two more columns were added: Email and Hire Date.

The gridColumnDefInstance event is emitted after the ngOnInit() lifecycle hook of the DikeGridComponent component.

The following screenshot shows the output after adding the columns:

By default, columns show a context menu. You can suppress this context menu for a specific column, all columns in a DikeGrid definition, or all DikeGrid instances.

See the Column Context Menu section for details.

Columns Order

Every column definition has an order property. If this property is not specified, the order of the columns depends on at which moment the columns are defined.

The following table shows the execution order the column definitions take place:

Column Definition

gridColumnDefInstance event listener

As it was told, this event is emitted after the ngOnInit() lifecycle hook of the DikeGridComponent component.

HTML definition

These columns are added in the ngAfterContentInit() lifecycle hook of the DikeGridComponent component.

DikeGridComponent instance queried from the view.

These columns are added in the ngAfterViewInit() lifecycle hook of the component that has the DikeGridComponent definition.

In every Column Definition execution, the columns are added in the order they are defined unless the order property is set.

Specifying the order of the columns

Let's say we want the following order:

  1. Employee Id

  2. Surname

  3. Name

  4. Gender

  5. Age

  6. Email

  7. Hire Date

After setting the order property, the output will be the following:

Column types

Th DikeGrid Library defines four column types through a union type called DikeColumnDataType.

Depending on which type the column is, there is a default alignment used to display the content of the rows.

DikeColumnDataType
Inner Type / Default alignment
Class Definition

Text

It holds data of type string. Default alignment start.

Instance of type DikeTextColumnDef.

Numeric

It holds data of type number. Default alignment end.

Instance of type DikeNumericColumnDef.

Date

It hold data of type string, number, Date. Default alignment center.

Instance of type DikeDateColumnDef.

Binary

It holds data of type string, number, boolean. Default alignment center.

Instance of type DikeBinaryColumnDef.

Content alignment comes from a union type called ColumnAlignment. This alignment could be set overwriting the default value.

When a column is defined via templating, the type must be provided through the dataType input property. If the column is defined in code, the corresponding class instance must be created.

Retrieving and Updating a field value

By default, every column defines functions for getting or setting its field value. For instance, consider a Numeric column, its default getter function is:

getValue: GetterFn<T, number> = (entry: T): number => {
  return ((entry as { [key in keyof T]: T[key] })[this.fieldName]) as number;
};

And its default setter function is:

setValue: SetterFn<T, number> = (entry: T, value: number): void => {
  (entry as { [key in keyof T]: T[key] })[this.fieldName] = value;
 };

These functions are of type GetterFn<T, R> and SetterFn<T, R> respectively. These default functions treat the received object of type T as a simple object, which means an object without any nested object.

Let's define the getter function for the Employee interface to retrieve the sales for March month.

// Define the March Sales column:
const marchSales = new DikeNumericColumnDef<Employee>('marchSales', 'March Sales');
marchSales.width = 150;
marchSales.getValue = (entry: Employee): number => entry.sales.monthlySales['March'];

The result of adding the column March Sales is shown in the following image:

As you can see, the marchSales field was defined but it does not exist. There is no marchSales field in the Employee interface, the value is in a nested object. Therefore, it is mandatory to define the getter function that retrieves the desired value.

If the column were editable, the corresponding setter function looks like the following:

marchSales.setValue = (entry: Employee, value: number): void => {
    entry.sales.monthlySales['March'] = value;
};

Templates for displaying field values

Every column has a default template for displaying its field value. This template depends on the column type because depending on the type the corresponding Angular Pipe is applied.

Text and Binary columns

<!-- Template definition for Text columns -->
<ng-template #dikeTextDisplay let-entry="rowEntry" let-value="fieldValue">
  <p>{{ value }}</p>
</ng-template>

<!-- Template definition for Binary columns -->
<ng-template #dikeBinaryDisplay let-entry="rowEntry" let-value="fieldValue">
  <p>{{ value }}</p>
</ng-template>

As you can see, for Text and Binary columns no Angular Pipes are applied.

Numeric and Date columns

<!-- Template definition for Numeric columns -->
<ng-template #dikeNumericDisplay let-entry="rowEntry" let-value="fieldValue">
  <p>{{ value | number }}</p>
</ng-template>

<!-- Template definition for Date columns -->
<ng-template #dikeDateDisplay let-entry="rowEntry" let-value="fieldValue">
  <p>{{ value | date:'shortDate' }}</p>
</ng-template>

To see more on Angular pipes visit the official docs.

Custom templates

You can define your own templates. If you notice when defining a template you always have available the row entry and the field value. Let's define custom templates for Surname, Name, Gender, Hire Date, and March Sales.

Surname and Name templates

The uppercase Angular Pipe for Surname and Name column templates was added. These templates are bound in the HTML definition.

column-definitions.component.html
<dike-grid-column
    fieldName="firstName"
    headerText="Name"
    dataType="Text"
    width="150"
    order="2"
    [displayTemplate]="firstName">

    <ng-template #firstName let-value="fieldValue">
        <p>{{ value | uppercase }}</p>
    </ng-template>
</dike-grid-column>

<dike-grid-column
    fieldName="lastName"
    headerText="Surname"
    dataType="Text"
    width="150"
    order="1"
    [displayTemplate]="lastName">

    <ng-template #lastName let-value="fieldValue">
        <p>{{ value | uppercase }}</p>
    </ng-template>
</dike-grid-column>

Both templates are assigned to the input property called displayTemplate.

Gender template

See the following code snippet for the Gender column template definition:

<!-- Gender column template is defined outside the dike-grid selector -->
<ng-template #gender let-value="fieldValue">
    <mat-icon [matTooltip]="value">{{ value }}</mat-icon>
</ng-template>

As you can see the Gender column template is retrieved querying the component's view. Remember that queried elements are set before the ngAfterViewInit life cycle hook, and the Gender column is defined in the ngAfterViewInit life cycle hook, the Gender column template is assigned to its corresponding column property.

Hire Date and March Sales column templates

In the following code snippet is shown the column templates definitions:

<!-- Column templates are defined outside the dike-grid selector -->
<ng-template #hireDate let-value="fieldValue">
    <p>{{ value | date:'fullDate' }}</p>
</ng-template>

<ng-template #marchSales let-value="fieldValue">
    <p>{{ value | currency }}</p>
</ng-template>

For Hire Date and March Sales column templates, the date and currency Angular Pipes are used respectively.

For these columns, an Observable is assigned to displayTemplate column property because both columns are defined in the gridColumnDefInstance event callback. Column templates will be available until the ngAfterViewInit hook and, remember that the gridColumnDefInstance event is emitted just after the DikeGridComponent's ngOnInit hook.

The following screenshot shows the output after defining the custom templates.

Column Identifiers

All column identifiers are UUIDs and are used internally. If the user assigns them when defining columns, these are ignored.

The column identifiers are columnId, slotId and belongToGroup properties.

Summary

In this section, the main building blocks were covered. Columns are the main part for displaying data through a DikeGrid instance.

Complete code for this section

<dike-grid #grid="dkgGrid" id="grid-col-def" height="500px"
    gridElevation
    striped
    (gridColumnDefInstance)="onColumnDefInstance($event)"
    [datasource]="dkgDataSource">

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

    <dike-grid-column
        fieldName="firstName"
        headerText="Name"
        dataType="Text"
        width="150"
        order="2"
        [displayTemplate]="firstName">

        <ng-template #firstName let-value="fieldValue">
            <p>{{ value | uppercase }}</p>
        </ng-template>
    </dike-grid-column>

    <dike-grid-column
        fieldName="lastName"
        headerText="Surname"
        dataType="Text"
        width="150"
        order="1"
        [displayTemplate]="lastName">

        <ng-template #lastName let-value="fieldValue">
            <p>{{ value | uppercase }}</p>
        </ng-template>
    </dike-grid-column>

</dike-grid>

<ng-template #gender let-value="fieldValue">
    <mat-icon [matTooltip]="value">{{ value }}</mat-icon>
</ng-template>

<ng-template #hireDate let-value="fieldValue">
    <p>{{ value | date:'fullDate' }}</p>
</ng-template>

<ng-template #marchSales let-value="fieldValue">
    <p>{{ value | currency }}</p>
</ng-template>

Last updated