This example is intended to be added as a Lightning action on the account object.
Clicking the action’s button on the account layout opens a panel to create a new
contact.
This example is similar to the example provided in Configure Components for Record-Specific Actions. Compare the two examples to better understand the differences between using @AuraEnabled Apex controllers and using Lightning Data Service.
<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId"> <aura:attribute name="account" type="Object"/> <aura:attribute name="simpleAccount" type="Object"/> <aura:attribute name="accountError" type="String"/> <force:recordData aura:id="accountRecordLoader" recordId="{!v.recordId}" fields="Name,BillingCity,BillingState" targetRecord="{!v.account}" targetFields="{!v.simpleAccount}" targetError="{!v.accountError}" /> <aura:attribute name="newContact" type="Object" access="private"/> <aura:attribute name="simpleNewContact" type="Object" access="private"/> <aura:attribute name="newContactError" type="String" access="private"/> <force:recordData aura:id="contactRecordCreator" layoutType="FULL" targetRecord="{!v.newContact}" targetFields="{!v.simpleNewContact}" targetError="{!v.newContactError}" /> <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> <!-- Display a header with details about the account --> <div class="slds-page-header" role="banner"> <p class="slds-text-heading--label">{!v.simpleAccount.Name}</p> <h1 class="slds-page-header__title slds-m-right--small slds-truncate slds-align-left">Create New Contact</h1> </div> <!-- Display Lightning Data Service errors, if any --> <aura:if isTrue="{!not(empty(v.accountError))}"> <div class="recordError"> <ui:message title="Error" severity="error" closable="true"> {!v.accountError} </ui:message> </div> </aura:if> <aura:if isTrue="{!not(empty(v.newContactError))}"> <div class="recordError"> <ui:message title="Error" severity="error" closable="true"> {!v.newContactError} </ui:message> </div> </aura:if> <!-- Display the new contact form --> <lightning:input aura:id="contactField" name="firstName" label="First Name" value="{!v.simpleNewContact.FirstName}" required="true"/> <lightning:input aura:id="contactField" name="lastname" label="Last Name" value="{!v.simpleNewContact.LastName}" required="true"/> <lightning:input aura:id="contactField" name="title" label="Title" value="{!v.simpleNewContact.Title}" /> <lightning:input aura:id="contactField" type="phone" name="phone" label="Phone Number" pattern="^(1?(-?\d{3})-?)?(\d{3})(-?\d{4})$" messageWhenPatternMismatch="The phone number must contain 7, 10, or 11 digits. Hyphens are optional." value="{!v.simpleNewContact.Phone}" required="true"/> <lightning:input aura:id="contactField" type="email" name="email" label="Email" value="{!v.simpleNewContact.Email}" /> <lightning:button label="Cancel" onclick="{!c.handleCancel}" class="slds-m-top--medium" /> <lightning:button label="Save Contact" onclick="{!c.handleSaveContact}" variant="brand" class="slds-m-top--medium"/> </aura:component>
({ doInit: function(component, event, helper) { component.find("contactRecordCreator").getNewRecord( "Contact", // sObject type (entityApiName) null, // recordTypeId false, // skip cache? $A.getCallback(function() { var rec = component.get("v.newContact"); var error = component.get("v.newContactError"); if(error || (rec === null)) { console.log("Error initializing record template: " + error); } else { console.log("Record template initialized: " + rec.sobjectType); } }) ); }, handleSaveContact: function(component, event, helper) { if(helper.validateContactForm(component)) { component.set("v.simpleNewContact.AccountId", component.get("v.recordId")); component.find("contactRecordCreator").saveRecord(function(saveResult) { if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") { // Success! Prepare a toast UI message var resultsToast = $A.get("e.force:showToast"); resultsToast.setParams({ "title": "Contact Saved", "message": "The new contact was created." }); // Update the UI: close panel, show toast, refresh account page $A.get("e.force:closeQuickAction").fire(); resultsToast.fire(); // Reload the view so components not using force:recordData // are updated $A.get("e.force:refreshView").fire(); } else if (saveResult.state === "INCOMPLETE") { console.log("User is offline, device doesn't support drafts."); } else if (saveResult.state === "ERROR") { console.log('Problem saving contact, error: ' + JSON.stringify(saveResult.error)); } else { console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error)); } }); } }, handleCancel: function(component, event, helper) { $A.get("e.force:closeQuickAction").fire(); }, })
({ validateContactForm: function(component) { var validContact = true; // Show error messages if required fields are blank var allValid = component.find('contactField').reduce(function (validFields, inputCmp) { inputCmp.showHelpMessageIfInvalid(); return validFields && inputCmp.get('v.validity').valid; }, true); if (allValid) { // Verify we have an account to attach it to var account = component.get("v.account"); if($A.util.isEmpty(account)) { validContact = false; console.log("Quick action context doesn't have a valid account."); } return(validContact); } } })