You can not change the allowEdition property at runtime.
Edition mode
The allowEdition property internally prepares the DikeGrid to support row edition, but you can only set this property at the creation phase.
The edition mode toggles the DikeGrid UI to show the necessary elements to execute edition operations. Therefore, you must provide an input property named editionMode.
Once you have enabled the edition mode, you will see an icon (three vertical dots) at the left of every row. When you click on this icon, it will show a contextual menu with the edition operations.
Edition actions
Once you have allowed the edition operations and toggled the DikeGrid to the edition mode, you can take a row to the edition state, make some changes to its fields and then cancel the edition or save the changes. Of course, you can also delete the row.
Before exploring the edition actions, consider the following column configuration:
We have defined all columns as editable except for EmployeeId, Gender, and Email columns.
You can not make a column group editable.
Row Status
When the DikeGrid wraps the provided entries, it assigns to the row a creation timestamp, and a status equals to Read value.
The DikeGrid changes the row status and the timestamp every time an edition operation occurs.
The row status values are:
Editing a row
You can double-click on a row to change it to the edition state or click on the Edit option from the row context menu.
After changing a row to the edition state, the DikeGrid instance shows the default column templates for editing. It also displays an icon (a pencil) indicating editing that row.
See the Edition Templates section to customize the column templates for editing.
Saving changes
After you have made the changes you needed, you can save those changes by pressing the ENTER key or clicking on the Save option from the row context menu.
Be aware that the DikeGrid will save the edited row if it is not pristine and is valid. Therefore, the DikeGrid will save the row if you have changed it.
Let us add a simple validator to the Name column to see validation in action.
We have just made the Name column required. If you do not provide a value for the Name field, the DikeGrid will show a red bar at the left of the Name field.
When you click on the red bar, the DikeGrid will show you the error message coming from the validator.
We have added a basic validator but very common. You can add more validators to a column, even your custom validators. See the Edition validation section for more details.
After updating the row, the DikeGrid changes the row status to the Modified value.
Canceling edition
You can cancel the row edition at any time by pressing the ESC key or clicking on the Cancel option from the row context menu.
If you have made changes, you will lose those changes by canceling the row edition.
Deleting a row
You can remove a row by clicking on the Delete option from the row context menu.
You can not delete a row if the row is in edition state.
After deleting a row, the DikeGrid changes the row status to the Deleted value.
Edition triggers
We named edition triggers those actions that help you interact with the DikeGrid rows in edition state.
There is one edition trigger per edition action except for deletion. Edition triggers work over a single row. We have seen every edition trigger in the previous sections. See the following table:
You can disable these edition triggers by providing the related Injection Tokens or at the grid level.
Disabling triggers at the grid level
You must provide a false value to the corresponding flag through the input property named gridEditionSettings.
The gridEditionSettings property is of type DikeGridEditionSettings. You must provide the corresponding flag related to edition triggers.
Let us disable the ENTER key corresponding to the Save action.
onEditRow(): void {// Take all rows that are not being edited from filtered rows:constfilteredRows=this.dikeGrid.filter.getFilteredRows().filter(row =>!row.isEditing);// You can only have one row in edition state:if (filteredRows.length>0&&this.dikeGrid.edition.rowsInEdition.length===0) {// Take the first row and change it to the edition mode:this.dikeGrid.edition.editRow(filteredRows[0]); }}onEmailEditable(): void {// Get the Email column:constemailColumn=this.dikeGrid.columnDef.findColumn(column =>column.fieldName ==='email');// The column exist and is a data column:if (!!emailColumn &&isDikeDataColumnDef(emailColumn)) {// Toggle the editable value: this.dikeGrid.columnDef.setColumnEditable(emailColumn, !emailColumn.editable, { editionSettings: { required: true } });
}}onUpdateRow(): void {// Take the row in edition and update it:if (this.dikeGrid.edition.rowsInEdition.length===1) {// The DikeGrid intance will not update the given row if the row is pristine and not valid:this.dikeGrid.edition.updateRow(this.dikeGrid.edition.rowsInEdition[0]); }}onRestoreRowModified(): void {// Take the row from the modified rows set:if (this.dikeGrid.edition.modifiedRows.length===1) {// Restore the row to its immediate previous state:this.dikeGrid.edition.restoreRow(this.dikeGrid.edition.modifiedRows[0]); }}onCancelRowEdition(): void {// Take the row that it is being edited:if (this.dikeGrid.edition.rowsInEdition.length===1) {this.dikeGrid.edition.cancelRowEdition(this.dikeGrid.edition.rowsInEdition[0]); }}onRemoveRow(): void {// Take all rows that are not being edited from filtered rows:constfilteredRows=this.dikeGrid.filter.getFilteredRows().filter(row =>!row.isEditing);// You can only have one row in edition state:if (filteredRows.length>0) {// Remove the first row from the final set:this.dikeGrid.edition.removeRow(filteredRows[0]); }}onRestoreRowDeleted(): void {// Take the row from the deleted rows set:if (this.dikeGrid.edition.removedRows.length>0) {// Restore the row to its immediate previous state:this.dikeGrid.edition.restoreRow(this.dikeGrid.edition.removedRows[0]); }}onRowsInEdition(): void {console.log('Rows in edition: ',this.dikeGrid.edition.rowsInEdition);}onModifiedRows(): void {console.log('Modified rows: ',this.dikeGrid.edition.modifiedRows);}onRemovedRows(): void {console.log('Removed rows: ',this.dikeGrid.edition.removedRows);}
The previous definition generates the following output:
You can only have one row in edition state, and we have enabled the In-line filters.
We describe every button in the following list.
Email - editable. Click on this button to make the Email column editable or not editable. It toggles the current editable value, and it is marked as required.
editRow - filtered. It changes one row from filtered set to edition state. It will be disabled if there are no filtered rows.
updateRow. It saves the changes of the row in edition mode.
restoreRow - modified. It reverts changes from a modified row. You can revert all the changes you have made.
cancelRowEdition. It cancels the edition of the row in edition state.
removeRow- filtered. It takes a row from the filtered set and removes it.
restoreRow - deleted. It restores a row from the deleted rows set.
Rows in edition. It prints the row in edition mode.
Modified rows. It prints all the rows that have been modified.
Removed rows. It prints all the rows that have been deleted.
Edition events
When performing the edition actions, the DikeGrid instance emits the corresponding events.
Please, open your dev console to see the output of these events.
You can also listen to these events from the DikeGridEdition instance.
Summary
You allow the edition by providing a property named allowEdition. Then, to let the user toggle to the edition mode, provide a property called editioMode. Finally, you define a column as editable to modify the column value.
In this section, we have explored how to edit one row at a time using the UI or the API.
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { Subscription } from'rxjs';import { DikeFilterable, DikeGridComponent, DikeGridDataRowEntry, DikeGridDataSourceInput, DikeGridEditionSettings, isDikeDataColumnDef} 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-edition', templateUrl:'./row-edition.component.html', styleUrls: ['./row-edition.component.scss'], encapsulation:ViewEncapsulation.None, changeDetection:ChangeDetectionStrategy.OnPush})exportclassRowEditionComponentimplementsOnInit,OnDestroy {// Retrieve the DikeGridComponent<T> instance from the view: @ViewChild('grid') dikeGrid:DikeGridComponent<Employee>; dkgDataSource:DikeGridDataSourceInput<Employee>; gridProperties:DikeGridProperties; editionSettings:DikeGridEditionSettings<Employee>; isFiltered:boolean;private changeGridPropertiesSubscription:Subscription=Subscription.EMPTY;constructor(private cdr:ChangeDetectorRef,private gridConfig:DikeGridConfig,private sampleData:SampleData) {this.isFiltered =false; }ngOnInit():void {// Get 1000 entries from the REST API:this.dkgDataSource =this.sampleData.getEmployees(1000);// Listening to any config property change:this.setChangeGridPropertiesSubscription();// Disable the ENTER edition trigger:this.editionSettings = { rowEditionEnterkey:false }; }ngOnDestroy():void {this.changeGridPropertiesSubscription.unsubscribe(); }onEditRow():void {// Take all rows that are not being edited from filtered rows:constfilteredRows=this.dikeGrid.filter.getFilteredRows().filter(row =>!row.isEditing);// You can only have one row in edition state:if (filteredRows.length>0&&this.dikeGrid.edition.rowsInEdition.length===0) {// Take the first row and change it to the edition mode:this.dikeGrid.edition.editRow(filteredRows[0]); } }onEmailEditable():void {// Get the Email column:constemailColumn=this.dikeGrid.columnDef.findColumn(column =>column.fieldName ==='email');// The column exist and is a data column:if (!!emailColumn &&isDikeDataColumnDef(emailColumn)) {// Toggle the editable value: this.dikeGrid.columnDef.setColumnEditable(emailColumn, !emailColumn.editable, { editionSettings: { required: true } });
} }onUpdateRow():void {// Take the row in edition and update it:if (this.dikeGrid.edition.rowsInEdition.length===1) {// The DikeGrid intance will not update the given row if the row is pristine and not valid:this.dikeGrid.edition.updateRow(this.dikeGrid.edition.rowsInEdition[0]); } }onRestoreRowModified():void {// Take the row from the modified rows set:if (this.dikeGrid.edition.modifiedRows.length===1) {// Restore the row to its immediate previous state:this.dikeGrid.edition.restoreRow(this.dikeGrid.edition.modifiedRows[0]); } }onCancelRowEdition():void {// Take the row that it is being edited:if (this.dikeGrid.edition.rowsInEdition.length===1) {this.dikeGrid.edition.cancelRowEdition(this.dikeGrid.edition.rowsInEdition[0]); } }onRemoveRow():void {// Take all rows that are not being edited from filtered rows:constfilteredRows=this.dikeGrid.filter.getFilteredRows().filter(row =>!row.isEditing);// You can only have one row in edition state:if (filteredRows.length>0) {// Remove the first row from the final set:this.dikeGrid.edition.removeRow(filteredRows[0]); } }onRestoreRowDeleted():void {// Take the row from the deleted rows set:if (this.dikeGrid.edition.removedRows.length>0) {// Restore the row to its immediate previous state:this.dikeGrid.edition.restoreRow(this.dikeGrid.edition.removedRows[0]); } }onRowsInEdition():void {console.log('Rows in edition: ',this.dikeGrid.edition.rowsInEdition); }onModifiedRows():void {console.log('Modified rows: ',this.dikeGrid.edition.modifiedRows); }onRemovedRows():void {console.log('Removed rows: ',this.dikeGrid.edition.removedRows); }onEditionRowChange(value:DikeGridDataRowEntry<Employee>):void {console.log('editionRowChange: ', value); }onUpdateRowChange(value:DikeGridDataRowEntry<Employee> |DikeGridDataRowEntry<Employee>[]):void {console.log('updateRowChange: ', value); }onCancelRowEditionChange(value:DikeGridDataRowEntry<Employee> |DikeGridDataRowEntry<Employee>[]):void {console.log('cancelRowEditionChange: ', value); }onRemoveRowChange(value:DikeGridDataRowEntry<Employee> |DikeGridDataRowEntry<Employee>[]):void {console.log('removeRowChangeChange: ', value); }onRestoreRowChange(value:DikeGridDataRowEntry<Employee> |DikeGridDataRowEntry<Employee>[]):void {console.log('restoreRowChange: ', value); }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; }privatesetChangeGridPropertiesSubscription():void {this.changeGridPropertiesSubscription.unsubscribe();this.changeGridPropertiesSubscription =this.gridConfig.configChange.subscribe((props:DikeGridProperties) => {this.gridProperties = props;this.cdr.markForCheck(); }); }}