Skip to content

Commit e721284

Browse files
committed
fix: improve handling of controls in form array
- Refactored control retrieval logic by replacing `getControlOfGroup` with direct use of `control.get` without using a startingIndex - Added `moveFormControlToPosition` method to handle control positioning during drag-and-drop operations. Ensured controls remain correctly linked to their respective groups
1 parent 27a1bfc commit e721284

File tree

3 files changed

+56
-18
lines changed

3 files changed

+56
-18
lines changed

src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
[formGroup]="group"
3636
[formModel]="formModel"
3737
[context]="groupModel"
38-
[group]="getControlOfGroup(groupModel)"
38+
[group]="control.get([groupModel.index])"
3939
[hidden]="_model.hidden"
4040
[class.d-none]="_model.hidden"
4141
[layout]="formLayout"

src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,37 @@ describe('DsDynamicFormArrayComponent', () => {
159159
expect(component.elementBeingSorted).toBeNull();
160160
expect(component.elementBeingSortedStartingIndex).toBeNull();
161161
});
162+
163+
describe('moveFormControlToPosition', () => {
164+
it('should move form control from one position to another', () => {
165+
const formArray = component.control as any;
166+
const initialControls = formArray.controls.map((ctrl: any) => ctrl);
167+
const movedControl = initialControls[1];
168+
169+
// Move control from index 1 to index 3
170+
(component as any).moveFormControlToPosition(1, 3);
171+
172+
expect(formArray.at(3)).toBe(movedControl);
173+
expect(formArray.length).toBe(5);
174+
});
175+
176+
it('should preserve form control values after move', () => {
177+
const formArray = component.control as any;
178+
179+
// Set actual values to the form controls
180+
formArray.at(0).patchValue({ testFormRowArrayGroupInput: 'Author 1' });
181+
formArray.at(1).patchValue({ testFormRowArrayGroupInput: 'Author 2' });
182+
formArray.at(2).patchValue({ testFormRowArrayGroupInput: 'Author 3' });
183+
formArray.at(3).patchValue({ testFormRowArrayGroupInput: 'Author 4' });
184+
formArray.at(4).patchValue({ testFormRowArrayGroupInput: 'Author 5' });
185+
186+
(component as any).moveFormControlToPosition(1, 3);
187+
188+
expect(formArray.at(0).value.testFormRowArrayGroupInput).toBe('Author 1');
189+
expect(formArray.at(1).value.testFormRowArrayGroupInput).toBe('Author 3');
190+
expect(formArray.at(2).value.testFormRowArrayGroupInput).toBe('Author 4');
191+
expect(formArray.at(3).value.testFormRowArrayGroupInput).toBe('Author 2');
192+
expect(formArray.at(4).value.testFormRowArrayGroupInput).toBe('Author 5');
193+
});
194+
});
162195
});

src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,16 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent {
8888
}
8989

9090
moveSelection(event: CdkDragDrop<Relationship>) {
91+
const prevIndex = event.previousIndex;
92+
const index = event.currentIndex;
9193

9294
// prevent propagating events generated releasing on the same position
93-
if (event.previousIndex === event.currentIndex) {
95+
if (prevIndex === index) {
9496
return;
9597
}
9698

97-
this.model.moveGroup(event.previousIndex, event.currentIndex - event.previousIndex);
98-
const prevIndex = event.previousIndex;
99-
const index = event.currentIndex;
99+
this.model.moveGroup(prevIndex, index - prevIndex);
100+
this.moveFormControlToPosition(prevIndex, index);
100101

101102
if (hasValue(this.model.groups[index]) && hasValue((this.control as any).controls[index])) {
102103
this.onCustomEvent({
@@ -124,19 +125,6 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent {
124125
return this.model.groups.length === 1 || !this.model.isDraggable;
125126
}
126127

127-
/**
128-
* Gets the control of the specified group model. It adds the startingIndex property to the group model if it does not
129-
* already have it. This ensures that the controls are always linked to the correct group model.
130-
* @param groupModel The group model to get the control for.
131-
* @returns The form control of the specified group model.
132-
*/
133-
getControlOfGroup(groupModel: any) {
134-
if (!groupModel.hasOwnProperty('startingIndex')) {
135-
groupModel.startingIndex = groupModel.index;
136-
}
137-
return this.control.get([groupModel.startingIndex]);
138-
}
139-
140128
/**
141129
* Toggles the keyboard drag and drop feature for the given sortable element.
142130
* @param event
@@ -199,6 +187,7 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent {
199187

200188
if (this.elementBeingSorted) {
201189
this.model.moveGroup(idx, newIndex - idx);
190+
this.moveFormControlToPosition(idx, newIndex);
202191
if (hasValue(this.model.groups[newIndex]) && hasValue((this.control as any).controls[newIndex])) {
203192
this.onCustomEvent({
204193
previousIndex: idx,
@@ -227,6 +216,7 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent {
227216

228217
cancelKeyboardDragAndDrop(sortableElement: HTMLDivElement, index: number, length: number) {
229218
this.model.moveGroup(index, this.elementBeingSortedStartingIndex - index);
219+
this.moveFormControlToPosition(index, this.elementBeingSortedStartingIndex);
230220
if (hasValue(this.model.groups[this.elementBeingSortedStartingIndex]) && hasValue((this.control as any).controls[this.elementBeingSortedStartingIndex])) {
231221
this.onCustomEvent({
232222
previousIndex: index,
@@ -281,4 +271,19 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent {
281271
}));
282272
}
283273
}
274+
275+
private moveFormControlToPosition(fromIndex: number, toIndex: number) {
276+
if (!hasValue(fromIndex) || !hasValue(toIndex)) {
277+
return;
278+
}
279+
280+
const formArray = this.control as any;
281+
if (formArray && formArray.controls) {
282+
const movedControl = formArray.at(fromIndex);
283+
if (movedControl) {
284+
formArray.removeAt(fromIndex,{ emitEvent: false });
285+
formArray.insert(toIndex, movedControl, { emitEvent: false });
286+
}
287+
}
288+
}
284289
}

0 commit comments

Comments
 (0)