This example demonstrates how to implement the following scenarios in DataGrid:
- Hide the Home Address form item if the AddressRequired value is false.
- Disable the LastName item editor if the FirstName form item value is empty.
Implementation Details
- Define the setCellValue callback function for the "AddressRequired" and "FirstName" columns to re-render items after an editor value is changed.
- Handle the customizeItem form event.
- In the event handler, call the getRowIndexByKey and cellValue methods to obtain current editor values. Assign the value obtained from the cellValue method to the item's visible property.
- In the onEditorPreparing function, change the disabled option of the required form item editor.
Files to Review
- jQuery
- Angular
- Vue
- React
- ASP.NET Core
Documentation
More Examples
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
HTML<dx-data-grid
(onEditorPreparing)="onEditorPreparing($event)"
(onInitNewRow)="onInitNewRow($event)"
[dataSource]="dataSource"
keyExpr="ID"
[showBorders]="true">
<dxo-paging [enabled]="false"></dxo-paging>
<dxo-editing
mode="popup"
[allowAdding]="true"
[allowUpdating]="true">
<dxo-popup
title="Employee Info"
[showTitle]="true"
[width]="700"
[height]="725">
</dxo-popup>
<dxo-form [customizeItem]="customizeItem">
<dxi-item
itemType="group"
[colCount]="2"
[colSpan]="2">
<dxi-item dataField="FirstName"></dxi-item>
<dxi-item dataField="LastName"></dxi-item>
<dxi-item dataField="Prefix"></dxi-item>
<dxi-item dataField="BirthDate"></dxi-item>
<dxi-item dataField="Position"></dxi-item>
<dxi-item dataField="HireDate"></dxi-item>
<dxi-item
dataField="Notes"
editorType="dxTextArea"
[colSpan]="2"
[editorOptions]="notesEditorProperties">
</dxi-item>
<dxi-item dataField="HireDate"></dxi-item>
</dxi-item>
<dxi-item
dataField="AddressRequired"
[colSpan]="2">
</dxi-item>
<dxi-item
itemType="group"
caption="Home Address"
[colCount]="2"
[colSpan]="2">
<dxi-item dataField="StateID"></dxi-item>
<dxi-item dataField="Address"></dxi-item>
</dxi-item>
</dxo-form>
</dxo-editing>
<dxi-column
dataField="Prefix"
caption="Title"
[width]="70">
</dxi-column>
<dxi-column
dataField="FirstName"
[setCellValue]="setCellValue">
</dxi-column>
<dxi-column dataField="LastName"></dxi-column>
<dxi-column
dataField="BirthDate"
dataType="date">
</dxi-column>
<dxi-column
dataField="Position"
[width]="170">
</dxi-column>
<dxi-column
dataField="HireDate"
dataType="date">
</dxi-column>
<dxi-column
dataField="StateID"
caption="State"
[width]="125">
<dxo-lookup
[dataSource]="states"
displayExpr="Name"
valueExpr="ID">
</dxo-lookup>
</dxi-column>
<dxi-column
dataField="Address"
[visible]="false">
</dxi-column>
<dxi-column
dataField="Notes"
[visible]="false">
</dxi-column>
<dxi-column
dataField="AddressRequired"
[setCellValue]="setCellValue"
[visible]="false">
</dxi-column>
</dx-data-grid>
TypeScriptimport { Component, ViewChild } from '@angular/core';
import { DxDataGridComponent } from 'devextreme-angular';
import { DataService, Employee, State } from './data.service';
import config from 'devextreme/core/config';
import dxDataGrid, {
Column,
EditorPreparingEvent,
InitNewRowEvent,
} from 'devextreme/ui/data_grid';
import { Item, GroupItem } from 'devextreme/ui/form';
import { Properties as TextAreaProperties } from 'devextreme/ui/text_area';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
providers: [DataService],
styleUrls: ['./app.component.css'],
})
export class AppComponent {
@ViewChild(DxDataGridComponent) dataGrid!: DxDataGridComponent;
dataSource: Employee[];
states: State[];
notesEditorProperties: TextAreaProperties;
constructor(service: DataService) {
config({
editorStylingMode: 'filled',
});
this.dataSource = service.getEmployees();
this.states = service.getStates();
this.notesEditorProperties = { height: 100 };
}
isHomeAddressGroup(item: GroupItem): boolean {
return item && item.itemType === 'group' && item.caption === 'Home Address';
}
customizeItem = (item: Item) => {
if (this.isHomeAddressGroup(item)) {
const gridInstance: dxDataGrid<Employee, number> = this.dataGrid.instance;
const editing = gridInstance.option('editing');
const rowIndex = gridInstance.getRowIndexByKey(editing?.editRowKey!);
item.visible = gridInstance.cellValue(rowIndex, 'AddressRequired');
}
};
onEditorPreparing(e: EditorPreparingEvent<Employee, number>) {
if (e.dataField === 'LastName' && e.parentType === 'dataRow') {
e.editorOptions.disabled = e.row?.data?.FirstName === '';
}
}
onInitNewRow(e: InitNewRowEvent<Employee, number>) {
e.data.AddressRequired = false;
e.data.FirstName = '';
}
setCellValue(
this: Column,
newData: Employee,
value: number,
currentRowData: Employee
) {
this.defaultSetCellValue!(newData, value, currentRowData);
}
}
Code<script setup lang="ts">
import { ref } from "vue";
import "devextreme/dist/css/dx.material.blue.light.compact.css";
import {
DxDataGrid,
DxColumn,
DxPaging,
DxEditing,
DxPopup,
DxLookup,
DxForm
} from "devextreme-vue/data-grid";
import { DxItem } from "devextreme-vue/form";
import "devextreme-vue/text-area";
import config from 'devextreme/core/config';
import service from '../data';
import type dxDataGrid from 'devextreme/ui/data_grid';
import type {
Column,
EditorPreparingEvent,
InitNewRowEvent,
} from 'devextreme/ui/data_grid';
import type { Item, GroupItem } from 'devextreme/ui/form';
import type { Properties as TextAreaProperties } from 'devextreme/ui/text_area';
import type { Employee } from '../data';
config({
editorStylingMode: 'filled',
});
const dataSource = service.getEmployees();
const states = service.getStates();
function isHomeAddressGroup(item: GroupItem): boolean {
return item && item.itemType === 'group' && item.caption === 'Home Address';
}
const notesEditorProperties: TextAreaProperties = { height: 100 };
const dataGridRef = ref<DxDataGrid>();
function customizeItem(item: Item){
if (isHomeAddressGroup(item)) {
const gridInstance = dataGridRef.value?.instance! as dxDataGrid<Employee, number>;
const editing = gridInstance.option('editing');
const rowIndex = gridInstance.getRowIndexByKey(editing?.editRowKey!);
item.visible = gridInstance.cellValue(rowIndex, 'AddressRequired');
}
};
function onEditorPreparing(e: EditorPreparingEvent<Employee, number>) {
if (e.dataField === 'LastName' && e.parentType === 'dataRow') {
e.editorOptions.disabled = e.row?.data?.FirstName === '';
}
}
function onInitNewRow(e: InitNewRowEvent<Employee, number>) {
e.data.AddressRequired = false;
e.data.FirstName = '';
}
function setCellValue(
this: Column,
newData: Employee,
value: number,
currentRowData: Employee
) {
this.defaultSetCellValue!(newData, value, currentRowData);
}
</script>
<template>
<div>
<DxDataGrid :data-source="dataSource" ref="dataGridRef" :show-borders="true" @editor-preparing="onEditorPreparing"
@init-new-row="onInitNewRow" key-expr="ID">
<DxPaging :enabled="false" />
<DxEditing :allow-updating="true" :allow-adding="true" mode="popup">
<DxPopup :show-title="true" :width="700" :height="725" title="Employee Info">
</DxPopup>
<DxForm :customize-item="customizeItem">
<DxItem :col-count="2" :col-span="2" item-type="group">
<DxItem data-field="FirstName" />
<DxItem data-field="LastName" />
<DxItem data-field="Prefix" />
<DxItem data-field="BirthDate" />
<DxItem data-field="Position" />
<DxItem data-field="HireDate" />
<DxItem :col-span="2" :editor-options="notesEditorProperties" data-field="Notes" editor-type="dxTextArea" />
</DxItem>
<DxItem data-field="AddressRequired" :col-span="2" />
<DxItem :col-count="2" :col-span="2" item-type="group" caption="Home Address">
<DxItem data-field="StateID" />
<DxItem data-field="Address" />
</DxItem>
</DxForm>
</DxEditing>
<DxColumn :width="70" data-field="Prefix" caption="Title" />
<DxColumn :set-cell-value="setCellValue" data-field="FirstName" />
<DxColumn data-field="LastName" />
<DxColumn data-field="BirthDate" data-type="date" />
<DxColumn :width="170" data-field="Position" />
<DxColumn data-field="HireDate" data-type="date" />
<DxColumn :width="125" data-field="StateID" caption="State">
<DxLookup :data-source="states" value-expr="ID" display-expr="Name" />
</DxColumn>
<DxColumn :visible="false" :set-cell-value="setCellValue" data-field="AddressRequired" />
<DxColumn :visible="false" data-field="Address" />
<DxColumn :visible="false" data-field="Notes" />
</DxDataGrid>
</div>
</template>