Skip to content

Commit 13cabaf

Browse files
authored
Merge pull request #4763 from jlipka/fix/move-form-array-items
fix: improve 'move' handling of controls in form array
2 parents 19235ee + e721284 commit 13cabaf

3 files changed

Lines changed: 56 additions & 18 deletions

File tree

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
@@ -162,4 +162,37 @@ describe('DsDynamicFormArrayComponent', () => {
162162
expect(component.elementBeingSorted).toBeNull();
163163
expect(component.elementBeingSortedStartingIndex).toBeNull();
164164
});
165+
166+
describe('moveFormControlToPosition', () => {
167+
it('should move form control from one position to another', () => {
168+
const formArray = component.control as any;
169+
const initialControls = formArray.controls.map((ctrl: any) => ctrl);
170+
const movedControl = initialControls[1];
171+
172+
// Move control from index 1 to index 3
173+
(component as any).moveFormControlToPosition(1, 3);
174+
175+
expect(formArray.at(3)).toBe(movedControl);
176+
expect(formArray.length).toBe(5);
177+
});
178+
179+
it('should preserve form control values after move', () => {
180+
const formArray = component.control as any;
181+
182+
// Set actual values to the form controls
183+
formArray.at(0).patchValue({ testFormRowArrayGroupInput: 'Author 1' });
184+
formArray.at(1).patchValue({ testFormRowArrayGroupInput: 'Author 2' });
185+
formArray.at(2).patchValue({ testFormRowArrayGroupInput: 'Author 3' });
186+
formArray.at(3).patchValue({ testFormRowArrayGroupInput: 'Author 4' });
187+
formArray.at(4).patchValue({ testFormRowArrayGroupInput: 'Author 5' });
188+
189+
(component as any).moveFormControlToPosition(1, 3);
190+
191+
expect(formArray.at(0).value.testFormRowArrayGroupInput).toBe('Author 1');
192+
expect(formArray.at(1).value.testFormRowArrayGroupInput).toBe('Author 3');
193+
expect(formArray.at(2).value.testFormRowArrayGroupInput).toBe('Author 4');
194+
expect(formArray.at(3).value.testFormRowArrayGroupInput).toBe('Author 2');
195+
expect(formArray.at(4).value.testFormRowArrayGroupInput).toBe('Author 5');
196+
});
197+
});
165198
});

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
@@ -87,15 +87,16 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent {
8787
}
8888

8989
moveSelection(event: CdkDragDrop<Relationship>) {
90+
const prevIndex = event.previousIndex;
91+
const index = event.currentIndex;
9092

9193
// prevent propagating events generated releasing on the same position
92-
if (event.previousIndex === event.currentIndex) {
94+
if (prevIndex === index) {
9395
return;
9496
}
9597

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

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

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

199187
if (this.elementBeingSorted) {
200188
this.model.moveGroup(idx, newIndex - idx);
189+
this.moveFormControlToPosition(idx, newIndex);
201190
if (hasValue(this.model.groups[newIndex]) && hasValue((this.control as any).controls[newIndex])) {
202191
this.onCustomEvent({
203192
previousIndex: idx,
@@ -226,6 +215,7 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent {
226215

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

0 commit comments

Comments
 (0)