Issue
I am creating a form builder in Angular, I used Lam Phuoc ThinhI work for reference, check his work here
<https://codepen.io/thinhlam/pen/BowEPp>
Now the problem is I have this 3 arrays, Current Field, Form Fields and Draggable Fields. Everytime I dragged a field, like for example the Header Field and then I changed the text or value of that field, the Draggable Fields is also affected. So if i dragged another Header field the value is the same with the first header field that i drag. Please check the image below.
image
app.component.html
<div *ngFor="let set of CurrentField.Settings; let i = index; trackBy:trackByIdx" [ngSwitch]="set.Type">
<div *ngSwitchCase="'textarea'" class="form-group">
<label for="textarea-{{i}}">{{set.Name}}</label>
<input [name]="'textarea' + i" type="text" class="form-control" [(ngModel)]="set.Value">
</div>
</div>
app.component.ts
FormFields: any;
CurrentField: any;
guid: number;
DragElements = [{
'Name': "Header",
"Type": "textLabel",
'Icon': "fa fa-header",
'Settings': [{
'Name': 'Field Label',
'Value': 'Header',
'Type': 'textarea'
}]
}, {
'Name': "Columns",
"Type": "columns",
'Icon': "fa fa-columns",
'Settings': [{
'Name': 'Number of Columns',
'Value': 0,
'PossibleValue': [2,3,4]
}, {
'Name': 'Column',
'Columns': []
}],
}, {
'Name': "Image",
"Type": "image",
'Icon': "fa fa-image",
'Settings': [{
'Name': 'Field Label',
'Value': 'Image',
'Type': 'textarea'
}]
}, {
'Name': "Single Text",
'Type': "text",
'Icon': "fa fa-font",
'Settings': [{
'Name': 'Field Label',
'Value': 'Single Text',
'Type': 'text'
}]
}, {
'Name': "Number",
'Type': "number",
'Icon': "fa fa-th-large",
'Settings': [{
'Name': 'Field Label',
'Value': 'Number',
'Type': 'text'
}]
}, {
'Name': "Date",
'Type': "date",
'Icon': "fa fa-calendar",
'Settings': [{
'Name': 'Field Label',
'Value': 'Date',
'Type': 'text'
}]
}, {
'Name': "Single Selection",
"Type": "dropdown",
'Icon': "fa fa-dot-circle-o",
'Settings': [{
'Name': 'Field Label',
'Value': 'Single Selection',
'Type': 'text'
}]
}, {
'Name': "Pagaraph Text",
"Type": "textarea",
'Icon': "fa fa-align-left",
'Settings': [{
'Name': 'Field Label',
'Value': 'Paragraph Text',
'Type': 'text'
}]
}];
constructor(
private cd: ChangeDetectorRef,
private zone: NgZone,
) {}
ngOnInit() {
this.CurrentField = {};
this.FormFields = [];
this.guid = 1;
}
createNewField = function() {
return {
'id': ++this.guid,
'Name': '',
'Settings': [],
'Active': true,
'ChangeFieldSetting': function(Value, SettingName) {
switch (SettingName) {
// case 'Field Label':
// this.Settings[0].Value = Value;
// // console.log(Value);
// break;
case 'Image Alignment':
this.Settings[2].DefaultAlignment = Value;
break;
case 'Columns':
let columns : any = {};
this.Settings[0].Value = Value;
for(let i = 0; i < Value; i++) {
columns = {
'ID': i + "-" + this.id,
'Title': 'Column '+i,
'Items': []
}
this.Settings[1].Columns.push(columns);
}
console.log(this);
break;
default:
break;
}
},
'GetFieldSetting': function(settingName) {
let result = {};
let settings = this.Settings;
settings.forEach((index, set) => {
if (index.Name == settingName) {
result = index;
return;
}
});
if (!Object.keys(result).length) {
settings[settings.length - 1].Options.forEach((index, set) => {
if (index.Name == settingName) {
result = index;
return;
}
});
}
return result;
}
};
}
changeFieldName = function(Value) {
this.CurrentField.Name = Value;
this.CurrentField.Settings[0].Value = this.CurrentField.Name;
}
removeElement = function(idx){
if(this.FormFields[idx].Active) {
this.CurrentField = {};
}
this.FormFields.splice(idx, 1);
};
addElement(ele, idx) {
// this.zone.run(() => {
this.CurrentField.Active = false;
this.CurrentField = this.createNewField();
Object.assign(this.CurrentField, ele);
if (idx == null) {
this.FormFields.push(this.CurrentField);
} else {
this.FormFields.splice(idx, 0, this.CurrentField);
}
// });
};
activeField = function(f) {
this.CurrentField.Active = false;
this.CurrentField = f;
f.Active = true;
};
Solution
Wherever you are using
Object.assign(this.CurrentField,ele);
like operations
deep clone before pushing.
Object.assign(this.CurrentField, JSON.parse(JSON.stringify(ele)));
This is one way of deep cloning which has its pros and cons. But your solution will be to deep clone using any suitable method.
Answered By – Arun Mohan
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0