Problem Statement :
In below stackblitz demo, I am able to insert the FormGroup dynamically at the starting of the grid on clicking the Add button and triggering the (blur) event from one control to update the value of another control sharing same rowIndex. Now the issue is if i inserted multiple formGroups and trigger on (blur) event on any of the newly added FormGroups it updates the value of other controls as well having different rowIndex.
Steps to reproduce the issue :
Stackblitz Demo : https://stackblitz.com/edit/angular-oitz5j-4uezqr
Requirement :
Tab out on any name field of particular row, Age field on same row should display a random number without impacting other rows.
What i tried so far ?
Tried to use Array unshift() method but getting error
Property 'unshift' does not exist on type 'FormArray'
Tried to use FormArray.insert() method.It will work if we want to add a FormGroup at specific index. But it fails to insert multiple FormGroups on the top of FormArray dynamically.
Update : Above issue is working fine without Kendo Grid. Please check the below demo.
Demo : https://stackblitz.com/edit/angular-oitz5j-2a31gs
Related issues in github/stackoverflow :
https://github.com/angular/angular/issues/16322
Angular - Form Array push specific index
Note : If we are going to add the controls at the end of the Grid, it is working like a champ. Please check the below demo which works fine with adding the controls at the last.
Demo : https://stackblitz.com/edit/angular-oitz5j-aszrjq
For those who wants to insert elements dynamically in FormArray initially then use Insert with index 0.
this.formName.controls.FieldNameArray.insert(0,[...])
https://angular.io/api/forms/FormArray#insert.
Why isn't my code working?
This isn't a Kendo issue at all. Your entire form is already being created every time the view observable is triggered. So when you add a row, you are basically adding to both the items in createForm as well as triggering the view observable (by calling updateGridData), which in turn adds to the items in createForm. Telerik seems to be doing the latter as seen in this example so we don't need to insert into items at all in addNewRow. Instead, just update gridData and then call updateGridData.
Solution
There are just two issues in your code. The first one being in your view subscribe block. The code you are using will basically just push on top of the previous items and not replace them. So we need to reinitialize the items FormArray here.
this.view.subscribe(r => {
this.createForm.setControl('items', new FormArray([]));
r.data.forEach((i) => {
const newRow = new FormGroup({
name: new FormControl(i.name),
age: new FormControl(i.age)
});
(this.createForm.get("items") as FormArray).push(newRow);
});
});
You could rewrite this using map like below.
this.view.subscribe(r => {
this.createForm.setControl('items', new FormArray(r.data.map(item =>
new FormGroup({
name: new FormControl(item.name),
age: new FormControl(item.age),
})
)));
});
Now all you need to do is assign gridData when a new row is added. We need to get the data entered by the user from createForm since gridData is not bound anywhere and will not contain the data which is entered by the user. There will be no need to do anything to the form here since the view subscribe block is already taking care of declaring createForm.
addNewRow() {
const blankRow = {
name: "",
age: ""
};
this.gridData = [blankRow, ...this.createForm.get('items').value];
const data: GridDataResult = { data: this.gridData, total: this.gridData.length };
this.editService.updateGridData(data);
}
The grid should now work.
Forked StackBlitz
Note: The reason why the example where you are pushing a new row to the end of the grid works is that you are only declaring createForm once at the start in ngOnInit. Then you manually update the gridData and insert into items. There's no updateGridData here which triggers view to recreate createForm. If there was, even this wouldn't be working as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With