# Grid Structure

## Live example

{% hint style="success" %}
[Grid Structure](https://demos.dikesoft.com/dk-grid/grid-structure) live example.
{% endhint %}

## CSS Grid Layout

The DikeGrid uses the CSS Grid Layout specification to create its internal structure and display all the defined columns.&#x20;

As you know, the CSS Grid Layout specification uses column and row templates. That is why every part of the DikeGrid is called a row. Therefore, for instance, the Header is called the Header Row, the Content, Content Row, etc.

## Code for this section

You can read any sub-section in the order you want. However, we recommend reading all sub-sections as they appear.

The following initial configuration will increase in every sub-section.

{% tabs %}
{% tab title="grid-structure.component.html" %}

```markup
<dike-grid id="grid-structure"
    [width]="gridProperties.width"
    [height]="gridProperties.height"
    
    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    
    [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">
    </dike-grid-column>

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

{% endtab %}

{% tab title="grid-structure.component.ts" %}

```typescript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';

import { Subscription } from 'rxjs';

import { DikeGridDataSourceInput } from '@dikesoft/data-grid';

import { Employee } from 'app/mock-api/common/employees/data.model';
import { DikeGridProperties } from 'app/core/config/dike-grid.properties';

import { DikeGridConfig } from 'app/services/dike-grid.config.service';
import { SampleData } from 'app/services/sample-data.service';

@Component({
  selector: 'grid-structure',
  templateUrl: './grid-structure.component.html',
  styleUrls: ['./grid-structure.component.scss'],

  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class GridStructureComponent implements OnInit, OnDestroy {

  dkgDataSource: DikeGridDataSourceInput<Employee>;
  gridProperties: DikeGridProperties;
  
  private changeGridPropertiesSubscription: Subscription = Subscription.EMPTY;

  constructor(
    private cdr: ChangeDetectorRef,
    private gridConfig: DikeGridConfig,
    private sampleData: SampleData) { }

  ngOnInit(): void {
    this.dkgDataSource = this.sampleData.getEmployees(1000);
    // Listening to any config property change:
    this.setChangeGridPropertiesSubscription();
  }

  ngOnDestroy(): void {
    this.changeGridPropertiesSubscription.unsubscribe();
  }

  private setChangeGridPropertiesSubscription(): void {
    this.changeGridPropertiesSubscription.unsubscribe();
    this.changeGridPropertiesSubscription = this.gridConfig.configChange.subscribe((props: DikeGridProperties) => {
      this.gridProperties = props;
      this.cdr.markForCheck();
    });
  }
}
```

{% endtab %}
{% endtabs %}

### Complete code

{% tabs %}
{% tab title="structure.module.ts" %}

```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';

import { DikeDataGridModule, DIVISION_PANEL_GAP,
    DIVISION_PANEL_LINE_WIDTH, BORDER_WIDTH, BORDER_GAP,
    COLUMN_CONTEXT_MENU_WIDTH, COLUMN_CONTEXT_MENU_HEIGHT,
    LOADING_MESSAGE
} from '@dikesoft/data-grid';

import { SharedModule } from 'app/shared/shared.module';
import { structureRoutes } from 'app/modules/admin/structure/structure.routing';
import { GridStructureComponent } from 'app/modules/admin/structure/grid-structure/grid-structure.component';

@NgModule({
  declarations: [
    GridStructureComponent
  ],
  imports: [
    CommonModule,
    RouterModule.forChild(structureRoutes),

    SharedModule,
    DikeDataGridModule
  ],
  providers: [
    { provide: DIVISION_PANEL_GAP, useValue: 21},
    { provide: DIVISION_PANEL_LINE_WIDTH, useValue: 3},
    { provide: BORDER_WIDTH, useValue: 3 },
    { provide: BORDER_GAP, useValue: 35 },
    { provide: COLUMN_CONTEXT_MENU_WIDTH, useValue: 700 },
    { provide: COLUMN_CONTEXT_MENU_HEIGHT, useValue: 550 },
    { provide: LOADING_MESSAGE, useValue: 'Loading rows of data, please wait...' }
  ]
})
export class StructureModule { }

```

{% endtab %}

{% tab title="grid-structure.component.html" %}

```markup
<div class="p-4 leading-6 text-secondary"><strong>Waiting Indicator message</strong></div>
<div class="p-4 flex flex-row flex-wrap justify-around items-center">
    <mat-form-field class="flex-auto w-80 mr-5">
        <mat-label>Custom message</mat-label>
        <input matInput
            type="text"
            [formControl]="customMessage">

        <mat-hint align="end">Text value</mat-hint>
        <mat-error *ngIf="customMessage.hasError('required')">Required</mat-error>
    </mat-form-field>
    <button mat-raised-button
        class="flex-none w-32 mr-5 mb-3"
        color="primary"
        [disabled]="!customMessage.valid"
        (click)="onDisplayWaitingIndicator()">Show Indicator
    </button>
    <button mat-raised-button
        class="flex-none w-32 mr-5 mb-3"
        color="primary"
        (click)="onHideWaitingIndicator()">Hide Indicator
    </button>
</div>

<dike-grid id="grid-structure" #grid="dkgGrid"
    [width]="gridProperties.width"
    [height]="gridProperties.height"

    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    [verticalRowLines]="gridProperties.verticalRowLines"
    
    [headerRowHeight]="gridProperties.headerHeight"
    [allowColumnContextMenu]="gridProperties.columnContextMenu"

    [allowRowFiltering]="gridProperties.allowRowFilter"
    [filterRowHeight]="gridProperties.filterRowHeight"

    [contentRowHeight]="gridProperties.contentRowHeight"

    allowRowGrouping
    [rowGroupingRowHeight]="gridProperties.rowGroupingHeight"
    [rowGroupingColumnHeight]="gridProperties.rowGroupingColumnHeight"
    [displayRowGroupingIndent]="gridProperties.displayRowGroupingIndent"
    [rowGroupingIndentWidth]="gridProperties.rowGroupingIndentWidth"

    allowSelection

    allowEdition
    [editionMode]="gridProperties.editionMode"
    [editionToolbar]="gridProperties.displayEditionToolbar"
    [editionToolbarPosition]="gridProperties.editionToolbarPosition"
    [editionToolbarAlignment]="gridProperties.editionToolbarAlignment"
    [editionToolbarRowHeight]="gridProperties.editionToolbarHeight"
    [editionToolbarItemHeight]="gridProperties.edtitionToolbarItemHeight"

    [allowPagination]="gridProperties.allowPagination"
    [paginationRowHeight]="gridProperties.paginationHeight"

    [allowColumnDragging]="gridProperties.allowColumnDragging"
    [datasource]="dkgDataSource">

    <dike-grid-column
        fieldName="employeeId"
        headerText="Employee Id"
        dataType="Text"
        width="350"
        panel="leftPanel"
        displayMenu="false">
    </dike-grid-column>

    <dike-grid-column
        fieldName="completeNameGroup"
        headerText="Complete Name">
        
        <dike-grid-column
            fieldName="firstName"
            headerText="Name"
            dataType="Text">
        </dike-grid-column>
    
        <dike-grid-column
            fieldName="lastName"
            headerText="Surname"
            dataType="Text">
        </dike-grid-column>
        
    </dike-grid-column>
    
    <dike-grid-column
        fieldName="gender"
        headerText="Gender"
        dataType="Binary"
        width="110"
        groupable
        draggable
        panel="groupPanel">
    </dike-grid-column>

    <dike-grid-column
        fieldName="age"
        headerText="Age"
        dataType="Numeric"
        contentAlign="center"
        width="85"
        groupable
        draggable
        panel="groupPanel">
    </dike-grid-column>

    <dike-grid-column
        fieldName="email"
        headerText="Email"
        dataType="Text"
        width="300">
    </dike-grid-column>

    <dike-grid-column
        fieldName="hireDate"
        headerText="Hire Date"
        dataType="Date"
        panel="rightPanel">
    </dike-grid-column>
</dike-grid>
```

{% endtab %}

{% tab title="grid-structure.component.ts" %}

```typescript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';

import { Subscription } from 'rxjs';
import { delay } from 'rxjs/operators';

import { DikeGridComponent, DikeGridDataSourceInput } from '@dikesoft/data-grid';

import { Employee } from 'app/mock-api/common/employees/data.model';
import { DikeGridProperties } from 'app/core/config/dike-grid.properties';

import { DikeGridConfig } from 'app/services/dike-grid.config.service';
import { SampleData } from 'app/services/sample-data.service';

@Component({
  selector: 'grid-structure',
  templateUrl: './grid-structure.component.html',
  styleUrls: ['./grid-structure.component.scss'],

  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class GridStructureComponent implements OnInit, OnDestroy {

  // Retrieve the DikeGridComponent<T> instance from the view:
  @ViewChild('grid') dikeGrid: DikeGridComponent<Employee>;

  dkgDataSource: DikeGridDataSourceInput<Employee>;
  gridProperties: DikeGridProperties;
  customMessage: FormControl;

  private changeGridPropertiesSubscription: Subscription = Subscription.EMPTY;

  constructor(
    private cdr: ChangeDetectorRef,
    private gridConfig: DikeGridConfig,
    private sampleData: SampleData) {

    this.customMessage = new FormControl('', Validators.required);
  }

  ngOnInit(): void {
    this.dkgDataSource = this.sampleData.getEmployees(1000).pipe(delay(2000));
    // Listening to any config property change:
    this.setChangeGridPropertiesSubscription();
  }

  ngOnDestroy(): void {
    this.changeGridPropertiesSubscription.unsubscribe();
  }

  onDisplayWaitingIndicator(): void {
    this.dikeGrid.waitingIndicator.customMessageIndicator(this.customMessage.value as string);
  }

  onHideWaitingIndicator(): void {
    this.dikeGrid.waitingIndicator.hideWaitingIndicator();
  }

  private setChangeGridPropertiesSubscription(): void {
    this.changeGridPropertiesSubscription.unsubscribe();
    this.changeGridPropertiesSubscription = this.gridConfig.configChange.subscribe((props: DikeGridProperties) => {
      this.gridProperties = props;
      this.cdr.markForCheck();
    });
  }
}

```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.dikesoft.com/fundamentals/grid-structure.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
