- Home
- Forum
- Angular - EJ 2
- How do you bind a list of options for a drop down list in inline edit mode on a grid?
How do you bind a list of options for a drop down list in inline edit mode on a grid?
I've been looking at this example: https://ej2.syncfusion.com/angular/demos/#/tailwind3/grid/normal-edit
But I can't see where the list of countries that populates the ShipCountry drop down list is coming from. editparams only contains a setting for popupHeight.
How would you bind a list to the drop down? Something that looked like this for example:
[{Id: '1', Text: 'Employee 1'}, {Id: '2', Text: 'Employee 2'}, {Id: '3', Text: 'Employee 3'}]
Hi Legion,
Greetings from Syncfusion Support.
Based on your query, it appears that you are referring our sample demos of Normal editing and wanted to know how the dataSource that populates the ShipCountry drop-down list is coming to the drop-down list, since editParams only contains a setting for popupHeight.
We
would like to inform you that when the ShipCountry column is set with editType as 'dropdownedit',
it is automatically populated with a drop-down list using distinct values from
the Grid’s dataSource based on the specified
field. This dataSource binding happens automatically when the drop-down enters
the edit state. Please refer the below documentation for more information.
Documentation: https://ej2.syncfusion.com/angular/documentation/grid/editing/edit-types#default-cell-edit-type-editor
API: https://ej2.syncfusion.com/angular/documentation/api/grid/column/#edittype
In our normal editing sample demos, the editParams is only used to set the popup height. Since you asked how the data is provided to the drop-down list, we suspect that you want to use a custom dataSource. We have already discussed about how to provide custom dataSource for the drop-downlist this in our documentation which can be accessed from below link:
Documentation: https://ej2.syncfusion.com/angular/documentation/grid/editing/edit-types#provide-custom-data-source-for-dropdownlist-component
Please feel free to reach out if you need any further assistance or clarification.
Regards,
Mohanraj Rengasamy
I followed the instructions in your link for providing a custom data source for the dropdownlist component. The problem I'm having now is that I can't seem to update the employeeParams (values for the dropdowncomponent) outside of component creation. If I try to set the list of values inside of effect or inside a subscribe I get an error in the console:
ERROR TypeError: col.edit.create is not a function
at EditRender2.getEditElements (edit-renderer.js:200:28)
at EditRender2.update (edit-renderer.js:41:31)
at NormalEdit2.inlineEditHandler (normal-edit.js:222:19)
at GridComponent2.<anonymous> (normal-edit.js:147:19)
at ComponentBase2.trigger (component-base.js:387:15)
at GridComponent2.<anonymous> (normal-edit.js:145:14)
at ComponentBase2.trigger (component-base.js:387:15)
at NormalEdit2.startEdit (normal-edit.js:143:12)
at InlineEdit2.startEdit (inline-edit.js:51:32)
at Edit2.startEdit (edit.js:148:21)
It makes me think something is going wrong with scoping or binding. You'll notice I'm using fixed values, so there's no issue with fetching data.
employeeParams?: IEditCell;
constructor() {
effect(() => {
this.employeeParams = { // THROWS ERROR here inside constructor in effect()
params: {
dataSource: new DataManager([
{ Id: '1', Text: 'test1' },
{ Id: '2', Text: 'test2' },
]),
fields: { text: 'Text', value: 'Id' },
query: new Query(),
actionComplete: () => false,
},
};
});
this.employeeParams = { // WORKS here in constructor OUTSIDE of effect()
params: {
dataSource: new DataManager([
{ Id: '1', Text: 'test1' },
{ Id: '2', Text: 'test2' },
]),
fields: { text: 'Text', value: 'Id' },
query: new Query(),
actionComplete: () => false,
},
};
}
ngOnInit(): void {
this.employeeParams = { // WORKS here in OnInit
params: {
dataSource: new DataManager([
{ Id: '1', Text: 'Test1' },
{ Id: '2', Text: 'Test2' },
]),
fields: { text: 'Text', value: 'Id' },
query: new Query(),
actionComplete: () => false,
},
};
}
forkJoin({
lookupLists: this.referenceService.getLookupLists([
'Country',
'BusinessUnit',
'Employee',
]),
cascadingLookupLists: this.referenceService.getCascadingLookupLists([
'Department',
'Division',
]),
}).subscribe(({ lookupLists, cascadingLookupLists }) => {
this.employeeParams = { // THROWS ERROR here inside subscribe
params: {
dataSource: new DataManager([
{ Id: '1', Text: 'Test1' },
{ Id: '2', Text: 'Test2' },
]),
fields: { text: 'Text', value: 'Id' },
query: new Query(),
actionComplete: () => false,
},
};
});
}
Hi Legion,
The reason you're encountering the error when assigning employeeParams inside an effect() or subscribe() block is due to the timing of the assignment in relation to the Grid's lifecycle. Specifically, this approach works only when the assignment occurs before the Grid and its columns are initialized. When employeeParams is updated after the Grid has rendered, the editor configuration (edit.create) is no longer bound, which results in the error:
|
ERROR TypeError: col.edit.create is not a function |
Best Practice :
Define employeeParams before the Grid renders, typically in the ngOnInit lifecycle hook:
|
ngOnInit(): void { this.employeeParams = { params: { dataSource: new DataManager([ { Id: '1', Text: 'Test1' }, { Id: '2', Text: 'Test2' }, ]), fields: { text: 'Text', value: 'Id' }, query: new Query(), actionComplete: () => false, }, }; } |
If You Need to Update It Dynamically (e.g., via subscribe()):
Since the column editors won't rebind automatically after initial rendering, you should manually update the column editor’s data source:
|
// Simulate async update, e.g., from service.subscribe() this.updateDropdownData([ { Id: '3', Text: 'Dynamic1' }, { Id: '4', Text: 'Dynamic2' }, ]);
// Helper method to update the dropdown editor after init updateDropdownData(newData: { Id: string; Text: string }[]) { const column = (this.grid as GridComponent).getColumnByField('ShipCountry'); if (column?.edit?.params) { (column.edit.params as any).dataSource = new DataManager(newData); }
|
Please refer the sample for more information: https://stackblitz.com/edit/angular-cymxomny-begrnkbe?file=src%2Fapp.component.ts
Please let us know if you need further assistance.
Regards,
Mohanraj Rengasamy
That doesn't produce an error but it doesn't update the list either. I had to do this:
(this.countryParams as any).params.dataSource.dataSource.json = lookupLists['Country'];
However, even this method doesn't entirely work in the case of cascading drop down lists. If I change the parent drop down list (in this case BusinessUnit) it will filter Department. However once I've clicked on Department it will never filter again. I can change BusinessUnit and Department will no longer filter.
Case 1:
Change Business Unit to 2.
Click on Department, Departments filtered on Business Unit 2.
Change Business Unit to 3.
Click on Department, Departments remain filtered on Business Unit 2.
Case 2:
Change Business Unit to 2.
Change Business Unit to 3.
Click on Department, Departments filtered on Business Unit 3.
Change Business Unit to 2.
Click on Department, Departments remain filtered on Business Unit 3.
Case 3:
Click on Department, Departments unfiltered, show complete list.
Change Business Unit to 2.
Click on Department, Departments remain unfiltered.
So it seems like once the Department drop down list has been interacted with it can no longer be filtered.
I have the columns defined as:
<e-column
field="BusinessUnitId"
headerText="Business Unit"
[allowEditing]="true"
width="100"
editType='dropdownedit'
[edit]="businessUnitParams"
textAlign="Left">
<ng-template #template let-data>
{{ data.BusinessUnit?.Name ?? '' }}
</ng-template>
</e-column>
<e-column
field="DepartmentId"
headerText="Department"
[allowEditing]="true"
width="100"
editType='dropdownedit'
[edit]="departmentParams"
textAlign="Left">
<ng-template #template let-data>
{{ data.Department?.Name ?? '' }}
</ng-template>
</e-column>
businessUnitParams: IEditCell = {
params: {
dataSource: new DataManager([]),
fields: { text: 'Text', value: 'Id' },
query: new Query(),
change: (e) => {
console.log('selected value: ', e.value);
this.onBusinessUnitChange(e.value);
},
},
};
departmentParams: IEditCell = {
params: {
dataSource: new DataManager([]),
fields: { text: 'Text', value: 'Id' },
query: new Query(),
change: (e) => {
console.log('selected value: ', e.value);
this.onDepartmentChange(e.value);
},
},
};
onBusinessUnitChange(selectedBusinessUnitId: number) {
let filteredDepartments = this.deptsNumId.filter((d: any) => d.ParentId == selectedBusinessUnitId);
(this.departmentParams as any).params.dataSource.dataSource.json = filteredDepartments;
}
Messy, but it's the only way I've gotten it to work:
onBusinessUnitChange(selectedBusinessUnitId: number) {
let filteredDepartments = this.deptsNumId.filter((d: any) => d.ParentId == selectedBusinessUnitId);
const dropdown = (document.getElementById('OrgHierarchyMappingsGridDepartmentId') as any)?.ej2_instances?.[0];
if (dropdown) {
dropdown.dataSource = filteredDepartments;
dropdown.dataBind();
}
}
Hi Legion,
Greetings from Syncfusion support,
Based on your query, it appears that you're implementing cascading dropdowns in the Grid's dialog editing mode.
To achieve this effectively, we recommend configuring the dependent dropdowns such that the selection in the parent dropdown (e.g., Business Unit) dynamically filters the options in the child dropdown (e.g., Department).
Cascading dropdown lists in dialog templates allow you to create dynamic dependencies where the options in one dropdown are based on the selected value of another. This approach allows you to create dynamic, dependent dropdowns within the dialog edit form of your Angular Grid. We have already discussed about your requirement in our documentation which can be accessed using the below link,
Documentation: https://ej2.syncfusion.com/angular/documentation/grid/editing/edit-types#render-cascading-dropdownlist-component-in-edit-form
Please get back to us if you need further assistance
Regards,
- 6 Replies
- 2 Participants
-
LR Legion Rempel
- May 15, 2025 08:43 PM UTC
- May 26, 2025 01:17 PM UTC