You need to sign in to do that
Don't have an account?
Paul Lightning
How to create more than one record with lightning components
Dear fellow experts,
I am building a lightning component where I am using a form with fields in order to create multiple opportunities.
I am already able to create multiple opportunities in my database but I am not able to create multiple local opportunities yet.
I want to first create multiple local opportunities that I can display as a list with certain fields that can be manually adjusted.
I very much appreciate help, since I couldn't find any solution although I was searching for it for one week!
Here is my code:
createMultipleOpportunities.cmp
<!-- form with fields that are used to create multiple opportunities, i don't think this code is relevant, therefore not shown here-->
<!--variable that is supposed to generate a collection or array where i can store my new local objects-->
<aura:attribute name="newChildOpportunities" type="Opportunity[]"/>
<!--Button that is supposed to create local opportunities-->
<ui:button label="Create child Opportunities" press="{!c.createChildOpportunitieslocally}"/>
<!--this part is supposed to iterate through all child opportunities, doesn't display them yet-->
<table class="slds-table slds-table--bordered">
<thead>
<tr>
<th scope="col"><span class="slds-truncate">Name</span></th>
<th scope="col"><span class="slds-truncate">Child Deal Size</span></th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.newChildOpportunities}" var="opportunity">
<tr>
<td>{!opportunity.Name}</td>
<td><ui:inputCurrency aura:id="childAmount" value="{!v.childDealSize}"/></td>
</tr>
</aura:iteration>
</tbody>
</table>
createMultipleOpportunitiesController.js
({
createChildOpportunitieslocally: function(component, event, helper) {
var i=0;
for(i=0;i<5;i++){
component.set("v.newChildOpportunity.Name", "child " + i);
component.set("v.newChildOpportunity.Deal_Size__c", 500);
}
},
})
Let me know if you need further information.
Thank you in advance for your help :)!
Best regards,
Paul
I am building a lightning component where I am using a form with fields in order to create multiple opportunities.
I am already able to create multiple opportunities in my database but I am not able to create multiple local opportunities yet.
I want to first create multiple local opportunities that I can display as a list with certain fields that can be manually adjusted.
I very much appreciate help, since I couldn't find any solution although I was searching for it for one week!
Here is my code:
createMultipleOpportunities.cmp
<!-- form with fields that are used to create multiple opportunities, i don't think this code is relevant, therefore not shown here-->
<!--variable that is supposed to generate a collection or array where i can store my new local objects-->
<aura:attribute name="newChildOpportunities" type="Opportunity[]"/>
<!--Button that is supposed to create local opportunities-->
<ui:button label="Create child Opportunities" press="{!c.createChildOpportunitieslocally}"/>
<!--this part is supposed to iterate through all child opportunities, doesn't display them yet-->
<table class="slds-table slds-table--bordered">
<thead>
<tr>
<th scope="col"><span class="slds-truncate">Name</span></th>
<th scope="col"><span class="slds-truncate">Child Deal Size</span></th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.newChildOpportunities}" var="opportunity">
<tr>
<td>{!opportunity.Name}</td>
<td><ui:inputCurrency aura:id="childAmount" value="{!v.childDealSize}"/></td>
</tr>
</aura:iteration>
</tbody>
</table>
createMultipleOpportunitiesController.js
({
createChildOpportunitieslocally: function(component, event, helper) {
var i=0;
for(i=0;i<5;i++){
component.set("v.newChildOpportunity.Name", "child " + i);
component.set("v.newChildOpportunity.Deal_Size__c", 500);
}
},
})
Let me know if you need further information.
Thank you in advance for your help :)!
Best regards,
Paul
I appreciate your help!
Best regards,
Paul
<aura:component controller="insertRecordController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
<!--Init handler which is call doInit js function on component Load-->
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<!--Event handler for Add and Delete Row Event which is fire from Child Component-->
<aura:handler name="deleteContactRowEVT" event="c:deleteContactRowEVT" action="{!c.removeDeletedContactRow}"/>
<aura:handler name="addContactRowEVT" event="c:addContactRowEVT" action="{!c.addNewContactRow}"/>
<aura:handler name="DeleteRowEvt" event="c:DeleteRowEvt" action="{!c.removeDeletedOpportunityRow}"/>
<aura:handler name="AddRowEvt" event="c:AddNewRowEvt" action="{!c.addNewOpportunityRow}"/>
<!--Aura Attribute for store Contact and Opportunity Object List as Array-->
<aura:attribute name="Acc" type="Account[]"/>
<aura:attribute name="AccountId" type="String"/>
<aura:attribute name="contactList" type="Contact[]"/>
<aura:attribute name="opportunityList" type="Opportunity[]"/>
<!--Header Part-->
<div class="slds-page-header">
<h1 class="slds-page-header__title">Create Multiple Contacts and opportunities Of an Account With Add/Delete Rows Dynamically</h1>
</div>
<div class="slds-page-header">
<h1 class="slds-page-header__title"> Account detail </h1>
</div>
<!--Table Account -->
<table class="slds-table slds-table_bordered slds-table_cell-buffer">
<thead>
<tr class="slds-text-title_caps">
<th scope="col">
<div class="slds-truncate">S.No</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Account Name">Name</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Phone">Phone</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Email">Email</div>
</th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.Acc}" var="item" indexVar="index">
<c:dynamicAccountComponent AccountInstance="{!item}" rowIndex="{!index}" />
</aura:iteration>
</tbody>
</table>
<br/>
<div class="slds-page-header">
<h1 class="slds-page-header__title"> Contact detail </h1>
</div>
<!--Table Part for contact -->
<table class="slds-table slds-table_bordered slds-table_cell-buffer">
<thead>
<tr class="slds-text-title_caps">
<th scope="col">
<div class="slds-truncate">S.No</div>
</th>
<th scope="col">
<div class="slds-truncate" title="First Name">First Name</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Last Name">Last Name</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Phone">Phone</div>
</th>
</tr>
</thead>
<tbody>
<!--Iterate the child Component for display Table rows
with pass the List Item Index for track the Every child Component
and pass each List Contact Instance -->
<aura:iteration items="{!v.contactList}" var="item" indexVar="index">
<c:dynamicRowItemComponent ContactInstance="{!item}" rowIndex="{!index}" />
</aura:iteration>
</tbody>
</table>
<br/>
<div class="slds-page-header">
<h1 class="slds-page-header__title"> Opportunity detail </h1>
</div>
<!--Table Part-->
<table class="slds-table slds-table_bordered slds-table_cell-buffer">
<thead>
<tr class="slds-text-title_caps">
<th scope="col">
<div class="slds-truncate">S.No</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Name">Opportunity Name</div>
</th>
<th scope="col">
<div class="slds-truncate" title="stage">Stage Name</div>
</th>
<th scope="col">
<div class="slds-truncate" title="CloseDate">Close Date</div>
</th>
</tr>
</thead>
<tbody>
<!--Iterate the child Component for display Table rows
with pass the List Item Index for track the Every child Component
and pass each List Contact Instance -->
<aura:iteration items="{!v.opportunityList}" var="item" indexVar="index">
<c:dynamicOpportunity opportunityInstance="{!item}" rowIndex="{!index}" />
</aura:iteration>
</tbody>
</table>
<br/>
<!--Save Button which is call Save js function on click -->
<button class="slds-button slds-button_brand" onclick="{!c.Save}">Save</button>
</aura:component>
parent component controller...............................................
({
doInit: function(component, event, helper) {
// create a Default RowItem [Contact Instance] on first time Component Load
// by call this helper function
helper.createObjectDataContact(component, event);
helper.createObjectDataAccount(component, event);
helper.createObjectDataOpportunity(component, event);
},
// function for save the Records
Save: function(component, event, helper) {
// first call the helper function in if block which will return true or false.
// this helper function check the "first Name" will not be blank on each row.
if (helper.validateRequiredContact(component, event) ) {
// call the apex class method for save the Contact List
// with pass the contact List attribute to method param.
var action = component.get("c.saveAccConOppRecord");
action.setParams({
"acc":component.get("v.Acc"),
"conList": component.get("v.contactList"),
"oppList": component.get("v.opportunityList"),
});
// set call back
action.setCallback(this, function(response) {
var state = response.getState();
//alert(response.getReturnValue);
if (state === "SUCCESS") {
//component.set("v.Acc");
//helper.createObjectDataAccount(component, event);
component.set("v.contactList", []);
helper.createObjectDataContact(component, event);
component.set("v.opportunityList", []);
helper.createObjectDataOpportunity(component, event);
alert('Records created successfully !! ');
}
});
// enqueue the server side action
$A.enqueueAction(action);
}
},
// function for create new object Row in Contact List
addNewContactRow: function(component, event, helper) {
// call the comman "createObjectData" helper method for add new Object Row to List
helper.createObjectDataContact(component, event);
},
addNewOpportunityRow: function(component, event, helper) {
// call the comman "createObjectData" helper method for add new Object Row to List
helper.createObjectDataOpportunity(component, event);
},
// function for delete the row
removeDeletedContactRow: function(component, event, helper) {
// get the selected row Index for delete, from Lightning Event Attribute
var index = event.getParam("indexVar");
// get the all List (contactList attribute) and remove the Object Element Using splice method
var AllRowsList = component.get("v.contactList");
AllRowsList.splice(index, 1);
// set the contactList after remove selected row element
component.set("v.contactList", AllRowsList);
},
removeDeletedOpportunityRow: function(component, event, helper) {
// get the selected row Index for delete, from Lightning Event Attribute
var index = event.getParam("indexVar");
// get the all List (contactList attribute) and remove the Object Element Using splice method
var AllRowsList = component.get("v.opportunityList");
AllRowsList.splice(index, 1);
// set the contactList after remove selected row element
component.set("v.opportunityList", AllRowsList);
},
})
parent component helper......................................................
({
createObjectDataContact: function(component, event) {
// get the contactList from component and add(push) New Object to List
var RowItemList = component.get("v.contactList");
RowItemList.push({
'sobjectType': 'Contact',
'FirstName': '',
'LastName': '',
'Phone': ''
});
// set the updated list to attribute (contactList) again
component.set("v.contactList", RowItemList);
},
createObjectDataAccount: function(component, event) {
// get the contactList from component and add(push) New Object to List
var RowItem = component.get("v.Acc");
RowItem.push({
'sobjectType': 'Account',
'Name': '',
'Phone': '',
'Email': ''
});
// set the updated acc to attribute acc again
component.set("v.Acc", RowItem);
},
createObjectDataOpportunity: function(component, event) {
// get the contactList from component and add(push) New Object to List
var RowItemList = component.get("v.opportunityList");
RowItemList.push({
'sobjectType': 'Opportunity',
'Name': '',
'StageName': '',
'CloseDate': ''
});
// set the updated list to attribute (contactList) again
component.set("v.opportunityList", RowItemList);
},
// helper function for check if first Name is not null/blank on save
validateRequiredAccount: function(component, event) {
var isValid = true;
var allContactRows = component.get("v.Acc");
for (var indexVar = 0; indexVar < allContactRows.length; indexVar++) {
if (allContactRows[indexVar].Name == '') {
isValid = false;
alert('First Name Can\'t be Blank on Row Number ' + (indexVar + 1));
}
}
return isValid;
},
// helper function for check if first Name is not null/blank on save
validateRequiredContact: function(component, event) {
var isValid = true;
var allContactRows = component.get("v.contactList");
for (var indexVar = 0; indexVar < allContactRows.length; indexVar++) {
if (allContactRows[indexVar].FirstName == '') {
isValid = false;
alert('First Name Can\'t be Blank on Row Number ' + (indexVar + 1));
}
}
return isValid;
},
validateRequiredOpportunity: function(component, event) {
var isValid = true;
var allOpportunityRows = component.get("v.opportunityList");
for (var indexVar = 0; indexVar < allOpportunityRows.length; indexVar++) {
if (allOpportunityRows[indexVar].Name == '') {
isValid = false;
alert('Opportunity Name Can\'t be Blank on Row Number ' + (indexVar + 1));
}
}
return isValid;
},
})
Account child component.............................................
<aura:component >
<!-- Aura Attribute for store single Contact[standard Object] Instance
And Store Index of Particular Instance -->
<aura:attribute name="AccountInstance" type="Account"/>
<aura:attribute name="rowIndex" type="String"/>
<!-- Table Row -->
<tr class="slds-text-title_caps">
<td>
{!v.rowIndex +1}
</td>
<td>
<ui:inputText class="slds-input" value="{!v.AccountInstance.Name}"/>
</td>
<td>
<ui:inputText class="slds-input" value="{!v.AccountInstance.Phone}"/>
</td>
<td>
<ui:inputText class="slds-input" value="{!v.AccountInstance.Email}"/>
</td>
</tr>
</aura:component>
<aura:component >
<!-- Aura Attribute for store single Contact[standard Object] Instance
And Store Index of Particular Instance -->
<aura:attribute name="ContactInstance" type="Contact"/>
<aura:attribute name="rowIndex" type="String"/>
<!-- Register 2 Lightning Event for handle add or Delete rows on Parent Component -->
<aura:registerEvent name="deleteContactRowEVT" type="c:deleteContactRowEVT"/>
<aura:registerEvent name="addContactRowEVT" type="c:addContactRowEVT"/>
<!-- Table Row -->
<tr class="slds-text-title_caps">
<td>
{!v.rowIndex + 1}
</td>
<td>
<ui:inputText class="slds-input" value="{!v.ContactInstance.FirstName}"/>
</td>
<td>
<ui:inputText class="slds-input" value="{!v.ContactInstance.LastName}"/>
</td>
<td>
<ui:inputPhone class="slds-input" value="{!v.ContactInstance.Phone}"/>
</td>
<td>
<!-- conditionally Display Add or Delete Icons
if rowIndex is 0 then show Add New Row Icon else show delete Icon
-->
<aura:if isTrue="{!v.rowIndex == 0}">
<a onclick="{!c.AddNewContactRow}">
<lightning:icon iconName="utility:add" class="slds-icon slds-icon_small" size="small" alternativeText="add"/>
<span class="slds-assistive-text">Add Icon</span>
</a>
<aura:set attribute="else">
<a onclick="{!c.removeContactRow}">
<lightning:icon variant="error" iconName="utility:delete" class="slds-icon slds-icon_small" size="small" alternativeText="icon"/>
<span class="slds-assistive-text">Delete Icon</span>
</a>
</aura:set>
</aura:if>
</td>
</tr>
</aura:component>
contact child component controller.........................................
({
AddNewContactRow : function(component, event, helper){
// fire the AddNewRowEvt Lightning Event
component.getEvent("addContactRowEVT").fire();
},
removeContactRow : function(component, event, helper){
// fire the DeleteRowEvt Lightning Event and pass the deleted Row Index to Event parameter/attribute
component.getEvent("deleteContactRowEVT").setParams({"indexVar" : component.get("v.rowIndex") }).fire();
},
})
opportunity child component..................................................
<aura:component >
<!-- Aura Attribute for store single Contact[standard Object] Instance
And Store Index of Particular Instance -->
<aura:attribute name="opportunityInstance" type="opportunity"/>
<aura:attribute name="rowIndex" type="String"/>
<!-- Register 2 Lightning Event for handle add or Delete rows on Parent Component -->
<aura:registerEvent name="DeleteRowEvt" type="c:DeleteRowEvt"/>
<aura:registerEvent name="AddRowEvt" type="c:AddNewRowEvt"/>
<!-- Table Row -->
<tr class="slds-text-title_caps">
<td>
{!v.rowIndex + 1}
</td>
<td>
<ui:inputText class="slds-input" value="{!v.opportunityInstance.Name}"/>
</td>
<td>
<ui:inputText class="slds-input" value="{!v.opportunityInstance.StageName}"/>
</td>
<td>
<Lightning:Input class="slds-input" value="{!v.opportunityInstance.CloseDate}" type='Date' />
</td>
<td>
<!-- conditionally Display Add or Delete Icons
if rowIndex is 0 then show Add New Row Icon else show delete Icon
-->
<aura:if isTrue="{!v.rowIndex == 0}">
<a onclick="{!c.AddNewOpportunityRow}">
<lightning:icon iconName="utility:add" class="slds-icon slds-icon_small" size="small" alternativeText="add"/>
<span class="slds-assistive-text">Add Icon</span>
</a>
<aura:set attribute="else">
<a onclick="{!c.removeOpportunityRow}">
<lightning:icon variant="error" iconName="utility:delete" class="slds-icon slds-icon_small" size="small" alternativeText="icon"/>
<span class="slds-assistive-text">Delete Icon</span>
</a>
</aura:set>
</aura:if>
</td>
</tr>
</aura:component>
opportunity child component controller.................................
({
AddNewOpportunityRow : function(component, event, helper){
// fire the AddNewRowEvt Lightning Event
component.getEvent("AddRowEvt").fire();
},
removeOpportunityRow : function(component, event, helper){
// fire the DeleteRowEvt Lightning Event and pass the deleted Row Index to Event parameter/attribute
component.getEvent("DeleteRowEvt").setParams({"indexVar" : component.get("v.rowIndex") }).fire();
}
})
DeleteRowEvt...................................
<aura:event type="COMPONENT" description="Event to remove Row" >
<aura:attribute name="indexVar" type="Integer" description="Use For Delete Row" />
</aura:event>
controller Apex class...................................................
public with sharing class insertRecordController {
@AuraEnabled
public static Id saveAccConOppRecord(List<Account> acc,List<Contact> conList,List<Opportunity> oppList){
Id AccountId;
system.debug(acc);
system.debug(conList);
system.debug(oppList);
SavePoint sp = Database.setSavePoint();
try{
//inserting Account
insert acc;
//Account a=[SELECT Id FROM Account WHERE CreatedDate=TODAY LIMIT 1 ];
for(Account a: acc){
AccountId=a.Id;}
//inserting List of Contact associated with Account id
List<Contact> contactToInsert=new List<Contact>();
for(Contact con : conList){
con.AccountId=AccountId;
contactToInsert.add(con);
}
insert contactToInsert;
//inserting List of Opportunity associated with Account id
List<Opportunity> OpportunityToInsert=new List<Opportunity>();
for(Opportunity opp : oppList){
opp.AccountID = AccountId;
OpportunityToInsert.add(opp);
}
insert OpportunityToInsert;
}
catch(Exception e){
Database.rollback(sp); // if, is there any error occure than transaction would be rolled back to same stage of database.
}
return AccountId;
}
}
Send a message
parent compo
accWithConWithOpp.cmp
child component name
//dynamicAccountComponent 1.for account
// dynamicRowItemComponent -for contact
//dynamicOpportunity - for opportunity
<aura:application extends="force:slds">
<!-- <c:DataProcessor /> -->
<c:accWithConWithOpp />
</aura:application>