DkGrid
  • Overview
  • Getting Started
    • Quick Start Tutorial
  • Fundamentals
    • Grid Structure
      • Grid Size
      • Header
      • Row Filter
      • Rows
      • Panels
      • Gutters
      • Edition Toolbar
      • Paginator
      • Borders
      • Column Context Menu
      • Waiting Indicator
    • DataSource
      • In-Memory DataSource
      • Custom DataSource
    • Theming
  • Columns
    • Column Definitions
    • Column Grouping
    • Column Sizing
    • Column Moving
    • Column Pinning
  • Rows
    • Row Sorting
    • Row Selection
    • Row Grouping
    • Row Pagination
  • Filtering
    • Column Filters
    • Filter types
    • In-line Filters
  • Editing
    • Row Edition
    • Edition templates
    • Edition validation
    • Multiple rows edition
  • Reference
    • DkGrid API
      • DkGridColumnDef
      • DkGridSorting
      • DkGridSelection
      • DkGridRowGrouping
      • DkGridPagination
      • DkGridWaitingIndicator
      • DkGridFactoryDataSource
      • DkGridFilter
      • DkGridEdition
    • Components
      • DkGridComponent
      • DkGridColumnComponent
    • Classes
      • DataSource
      • Columns
      • Rows
      • Filtering
      • Editing
    • Interfaces
      • Columns
      • Sorting
      • Row Grouping
      • Filtering
      • Editing
    • Injection Tokens
      • Grid Structure
      • Filtering
      • Editing
      • Theming
    • Type aliases
      • DataSource
      • Columns
      • Selection
      • Filtering
      • Editing
    • Type Guards
Powered by GitBook
On this page
  • Live example
  • Allowing the selection operation
  • Selectable rows
  • Header Checkbox Selection
  • Group Selection
  • DikeGrid Selection API
  • Selection events
  • Summary
  • Complete code for this section
  1. Rows

Row Selection

The user can select one or all rows from the data source. This section describes how you can configure this feature.

PreviousRow SortingNextRow Grouping

Last updated 2 years ago

Live example

live example.

Allowing the selection operation

To allow the user to select/deselect the DikeGrid rows, you must provide an input property named allowSelection. This property is at the grid scope.

row-selection.component.html
<dike-grid id="grid-row-selection" height="700px" #grid="dkgGrid"
    [allowSelection]="gridProperties.allowSelection">
</dike-grid>

You can change the value of the allowSelection property at runtime.

Open the for the live example and click on the Allow Selection checkbox.

Once you have enabled selection, you will see a checkbox column displayed for every row. To select/deselect a row, click on the related checkbox.

Selectable rows

By default, when you enable selection for the DikeGrid, all rows are susceptible to being selected.

If you want the user can select only some rows, you can provide a function specifying the conditions the rows must meet. You can set this function by providing a property named selectableRows.

Let us define this function to allow the user to select rows whose age value is not 27.

<dike-grid id="grid-row-selection" height="700px" #grid="dkgGrid"
    [selectableRows]="selectableRowsDefinition">
</dike-grid>
selectableRowsDefinition(entry: Employee): boolean {
    // Allow selection only for those rows whose age value is different of 27:
    return entry.age !== 27;
}

You can change this function definition at runtime. Therefore, the DikeGrid instance will evaluate the currently selected rows, deselecting those rows that do not meet the new criteria.

As you can see, rows that do not meet the defined criteria display their checkbox disabled.

Header Checkbox Selection

When you provide an in-memory data set, the DikeGrid instance always shows a checkbox in its header.

On the other hand, the DikeGrid instance will not show a checkbox in its header when you provide a custom Datasource because the DikeGrid does not know the total length of the provided data set.

By default, the checkbox in the header will select all rows even though the data set is filtered. However, if you want to select only the filtered rows, you can use the selection API.

Group Selection

When you group rows by a column, every group will show its checkbox.

  1. The selectable rows under the group will be selected when you click on the checkbox in the group. If the group has non-selectable rows, its state will be indeterminate.

  2. When you click in any of the rows under the group, the checkbox in the group will update its status to indeterminate and become checked until you select all rows.

The checkbox in the header will update its state as well.

We have enabled row grouping in the live demo to see this feature.

row-selection.component.html
<dike-grid id="grid-row-selection" height="700px" #grid="dkgGrid"
    allowRowGrouping
    allowRowFiltering
    allowColumnDragging>
    
    <dike-grid-column
        fieldName="gender"
        headerText="Gender"
        dataType="Binary"
        width="130"
        draggable
        groupable>
    </dike-grid-column>

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

