-
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