Newer Version Available
Lightning Data Service Example
Here’s a longer, more complete example of using Lightning Data
Service to create a “Quick
Contact” action panel.
Example
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 very 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.
ldsQuickContact.cmp
1<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId">
2
3 <aura:attribute name="account" type="Object"/>
4 <aura:attribute name="accountError" type="String"/>
5 <force:recordPreview aura:id="accountRecordLoader"
6 recordId="{!v.recordId}"
7 fields="Name,BillingCity,BillingState"
8 targetRecord="{!v.account}"
9 targetError="{!v.accountError}"
10 />
11
12 <aura:attribute name="newContact" type="Object" access="private"/>
13 <aura:attribute name="newContactError" type="String" access="private"/>
14 <aura:attribute name="hasErrors" type="Boolean"
15 description="Indicate whether there were failures when validating the contact." />
16 <force:recordPreview aura:id="contactRecordCreator"
17 layoutType="FULL"
18 targetRecord="{!v.newContact}"
19 targetError="{!v.newContactError}"
20 />
21
22 <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
23
24 <!-- Display a header with details about the account -->
25 <div class="slds-page-header" role="banner">
26 <p class="slds-text-heading--label">{!v.account.Name}</p>
27 <h1 class="slds-page-header__title slds-m-right--small
28 slds-truncate slds-align-left">Create New Contact</h1>
29 </div>
30
31 <!-- Display Lightning Data Service errors, if any -->
32 <aura:if isTrue="{!not(empty(v.accountError))}">
33 <div class="recordError">
34 <ui:message title="Error" severity="error" closable="true">
35 {!v.accountError}
36 </ui:message>
37 </div>
38 </aura:if>
39 <aura:if isTrue="{!not(empty(v.newContactError))}">
40 <div class="recordError">
41 <ui:message title="Error" severity="error" closable="true">
42 {!v.newContactError}
43 </ui:message>
44 </div>
45 </aura:if>
46
47 <!-- Display form validation errors, if any -->
48 <aura:if isTrue="{!v.hasErrors}">
49 <div class="formValidationError">
50 <ui:message title="Error" severity="error" closable="true">
51 The new contact can't be saved because it's not valid.
52 Please review and correct the errors in the form.
53 </ui:message>
54 </div>
55 </aura:if>
56
57 <!-- Display the new contact form -->
58 <div class="slds-form--stacked">
59
60 <div class="slds-form-element">
61 <label class="slds-form-element__label" for="contactFirstName">First Name: </label>
62 <div class="slds-form-element__control">
63 <ui:inputText class="slds-input" aura:id="contactFirstName"
64 value="{!v.newContact.FirstName}" required="true"/>
65 </div>
66 </div>
67 <div class="slds-form-element">
68 <label class="slds-form-element__label" for="contactLastName">Last Name: </label>
69 <div class="slds-form-element__control">
70 <ui:inputText class="slds-input" aura:id="contactLastName"
71 value="{!v.newContact.LastName}" required="true"/>
72 </div>
73 </div>
74
75 <div class="slds-form-element">
76 <label class="slds-form-element__label" for="contactTitle">Title: </label>
77 <div class="slds-form-element__control">
78 <ui:inputText class="slds-input" aura:id="contactTitle"
79 value="{!v.newContact.Title}" />
80 </div>
81 </div>
82
83 <div class="slds-form-element">
84 <label class="slds-form-element__label" for="contactPhone">Phone Number: </label>
85 <div class="slds-form-element__control">
86 <ui:inputPhone class="slds-input" aura:id="contactPhone"
87 value="{!v.newContact.Phone}" required="true"/>
88 </div>
89 </div>
90 <div class="slds-form-element">
91 <label class="slds-form-element__label" for="contactEmail">Email: </label>
92 <div class="slds-form-element__control">
93 <ui:inputEmail class="slds-input" aura:id="contactEmail"
94 value="{!v.newContact.Email}" />
95 </div>
96 </div>
97
98 <div class="slds-form-element">
99 <ui:button label="Cancel" press="{!c.handleCancel}"
100 class="slds-button slds-button--neutral" />
101 <ui:button label="Save Contact" press="{!c.handleSaveContact}"
102 class="slds-button slds-button--brand" />
103 </div>
104
105 </div>
106
107</aura:component>
ldsQuickContactController.js
1({
2 doInit: function(component, event, helper) {
3 component.find("contactRecordCreator").getNewRecord(
4 "Contact",
5 null,
6 null,
7 false,
8 $A.getCallback(function() {
9 var rec = component.get("v.newContact");
10 var error = component.get("v.newContactError");
11 if(error || (rec === null)) {
12 console.log("Error initializing record template: " + error);
13 }
14 else {
15 console.log("Record template initialized: " + rec.sobjectType);
16 }
17 })
18 );
19 },
20
21 handleSaveContact: function(component, event, helper) {
22 if(helper.validateContactForm(component)) {
23 component.set("v.hasErrors", false);
24 component.set("v.newContact.AccountId", component.get("v.recordId"));
25 component.find("contactRecordCreator").saveRecord(function(saveResult) {
26 if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
27
28 // Success! Prepare a toast UI message
29 var resultsToast = $A.get("e.force:showToast");
30 resultsToast.setParams({
31 "title": "Contact Saved",
32 "message": "The new contact was created."
33 });
34
35 // Update the UI: close panel, show toast, refresh account page
36 $A.get("e.force:closeQuickAction").fire();
37 resultsToast.fire();
38
39 // Reload the view so components not using force:recordPreview
40 // are updated
41 $A.get("e.force:refreshView").fire();
42 }
43 else if (saveResult.state === "INCOMPLETE") {
44 console.log("User is offline, device doesn't support drafts.");
45 }
46 else if (saveResult.state === "ERROR") {
47 console.log('Problem saving contact, error: ' +
48 JSON.stringify(saveResult.error));
49 }
50 else {
51 console.log('Unknown problem, state: ' + saveResult.state +
52 ', error: ' + JSON.stringify(saveResult.error));
53 }
54 });
55 }
56 else {
57 // New contact form failed validation, show a message to review errors
58 component.set("v.hasErrors", true);
59 }
60 },
61
62 handleCancel: function(component, event, helper) {
63 $A.get("e.force:closeQuickAction").fire();
64 },
65})
ldsQuickContactHelper.js
1({
2 validateContactForm: function(component) {
3 var validContact = true;
4
5 // First and Last Name are required
6 var firstNameField = component.find("contactFirstName");
7 if($A.util.isEmpty(firstNameField.get("v.value"))) {
8 validContact = false;
9 firstNameField.set("v.errors", [{message:"First name can't be blank"}]);
10 }
11 else {
12 firstNameField.set("v.errors", null);
13 }
14 var lastNameField = component.find("contactLastName");
15 if($A.util.isEmpty(lastNameField.get("v.value"))) {
16 validContact = false;
17 lastNameField.set("v.errors", [{message:"Last name can't be blank"}]);
18 }
19 else {
20 lastNameField.set("v.errors", null);
21 }
22
23 // Verify we have an account to attach it to
24 var account = component.get("v.account");
25 if($A.util.isEmpty(account)) {
26 validContact = false;
27 console.log("Quick action context doesn't have a valid account.");
28 }
29
30 // TODO: (Maybe) Validate email and phone number
31
32 return validContact;
33 }
34})