Hi Anish,
You can do your implementation something like this :
<aura:application >
<aura:attribute name="contact" type="Contact" default="{LastName: 'Smith'}"/>
<ul>
<li>LastName: {!v.contact.LastName}</li>
<li>Email: {!v.contact.Email}</li>
</ul>
<c:FieldSetForm
fsName="Contact_Field_Set"
typeName="Contact"
record="{!v.contact}"
/>
<button onclick="{!c.handleSave}">save</button>
</aura:application>
FieldSetForm.cmp
----------------
<aura:component controller="FieldSetCtlr">
<aura:handler name="init" value="{!this}" action="{!c.init}" />
<aura:attribute name="record" type="Object" description="The record being edited"/>
<aura:attribute name="fsName" type="String"/>
<aura:attribute name="typeName" type="String"/>
<aura:attribute name="fields" type="Object[]"/>
<aura:attribute name="form" type="Aura.Component[]"/>
<aura:attribute name="inputToField" type="Map"/>
<p>
{!v.form}
</p>
</aura:component>
FieldSetFormController.js
-------------------------
({
init: function(cmp, event, helper) {
console.log('FieldSetFormController.init');
var action = cmp.get('c.getFields');
action.setParams({
fsName: cmp.get('v.fsName'),
typeName: cmp.get('v.typeName')
});
action.setCallback(this,
function(response) {
console.log('FieldSetFormController getFields callback');
var fields = response.getReturnValue();
cmp.set('v.fields', fields);
helper.createForm(cmp);
}
);
$A.enqueueAction(action);
},
handleValueChange: function(cmp, event, helper) {
console.log('change');
var inputToField = cmp.get('v.inputToField');
var field = inputToField[event.getSource().getGlobalId()];
var obj = cmp.get('v.record');
if (!obj[field]) {
// Have to make a copy of the object to set a new property - thanks LockerService!
obj = JSON.parse(JSON.stringify(obj));
}
obj[field] = event.getSource().get('v.value');
cmp.set('v.record', obj);
}
})
FieldSetFormHelper.js
---------------------
({
configMap: {
'anytype': { componentDef: 'ui:inputText', attributes: {} },
'base64': { componentDef: 'ui:inputText', attributes: {} },
'boolean': {componentDef: 'ui:inputCheckbox', attributes: {} },
'combobox': { componentDef: 'ui:inputText', attributes: {} },
'currency': { componentDef: 'ui:inputText', attributes: {} },
'datacategorygroupreference': { componentDef: 'ui:inputText', attributes: {} },
'date': {
componentDef: 'ui:inputDate',
attributes: {
displayDatePicker: true
}
},
'datetime': { componentDef: 'ui:inputDateTime', attributes: {} },
'double': { componentDef: 'ui:inputNumber', attributes: {} },
'email': { componentDef: 'ui:inputEmail', attributes: {} },
'encryptedstring': { componentDef: 'ui:inputText', attributes: {} },
'id': { componentDef: 'ui:inputText', attributes: {} },
'integer': { componentDef: 'ui:inputNumber', attributes: {} },
'multipicklist': { componentDef: 'ui:inputText', attributes: {} },
'percent': { componentDef: 'ui:inputNumber', attributes: {} },
'phone': { componentDef: 'ui:inputPhone', attributes: {} },
'picklist': { componentDef: 'ui:inputText', attributes: {} },
'reference': { componentDef: 'ui:inputText', attributes: {} },
'string': { componentDef: 'ui:inputText', attributes: {} },
'textarea': { componentDef: 'ui:inputText', attributes: {} },
'time': { componentDef: 'ui:inputDateTime', attributes: {} },
'url': { componentDef: 'ui:inputText', attributes: {} }
},
createForm: function(cmp) {
console.log('FieldSetFormHelper.createForm');
var fields = cmp.get('v.fields');
var obj = cmp.get('v.record');
var inputDesc = [];
var fieldPaths = [];
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var config = this.configMap[field.type.toLowerCase()];
if (config) {
config.attributes.label = field.label;
config.attributes.required = field.required;
config.attributes.value = obj[field.fieldPath];
config.attributes.fieldPath = field.fieldPath;
inputDesc.push([
config.componentDef,
config.attributes
]);
fieldPaths.push(field.fieldPath);
} else {
console.log('type ' + field.type.toLowerCase() + ' not supported');
}
}
$A.createComponents(inputDesc, function(cmps) {
console.log('createComponents');
var inputToField = {};
for (var i = 0; i < fieldPaths.length; i++) {
cmps[i].addHandler('change', cmp, 'c.handleValueChange');
inputToField[cmps[i].getGlobalId()] = fieldPaths[i];
}
cmp.set('v.form', cmps);
cmp.set('v.inputToField', inputToField);
});
}
})
FieldSetCtlr.cls
----------------
public class FieldSetCtlr {
@AuraEnabled
public static List<FieldSetMember> getFields(String typeName, String fsName) {
Schema.SObjectType targetType = Schema.getGlobalDescribe().get(typeName);
Schema.DescribeSObjectResult describe = targetType.getDescribe();
Map<String, Schema.FieldSet> fsMap = describe.fieldSets.getMap();
Schema.FieldSet fs = fsMap.get(fsName);
List<Schema.FieldSetMember> fieldSet = fs.getFields();
List<FieldSetMember> fset = new List<FieldSetMember>();
for (Schema.FieldSetMember f: fieldSet) {
fset.add(new FieldSetMember(f));
}
return fset;
}
public class FieldSetMember {
public FieldSetMember(Schema.FieldSetMember f) {
this.DBRequired = f.DBRequired;
this.fieldPath = f.fieldPath;
this.label = f.label;
this.required = f.required;
this.type = '' + f.getType();
}
public FieldSetMember(Boolean DBRequired) {
this.DBRequired = DBRequired;
}
@AuraEnabled
public Boolean DBRequired { get;set; }
@AuraEnabled
public String fieldPath { get;set; }
@AuraEnabled
public String label { get;set; }
@AuraEnabled
public Boolean required { get;set; }
@AuraEnabled
public String type { get; set; }
}
}
Thanks.