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