I am creating a custom form in lightning to create case. The default create case form shows all the read only fields and is not as user friendly. Using the solution mentioned in this post I created a form that dynamically retrieves fields from fieldset and renders the form.
The challenge I am having is when submitting the forms I am not able to retrieve the fields using their id. Setting aura-id in dynamically created components does not work and when using the html id attribute I am not able to retrieve it using document.getElementById
. I need to validate to make sure required fields are populated and then submit values to apex controller to create case. Below is code from my component. Any help will be very much appreciated!
The component:
<aura:component implements="flexipage:availableForAllPageTypes,force:lightningQuickAction" controller="FieldSetController">
<aura:attribute name="values" type="Object[]"/>
<aura:attribute name="fields" type="Object[]"/>
<aura:attribute name="form" type="Aura.Component[]"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<fieldset class="slds-box slds-theme--default slds-container--medium">
<legend class="slds-text-heading--small slds-p-vertical--medium">
Create New Case
</legend>
<form id="caseForm" class="slds-form--stacked">
{!v.form}
</form>
</fieldset>
<ui:inputText label="testbox" aura:id="testboxid" value="test"/>
</aura:component>
The controller:
({
doInit: function(component, event, helper) {
console.log('**** INSIDE INIT');
helper.getFields(component, event);
},
doSubmit: function(component, event, helper) {
console.log('called submit');
helper.submitForm(component, event);
},
fieldOnChange: function(component, event, helper){
console.log('value changed');
},
submit2: function(component, event, helper) {
//debugger;
console.log(component.get("v.form")[0].get("domId"));
}
})
The helper:
({
/*
* Map the Schema.FieldSetMember to the desired component config, including specific attribute values
* Source: https://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#CSHID=apex_class_Schema_FieldSetMember.htm|StartTopic=Content%2Fapex_class_Schema_FieldSetMember.htm|SkinName=webhelp
*
* Change the componentDef and attributes as needed for other components
*/
configMap: {
"anytype": { componentDef: "ui:inputText" },
"base64": { componentDef: "ui:inputText" },
"boolean": {componentDef: "ui:inputCheckbox" },
"combobox": { componentDef: "ui:inputSelect" },
"currency": { componentDef: "ui:inputText" },
"datacategorygroupreference": { componentDef: "ui:inputText" },
"date": { componentDef: "ui:inputDate" },
"datetime": { componentDef: "ui:inputDateTime" },
"double": { componentDef: "ui:inputNumber", attributes: { values: { format: "0.00"} } },
"email": { componentDef: "ui:inputEmail" },
"encryptedstring": { componentDef: "ui:inputText" },
"id": { componentDef: "ui:inputText" },
"integer": { componentDef: "ui:inputNumber", attributes: { values: { format: "0"} } },
"multipicklist": { componentDef: "ui:inputText" },
"percent": { componentDef: "ui:inputNumber", attributes: { values: { format: "0"} } },
"picklist": { componentDef: "ui:inputSelect" },
"reference": { componentDef: "ui:inputText" },
"string": { componentDef: "ui:inputText" },
"textarea": { componentDef: "ui:inputTextArea" },
"time": { componentDef: "ui:inputDateTime", attributes: { values: { format: "h:mm a"} } },
"url": { componentDef: "ui:inputText" },
"button": { componentDef: "ui:button" }
},
// Adds the component via newComponentAsync and sets the value handler
addComponent: function(component, facet, config, fieldPath) {
if(config.attributes.values.fieldtype === 'button'){
console.log('Inside creating button')
$A.createComponents(
[
["aura:html",{
"tag": "div",
HTMLAttributes:{"class" : "slds-form-element"},
}],
[config.componentDef,{
"label": "Submit",
"buttonType": "button",
"class": "slds-button slds-button--brand",
"press": component.getReference("c.submit2")
}]
],
function(components, status, errorMessage){
if(status === "SUCCESS"){
var cmp1 = components[0];
var cmp2 = components[1];
cmp1.set("v.body",cmp2);
facet.push(cmp1);
}
else if(status === "INCOMPLETE"){
console.log("No response");
}
else if(status === "ERROR"){
console.log("ERROR: " + errorMessage);
}
}
);
}
else{
$A.createComponents(
[
["aura:html",{
"tag": "div",
HTMLAttributes:{"class" : "slds-form-element"},
}],
["aura:html",{
"tag":"label",
HTMLAttributes:{"class" : "slds-form-element__label"}
}],
["aura:html",{
"tag":"div",
HTMLAttributes:{"class" : "slds-form-element__control"}
}],
[config.componentDef,{
"domId" : fieldPath,
"label": config.attributes.values.label,
"required" : config.attributes.values.required,
"onchange" : component.getReference("c.fieldOnChange")
}]
],
function(components, status, errorMessage){
if(status === "SUCCESS"){
var cmp1 = components[0];
var cmp2 = components[1];
var cmp3 = components[2];
var cmp4 = components[3];
if(config.attributes.values.fieldtype == 'PICKLIST')
cmp4.set("v.options",config.attributes.values.picklistopts);
/*cmp4.set("v.id",fieldPath);
cmp4.set("v.name",fieldPath);*/
console.log('*** ' + cmp4.getLocalId());
cmp1.set("v.body",cmp2);
cmp1.set("v.body",cmp3);
cmp3.set("v.body",cmp4);
facet.push(cmp1);
}
else if(status === "INCOMPLETE"){
console.log("No response");
}
else if(status === "ERROR"){
console.log("ERROR: " + errorMessage);
}
}
);
}
},
// Create a form given the set of fields
createForm: function(component, fields) {
var field = null;
var cmp = null;
var def = null;
var config = null;
var self = this;
var btn = {"label" : "Submit",
"type" : "button",
"required" : "false"};
fields.push(btn);
// Clear any existing components in the form facet
component.set("v.form", []);
var facet = component.get("v.form");
var values = component.get("v.values");
for (var i = 0; i < fields.length; i++) {
field = fields[i];
// Copy the config, note that this type of copy may not work on all browsers!
config = JSON.parse(JSON.stringify(this.configMap[field.type.toLowerCase()]));
// Add attributes if needed
config.attributes = config.attributes || {};
// Add attributes.values if needed
config.attributes.values = config.attributes.values || {};
// Set the required and label attributes
config.attributes.values.required = field.required;
config.attributes.values.label = field.label;
config.attributes.values.fieldtype = field.type;
if(field.type == 'PICKLIST'){
var opts = [];
for(var j=0; j < field.picklistoptions.length; j++){
opts.push({class: "optionClass", label: field.picklistoptions[j], value: field.picklistoptions[j]});
}
config.attributes.values.picklistopts = opts;
}
// Add the value for each field as a name/value
values.push({name: field.fieldPath, value: config});
// Add the component to the facet and configure it
self.addComponent(component, facet, config, field.fieldPath);
}
component.set("v.form", facet);
component.set("v.values", values);
console.log('Values list ' + values);
},
getFields: function(component) {
var action = component.get("c.getFields");
var self = this;
var typeName = component.get("v.type");
var fsName = component.get("v.fsName");
action.setCallback(this, function(a) {
var fields = a.getReturnValue();
component.set("v.fields", fields);
self.createForm(component, fields);
});
$A.enqueueAction(action);
},
submitForm: function(component, event) {
//var values = component.get("v.values");
//var s = JSON.stringify(values, undefined, 2);
console.log('submit called');
}
})