-
ChatterFeed
-
0Best Answers
-
0Likes Received
-
0Likes Given
-
1Questions
-
1Replies
Multi insert records with lightning:recordEditForm - Dynamic Binding - FieldSets - Empty Fields
Hello everyone! I'm a Jr working with Lightning Components, and I have a problem, I read all the possible documentation related to lightning:recordEditForm but I didn't have success with the issue that I have.
I'm trying to create a Dynamic Form with two LC one is WorkOrder (parent) and the other one is WorkOrderLineItem (child) I define the FieldSets API Name via the Design Resource, and also in my form I have an Add Button for add WorkOrderLineItems as many I want into my Parent Form, and I placed one independet Submit button for save all the records in the corresponding objects. The thing is, when I'm trying to save the form with all the fields filled, I don't receive any errors, but when I go to WorkOrder records I can see one new record created with or without WorkOrderLineItems BUT with Empty fields. E.g: I created one WorkOrder with one WorkOrderLineItem, when I look into WorkOrder Records I can see the new record but without the information that I filled before, but with the WorkOrderLineItem.
I'm using on both components the Lightning:recordEditForm, I wanna know if is one issue with this specific component when has a child or I can't do thie Dynamic Form in this way or if is another thing that I don't know... Can you guys help me to understand?
Thanks!!!
Below my code:
3. <!--ComplexWOFormHelper.js-->
4. <!--ComplexWOForm.design-->
6. <!-- Add_WOLIController.js -->
7. <!-- Add_WOLIHelper.js-->
8. <!-- FSFormController.apxc-->
9. <!-- Field.apxc -->
I'm trying to create a Dynamic Form with two LC one is WorkOrder (parent) and the other one is WorkOrderLineItem (child) I define the FieldSets API Name via the Design Resource, and also in my form I have an Add Button for add WorkOrderLineItems as many I want into my Parent Form, and I placed one independet Submit button for save all the records in the corresponding objects. The thing is, when I'm trying to save the form with all the fields filled, I don't receive any errors, but when I go to WorkOrder records I can see one new record created with or without WorkOrderLineItems BUT with Empty fields. E.g: I created one WorkOrder with one WorkOrderLineItem, when I look into WorkOrder Records I can see the new record but without the information that I filled before, but with the WorkOrderLineItem.
I'm using on both components the Lightning:recordEditForm, I wanna know if is one issue with this specific component when has a child or I can't do thie Dynamic Form in this way or if is another thing that I don't know... Can you guys help me to understand?
Thanks!!!
Below my code:
- PARENT CMP <!--ComplexWOForm.cmp-->
<aura:component controller="FSFormController"
implements="flexipage:availableForRecordHome,force:hasRecordId,force:hasSObjectName,flexipage:availableForAllPageTypes">
<aura:attribute name="recordTypeId" type="String" />
<aura:attribute name="fields" type="Object[]" access="private" />
<aura:handler name="init" value="{!this}" action="{!c.init}" />
<!-- <aura:handler event="force:refreshView" action="{!c.init}" /> -->
<aura:attribute name="fieldSetName" type="String" description="The api name of the field set to use from the given object." />
<aura:attribute name="fieldSetName2" type="String" description="The api name of the field set to use from the given object." />
<aura:attribute name="WOLIDetailsList" type="List" default="[]"/>
<aura:attribute name="sObjectName2" type="string" />
<aura:attribute name="object2" type="WorkOrderLineItem" default="{'sobjectType':'WorkOrderLineItem','WorkOrderId':''}" />
<aura:attribute name="mrName" type="string" description="API name of MR field on the child. "/>
<aura:attribute name="object1" type="WorkOrder" default="{'sobjectType':'WorkOrder'}" />
<!--the following attribute is for receive the ID of the parent
I use it in the controller on de doSubmit-->
<aura:attribute name="ParentRecordId" type="String" />
<!--FORM start here-->
<lightning:recordEditForm aura:id="test"
objectApiName="{! v.sObjectName }"
recordId="{! v.recordId }"
>
<lightning:messages />
<!-- Header -->
<div class=" slds-size_6-of-8 slds-box slds-theme_default ">
<div class="slds-page-header slds-grid slds-grid_pull-padded-medium">
<div class="slds-order_1">
<div class="slds-col slds-p-horizontal_medium">
<img src="{!$Resource.twiloLogo}"/>
</div>
</div>
<div class="slds-order_2">
<div class="slds-col slds-p-horizontal_medium">
<div class="slds-text-heading_large">
<h1 > Complex Work Order.</h1>
</div>
</div>
</div>
</div>
</div>
<!-- /Header -->
<!-- Creating the Parent Form-->
<div class="slds-size_6-of-8 slds-box slds-theme_default">
<aura:iteration items="{!v.fields}" var="field" indexVar="indexParent">
<lightning:inputField aura:id="{!'fieldId' + indexParent}"
fieldName="{! field.APIName }"
class=" slds-p-top_small slds-m-top_medium" />
</aura:iteration>
</div>
<!--/ Creating the Parent Form-->
<!-- Adding WOLI List to Parent Form-->
<aura:iteration items="{!v.WOLIDetailsList}" var="item" indexVar="index">
<div class="slds-size_6-of-8 slds-box slds-theme_default">
<!--Dynamic Binding -->
<span class="slds-col slds-p-horizontal_medium">
<c:Add_WOLI fieldSetName2="{!v.fieldSetName2}"
sObjectName2="{!v.sObjectName2}"
RecordIdChild="{!v.ParentRecordId}"
WOLIDetailsInnerComponent="{!v.WOLIDetailsList}"
indexNo="{!index}"/>
<hr/>
</span>
</div>
</aura:iteration>
<div>
<lightning:button iconName="utility:add" variant="border-filled" label="WOLI" onclick="{!c.addDetails}"/>
</div>
<!-- /Adding WOLI List to Parent Form-->
</lightning:recordEditForm>
<lightning:layout horizontalAlign="center" class="slds-m-top_large">
<lightning:button variant="brand" label="Submit" title="Submit" type="submit" onclick="{!c.handleSubmit}"/>
<lightning:button variant="neutral" label="Cancel" title="Cancel" type="text" onclick="{!c.handleCancel}"/>
</lightning:layout>
</aura:component>
2. <!--ComplexWOFormController.js-->
({
init: function(cmp, event, helper) {
var fieldSetName = cmp.get('v.fieldSetName');
var sobjectName = cmp.get('v.sObjectName');
var recordId = cmp.get('v.recordId');
console.log("IM @ init parent fieldsetname ",fieldSetName);
console.log("IM @ init parent sobjectName",sobjectName);
console.log("IM @ init parent recordId",recordId);
if (!fieldSetName) {
console.log('The field set is required.');
return;
}
var getFormAction = cmp.get('c.getForm');
getFormAction.setParams({
fieldSetName: fieldSetName,
objectName: sobjectName,
recordId: recordId
});
getFormAction.setCallback(this, function(response) {
var state = response.getState();
console.log('FieldSetFormController getFormAction callback PARENT');
console.log("callback state: " + state);
if (cmp.isValid() && state === "SUCCESS") {
var form = response.getReturnValue();
cmp.set('v.fields', form.Fields);
}
}
);
$A.enqueueAction(getFormAction);
},
handleSubmit : function(component, event, helper) {
console.log("I'm at Handle Submit " );
var simpleWO =component.get("v.object1");
var action= component.get("c.saveSimpleWO");
action.setParams({simpleWO :simpleWO});
action.setCallback(this, function(response) {
var state = response.getState();
console.log("State of SIMPLE WO",state);
if (state === "SUCCESS") {
// Alert the user with the value returned
// from the server
alert("From server: " + response.getReturnValue());
var parentId= response.getReturnValue();
//assign the value of parent ID to our attribute
component.set("v.ParentRecordId",parentId);
// You would typically fire a event here to trigger
// client-side notification that the server-side
// action is compvare
//
// add more logic her
// store/save education detail records as well
// component.find('test').submit();
}
else if (state === "INCOMPLETE") {
// do something
}
else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " +
errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});//$A.enqueueAction adds the server-side action to the queue
$A.enqueueAction(action);
},
handleCancel : function(component, event, helper) {
event.preventDefault();
helper.cancel(component,event);
},
addDetails: function(component,event,helper){
console.log("Add WOLI Details");
var CurrentWOLIdetailsList = component.get("v.WOLIDetailsList");
var currentSize= parseInt(CurrentWOLIdetailsList.length);
var NewSize= parseInt((currentSize)+1);
CurrentWOLIdetailsList.push(NewSize);
component.set("v.WOLIDetailsList", CurrentWOLIdetailsList);
},
})
3. <!--ComplexWOFormHelper.js-->
({
cancel :function(cmp, event) {
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
"title": "Cancel!",
"message": "Record Not Saved"
});
toastEvent.fire();
$A.get('e.force:refreshView').fire();
},
})
4. <!--ComplexWOForm.design-->
<design:component>
<design:attribute name="fieldSetName" label="Field Set Name for Parent Component (WorkOrder)" description="API valid Name of the field set to use." />
<design:attribute name="fieldSetName2" label="Field Set Name for Child Component (WorkOrderLineItems)" description="API Name of the field set to use." />
<design:attribute name="sObjectName" label="Object Name for Parent Component" description="API Name of the Object to use. This only needs to be populated when not on a record detail page." />
<design:attribute name="sObjectName2" label="Object Name for Child Component" description="API Name of the Object to use. This only needs to be populated when not on a record detail page." />
<design:attribute name="mrName" label="API name of MR field on the child. "/>
</design:component>
5. Child Component <!-- Add_WOLI.cmp -->
<aura:component controller="FSFormController"
implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
<!-- WOLI Object-->
<aura:attribute name="fieldSetName2" type="String" description="The api name of the field set to use from the given object." />
<aura:attribute name="sObjectName2" type="String" />
<aura:attribute name="object2" type="WorkOrderLineItem" default="{'sobjectType':'WorkOrderLineItem','WorkOrderId':''}" />
<aura:attribute name="mrName" type="string" description="API name of MR field on the child. "/>
<aura:attribute name="indexNo" type="Integer"/>
<aura:attribute name="sequenceNo" type="Integer"/>
<!--in EDU details is name="RegistrationRecordIdChild"-->
<aura:attribute name="RecordIdChild" type="String"/>
<!--this is the conection between the parent (I declared use this attribute on the parent COMPLEXWOFORM)-->
<aura:attribute name="WOLIDetailsInnerComponent" type="List" />
<aura:attribute name="fields2" type="Object[]" access="private" />
<aura:handler name="init" value="{!this}" action="{!c.doinit}"/>
<!-- <aura:handler event="force:refreshView" action="{!c.doinit}" /> -->
<!---whenever any change occurs in RecordIdChild aura handler calls to the controller-->
<aura:handler name="change" value="{!v.RecordIdChild}" action="{!c.saveWOLI}"/>
<aura:handler name="change" value="{!v.indexNo}" action="{!c.changeInIndexNo}" />
<div class="slds-size_6-of-8 slds-box slds-theme_shade">
<div class="slds-page-header">
<div class="sslds-col slds-p-horizontal_medium">
<div class="slds-text-heading--small">
<h2> WOLI # {!v.sequenceNo} </h2>
</div>
</div>
</div>
</div>
<div class="slds-size_6-of-8 slds-box slds-theme_shade">
<aura:iteration items="{!v.fields2}" var="field" indexVar="listIndex">
<lightning:inputField aura:id="{!'fieldId' + listIndex}"
fieldName="{!field.APIName }"
required="{!field.DBRequired}"
type="{!field.Type}"
class=" slds-p-top_small slds-m-top_medium" />
</aura:iteration>
</div>
<lightning:button iconName="utility:delete" variant="border-filled" label="Delete this wOLI" onclick="{!c.deleteDetails}"/>
</aura:component>
6. <!-- Add_WOLIController.js -->
({
doinit: function(cmp, event, helper){
var fieldSetName = cmp.get('v.fieldSetName2');
var sobjectName = cmp.get('v.sObjectName2');
var recordId = cmp.get('v.recordId');
console.log("IM AT dointchild fieldsetname WOLI",fieldSetName);
console.log("IM AT dointchild WOLI sobjectName",sobjectName);
console.log("IM AT dointchild WOLI recordId",recordId);
if (!fieldSetName) {
console.log('The field set is required.');
return;
}
console.log("DO INIT CHILD CMP")
var getFormAction = cmp.get('c.getForm');
getFormAction.setParams({
fieldSetName: fieldSetName,
objectName: sobjectName,
recordId: recordId
});
getFormAction.setCallback(this, function(response){
var state = response.getState();
console.log('FSFormController getFormAction callback CHILD');
console.log("callback state: " + state);
if (cmp.isValid() && state === "SUCCESS") {
console.log("Im at doinit child IS VALID ");
var form = response.getReturnValue();
cmp.set('v.fields2', form.Fields);
}
});
$A.enqueueAction(getFormAction);
helper.helperRectifySequence(cmp,event);
},
changeInIndexNo: function(component, event, helper){
helper.helperRectifySequence(component,event);
},
deleteDetails : function(component, event, helper) {
var NewWOLIdetails= component.get("v.WOLIDetailsInnerComponent");
var currentIndex= component.get("v.indexNo");
if(currentIndex > -1)
NewWOLIdetails.splice(currentIndex,1);
component.set("v.WOLIDetailsInnerComponent", NewWOLIdetails);
},
saveWOLI: function(component,event, helper){
// call apex class function w the name of the class
//SaveEducationalDetails
console.log("IM AT save WOLI");
var RecordIdChild = component.get("v.RecordIdChild");
component.set("v.object2.WorkOrderId",RecordIdChild);
var sOName2 = component.get("v.object2");
var rela= component.get("v.object2.WorkOrderId");
var action = component.get("c.saveComplexWO");
action.setParams({complexWO : sOName2});
action.setCallback(this,function(response) {
var state = response.getState();
console.log("STATE @ SAVEWOLI: ",state);
if (state === "SUCCESS") {
console.log("Add WOLI saved");
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({"title": "Success!",
"message": "The Complex WO has been saved.",
"type": "Success"});
toastEvent.fire();
$A.get('e.force:refreshView').fire();
}
else if (state === "INCOMPLETE") {
// do something
}
else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " +
errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});//$A.enqueueAction adds the server-side action to the queue
$A.enqueueAction(action);
},
})
7. <!-- Add_WOLIHelper.js-->
({
helperRectifySequence : function(component,event) {
var indexNo= component.get("v.indexNo");
var New=parseInt(indexNo)+1;
component.set("v.sequenceNo",New);
},
})
8. <!-- FSFormController.apxc-->
public with sharing class FSFormController {
@AuraEnabled
public static FieldSetForm getForm(Id recordId, String objectName, String fieldSetName) {
FieldSetForm form = new FieldSetForm();
form.Fields = getFields(recordId, objectName, fieldSetName);
return form;
}
private static List<Field> getFields(Id recordId, String objectName, String fieldSetName) {
Schema.SObjectType objectType = null;
if (recordId != null) {
objectType = recordId.getSobjectType();
}
else if (String.isNotBlank(objectName)) {
objectType = Schema.getGlobalDescribe().get(objectName);
}
Schema.DescribeSObjectResult objectDescribe = objectType.getDescribe();
Map<String, Schema.FieldSet> fieldSetMap = objectDescribe.fieldSets.getMap();
Schema.FieldSet fieldSet = fieldSetMap.get(fieldSetName);
List<Schema.FieldSetMember> fieldSetMembers = fieldSet.getFields();
List<Field> fields = new List<Field>();
for (Schema.FieldSetMember fsm : fieldSetMembers) {
Field f = new Field(fsm);
fields.add(f);
}
return fields;
}
public class FieldSetForm {
@AuraEnabled
public List<Field> Fields { get; set; }
public FieldSetForm() {
Fields = new List<Field>();
}
}
@AuraEnabled
public static id saveSimpleWO(SObject simpleWO){
//DML op to save SWO
insert simpleWO;
return simpleWO.id;
}
@AuraEnabled
public static id saveComplexWO(SObject complexWO){
//DML op to save SWO
insert complexWO;
return complexWO.id;
}
}
9. <!-- Field.apxc -->
public class Field {
public Field(Schema.FieldSetMember f) {
this.DBRequired = f.DBRequired;
this.APIName = f.fieldPath;
this.Label = f.label;
this.Required = f.required;
this.Type = String.valueOf(f.getType());
}
public Field(Boolean DBRequired) {
this.DBRequired = DBRequired;
}
@AuraEnabled
public Boolean DBRequired { get;set; }
@AuraEnabled
public String APIName { get;set; }
@AuraEnabled
public String Label { get;set; }
@AuraEnabled
public Boolean Required { get;set; }
@AuraEnabled
public String Type { get; set; }
}
-
- Karla Martinez3
- October 24, 2018
- Like
- 0
Superbadge Security Specialist step 5 - Could not find just one PermissionSet enabled for 2FA.
I have created a permission set with the system permission "Two-Factor Authentication for User Interface Logins" and assigned it to the Samantha Cordero users. Here is the login history which i have used the Authenticator to authenticate the login of the user.
What else am i missing? Any help is much appreciated.
- Vigneshwaran Gurunathan
- July 13, 2016
- Like
- 0