As you can see, apart from allowing row grouping, we have enabled column dragging. Then, we set Gender and Age columns being groupable.

You can move the Age column to the group panel with the previous configuration. Thus, you can select any group or a row under any group.

DikeGrid Selection API

You can also use the selection API to select rows.

Before using the selection API, you must retrieve the related DikeGrid instance by querying the component's view.

<dike-grid id="grid-row-selection" height="700px" #grid="dkgGrid">
</dike-grid>
@Component({
  selector: 'row-selection',
  templateUrl: './row-selection.component.html',
  styleUrls: ['./row-selection.component.scss'],

  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class RowSelectionComponent implements OnInit, OnDestroy {
  // Retrieve the DikeGridComponent<T> instance from the view:
  @ViewChild('grid') dikeGrid: DikeGridComponent<Employee>;
  // ...
}

The selection API has the following methods:

Method
Description

selectOne()

  1. It marks the given row as selected.

  2. The given row must pass the selectable function.

  3. This method emits the selectionChange and selectedRowChange events.

select()

  1. It marks the given rows as selected.

  2. It emits the selectionChange event.

deselectOne()

  1. It turns off the selected flag for the given row.

  2. This method emits the selectionChange and deselectedRowChange events.

deselect()

  1. It turns off the selected flag for the given rows.

  2. This method emits the selectionChange event.

getSelectedRows()

This method returns an array of all selected rows.

getSelectedEntries()

It returns all selected entries.

selectAll()

This method will set all rows coming from the data source as selected.

deselectAll()

It turns off the selection flag of all selected rows.

resetSelection()

This method deselects all selected rows and cleanses some internal variables. The DikeGrid instance will invoke this method every time you provide a new data set.

To use any previous methods, you must have allowed selection by providing the input property named allowSelection.

Remember, when you provide a data source, the DikeGrid instance wraps every entry into an object of type DikeGridRowEntry. See the class hierarchy for the DikeGrid rows.

To see the selection API in action, we have created the following UI:

<div class="mt-2 flex flex-row flex-wrap items-center justify-around">
    <div class="flex-none w-56 flex flex-col m-2 items-center">
        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            [disabled]="!isFiltered"
            (click)="onSelectOne()">selectOne / filtered
        </button>

        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            [disabled]="!isFiltered"
            (click)="onSelect()">select / filtered
        </button>
    </div>

    <div class="flex-none w-56 flex flex-col m-2 items-center">
        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            [disabled]="!isFiltered"
            (click)="onDeselectOne()">deselectOne / filtered
        </button>

        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            [disabled]="!isFiltered"
            (click)="onDeselect()">deselect / filtered
        </button>
    </div>

    <div class="flex-none w-56 flex flex-col m-2 items-center">
        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            (click)="onGetSelectedRows()">getSelectedRows
        </button>

        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            (click)="onGetSelectedEntries()">getSelectedEntries
        </button>
    </div>

    <div class="flex-none w-56 flex flex-col m-2 items-center">
        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            (click)="onSelectAll()">selectAll
        </button>

        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            (click)="onDeselectAll()">deselectAll
        </button>
    </div>
</div>

<dike-grid id="grid-row-selection" height="700px" #grid="dkgGrid">
</dike-grid>
onSelectOne(): void {
  const filteredRows = this.dikeGrid.filter.getFilteredRows();

  if (filteredRows.length > 0) {
    this.dikeGrid.selection.selectOne(filteredRows[0]);
  }
}

onSelect(): void {
  const filteredRows = this.dikeGrid.filter.getFilteredRows();

  if (filteredRows.length > 0) {
    this.dikeGrid.selection.select(filteredRows);
  }
}

onDeselectOne(): void {
  const selectedFromFiltered = this.dikeGrid.filter.getFilteredRows().filter(row => row.selected);

  if (selectedFromFiltered.length > 0) {
    this.dikeGrid.selection.deselectOne(selectedFromFiltered[0]);
  }
}

onDeselect(): void {
  const filteredRows = this.dikeGrid.filter.getFilteredRows();

  if (filteredRows.length > 0) {
    this.dikeGrid.selection.deselect(filteredRows);
  }
}

onGetSelectedRows(): void {
  console.log('Selected rows: ', this.dikeGrid.selection.getSelectedRows());
}

onGetSelectedEntries(): void {
  console.log('Selected entries: ', this.dikeGrid.selection.getSelectedEntries());
}

onSelectAll(): void {
  this.dikeGrid.selection.selectAll();
}

onDeselectAll(): void {
  this.dikeGrid.selection.deselectAll();
}

The previous HTML code generates the following output:

For every button, we have attached the following actions:

  1. Buttons selectOne / filtered, select / filtered, deselectOne / filtered and deselect / filtered work over the filtered set. These buttons are enabled if you have filtered the original set.

  2. To allow filtering, we enabled the DikeGrid Row Filter.

  3. The selectAll and deselectAll buttons are self-explanatory.

  4. We printed out the selected rows and selected entries in the dev console.

Please, open the live demo and see the previous buttons in action.

To evaluate if the DikeGrid instance has a filter applied, we listen to the filterChange and columnsChange events.

<dike-grid id="grid-row-selection" height="700px" #grid="dkgGrid"
    (columnsChange)="onColumnsChange($event)"
    (filterChange)="onFilterChange($event)">
</dike-grid>
onFilterChange(filterable: DikeFilterable<Employee>): void {
  // We ignore the argument filterable because we are only interested in the action.
  this.isFiltered = !!this.dikeGrid ? this.dikeGrid.filter.isFilterApplied() : false;
}

onColumnsChange(columns: DikeColumnDef[]): void {
  // We ignore the argument columns because we are only interested in the action.
  this.isFiltered = !!this.dikeGrid ? this.dikeGrid.filter.isFilterApplied() : false;
}
  1. The filterChange event fires every time the user types something in the DikeGrid Row Filter.

  2. We listen to the columnsChange event because every time the user groups the rows by a column, the user must move that column to the group panel, provoking the DikeGrid instance to raise the columnsChange event.

Remember that the DikeGrid ignores filters for the columns in the group panel.

Selection events

Every time we select or deselect one or more rows, the DikeGrid instance emits the related event.

The following are the selection events:

Event
Description

selectedRowChange

It emits when the user selects one row.

deselectRowChange

It emits when the user deselects one row.

selectionChange

It emits when the user selects/deselects one or more rows.

We listen to these three events:

<dike-grid id="grid-row-selection" height="700px" #grid="dkgGrid"
    (selectedRowChange)="onSelectedRowChange($event)"
    (deselectedRowChange)="onDeselectedRowChange($event)"
    (selectionChange)="onSelectionChange($event)">
</dike-grid>
onSelectedRowChange(row: DikeGridDataRowEntry<Employee>): void {
  console.log('Select one row change: ', row);
}

onDeselectedRowChange(row: DikeGridDataRowEntry<Employee>): void {
  console.log('Deselect one row change: ', row);
}

onSelectionChange(rows: DikeGridDataRowEntry<Employee>[]): void {
  console.log('Selection change: ', rows);
}

Please, open the dev console to see the output of these events.

Summary

To perform the selection operation, you must allow it by providing an input property named allowSelection. By default, the user can select all rows, but you can enable only some rows for selection by providing a custom function where every row must meet the established criteria. You can select or deselect rows through the UI or the selection API.

Complete code for this section

<div class="mt-2 flex flex-row flex-wrap items-center justify-around">
    <div class="flex-none w-56 flex flex-col m-2 items-center">
        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            [disabled]="!isFiltered"
            (click)="onSelectOne()">selectOne / filtered
        </button>

        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            [disabled]="!isFiltered"
            (click)="onSelect()">select / filtered
        </button>
    </div>

    <div class="flex-none w-56 flex flex-col m-2 items-center">
        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            [disabled]="!isFiltered"
            (click)="onDeselectOne()">deselectOne / filtered
        </button>

        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            [disabled]="!isFiltered"
            (click)="onDeselect()">deselect / filtered
        </button>
    </div>

    <div class="flex-none w-56 flex flex-col m-2 items-center">
        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            (click)="onGetSelectedRows()">getSelectedRows
        </button>

        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            (click)="onGetSelectedEntries()">getSelectedEntries
        </button>
    </div>

    <div class="flex-none w-56 flex flex-col m-2 items-center">
        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            (click)="onSelectAll()">selectAll
        </button>

        <button mat-raised-button
            class="flex-none w-56 my-2"
            color="primary"
            (click)="onDeselectAll()">deselectAll
        </button>
    </div>
</div>

<dike-grid id="grid-row-selection" height="700px" #grid="dkgGrid"
    [displayRowId]="gridProperties.displayRowId"
    [gridElevation]="gridProperties.matElevation"
    [gridElevationValue]="gridProperties.elevationValue"
    [striped]="gridProperties.stripeRows"
    [verticalRowLines]="gridProperties.verticalRowLines"

    (columnsChange)="onColumnsChange($event)"
    (filterChange)="onFilterChange($event)"
    (selectedRowChange)="onSelectedRowChange($event)"
    (deselectedRowChange)="onDeselectedRowChange($event)"
    (selectionChange)="onSelectionChange($event)"
    [selectableRows]="selectableRowsDefinition"

    allowRowGrouping
    allowRowFiltering
    allowColumnDragging
    [allowSelection]="gridProperties.allowSelection"
    [datasource]="dkgDataSource">

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

    <dike-grid-column
        fieldName="country"
        headerText="Country"
        dataType="Text"
        width="250">
    </dike-grid-column>

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

        <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-column>

    <dike-grid-column
        fieldName="gender"
        headerText="Gender"
        dataType="Binary"
        width="130"
        draggable
        groupable>
    </dike-grid-column>

    <dike-grid-column
        fieldName="age"
        headerText="Age"
        dataType="Numeric"
        contentAlign="center"
        width="100"
        draggable
        groupable>
    </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"
        width="150">
    </dike-grid-column>

</dike-grid>
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';

import { Subscription } from 'rxjs';

import { DikeGridComponent, DikeGridDataRowEntry, 
  DikeGridDataSourceInput, DikeFilterable, DikeColumnDef 
} from '@dikesoft/angular-data-grid';
import { DikeGridProperties } from 'app/core/config/dike-grid.properties';
import { Employee } from 'app/mock-api/common/employees/data.model';

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

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

  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class RowSelectionComponent implements OnInit, OnDestroy {
  // Retrieve the DikeGridComponent<T> instance from the view:
  @ViewChild('grid') dikeGrid: DikeGridComponent<Employee>;

  dkgDataSource: DikeGridDataSourceInput<Employee>;
  gridProperties: DikeGridProperties;

  isFiltered: boolean;

  private changeGridPropertiesSubscription: Subscription = Subscription.EMPTY;

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

    this.isFiltered = false;
  }

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

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

  selectableRowsDefinition(entry: Employee): boolean {
    // Allow selection only for those rows whose age value is different of 27:
    return entry.age !== 27;
  }

  onSelectOne(): void {
    const filteredRows = this.dikeGrid.filter.getFilteredRows();

    if (filteredRows.length > 0) {
      this.dikeGrid.selection.selectOne(filteredRows[0]);
    }
  }

  onSelect(): void {
    const filteredRows = this.dikeGrid.filter.getFilteredRows();

    if (filteredRows.length > 0) {
      this.dikeGrid.selection.select(filteredRows);
    }
  }

  onDeselectOne(): void {
    const selectedFromFiltered = this.dikeGrid.filter.getFilteredRows().filter(row => row.selected);

    if (selectedFromFiltered.length > 0) {
      this.dikeGrid.selection.deselectOne(selectedFromFiltered[0]);
    }
  }

  onDeselect(): void {
    const filteredRows = this.dikeGrid.filter.getFilteredRows();

    if (filteredRows.length > 0) {
      this.dikeGrid.selection.deselect(filteredRows);
    }
  }

  onGetSelectedRows(): void {
    console.log('Selected rows: ', this.dikeGrid.selection.getSelectedRows());
  }

  onGetSelectedEntries(): void {
    console.log('Selected entries: ', this.dikeGrid.selection.getSelectedEntries());
  }

  onSelectAll(): void {
    this.dikeGrid.selection.selectAll();
  }

  onDeselectAll(): void {
    this.dikeGrid.selection.deselectAll();
  }

  onFilterChange(filterable: DikeFilterable<Employee>): void {
    // We ignore the argument filterable because we are only interested in the action.
    this.isFiltered = !!this.dikeGrid ? this.dikeGrid.filter.isFilterApplied() : false;
  }

  onColumnsChange(columns: DikeColumnDef[]): void {
    // We ignore the argument columns because we are only interested in the action.
    this.isFiltered = !!this.dikeGrid ? this.dikeGrid.filter.isFilterApplied() : false;
  }

  onSelectedRowChange(row: DikeGridDataRowEntry<Employee>): void {
    console.log('Select one row change: ', row);
  }

  onDeselectedRowChange(row: DikeGridDataRowEntry<Employee>): void {
    console.log('Deselect one row change: ', row);
  }

  onSelectionChange(rows: DikeGridDataRowEntry<Employee>[]): void {
    console.log('Selection change: ', rows);
  }

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

The selectableRows property is of type , and you can also provide this function using the selection API.

See the section for further details about an in-memory data set and a custom Datasource.

For further details, see the definition.

You can also listen to these events from the instance.

Datasource
Row Selection
SelectableFn
DikeGridSelection
DikeGridSelection
Floating Configuration Panel
Floating Configuration Panel - Selection
Enabling Row Selection
Defining the selectableRows function
Group Selection
Row Selection using the API