2

I want to load the fields of an existing Record into a component, then display that component next to the existing detail of the record. Let the user change what they will then save that form as a new record. I am trying to use Lightning data service. I know how to load a record with force:recordData and how to create a new record. Here I want to do both. Can I use the force:recordData tag twice in one page ? What is a good way to do this ? This is what I have:

<aura:component implements="force:lightningQuickAction,flexipage:availableForRecordHome,force:hasRecordId">

<aura:attribute name="clonedExamRecord" type="Object"/>
<aura:attribute name="recordSaveError" type="String"/>
<aura:attribute name="recordId" type="String"/>
<aura:attribute name="existingExam" type="Object"/>

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

<force:recordData aura:id="ClonedExamCreator"
    layoutType="FULL"
    targetFields="{!v.clonedExamRecord}"
    targetError="{!v.recordSaveError}"
    mode="EDIT" />  

<force:recordData aura:id="ExamLoader"
                  recordId="{!v.recordId}"
                  layoutType="FULL"
                  targetFields="{!v.existingExam}"
                  mode="VIEW"/>

<!-- Display an editing form -->
<div class="Record Details">
    <lightning:card iconName="action:edit" title="Cloned Exam">
        <div class="slds-p-horizontal--small">
            <lightning:input label="Name" value="{!v.clonedExamRecord.Name}" placeholder="{!v.existingExam.Name}"/>
            <br/>
            <lightning:input label="Number of Minutes" value="{!v.clonedExamRecord.Number_of_Minutes__c}"/>
            <br/>
            <lightning:input label="Graded" type="checkbox" value="{!v.clonedExamRecord.Graded__c}"/>
            <br/>
            <lightning:input label="Show One Question at a Time" type="checkbox" value="{!v.clonedExamRecord.Show_One_Question_at_a_Time__c}"/>
            <br/>
            <lightning:input label="Show Score Upon Completion" type="checkbox" value="{!v.clonedExamRecord.Show_Score_Upon_Completion__c}"/>
            <br/>
            <lightning:input label="Randomize Question Order" type="checkbox" value="{!v.clonedExamRecord.Randomize_Question_Order__c}"/>
            <br/>
            <lightning:select label="Status" value="{!v.clonedExamRecord.Status__c}">
                <option value="Created">Created</option>
                <option value="Sent">Sent</option>
                <option value="Ungraded">Ungraded</option>
                <option value="Graded">Graded</option>
                <option value="Cancelled">Cancelled</option>
            </lightning:select>
            <lightning:button variant="brand" label="Clone" iconName="action:new_campaign" onclick="{!c.createNewExam}" />
        </div>
    </lightning:card>
</div>

<!-- Display Lightning Data Service errors, if any -->
<aura:if isTrue="{!not(empty(v.recordError))}">
    <div class="recordError">
        {!v.recordError}
    </div>
</aura:if>

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

({
doInit : function(component, event, helper){
      // Prepare a new record from template
    component.find("ClonedExamCreator").getNewRecord(
        "Exam__c", // sObject type (objectApiName)
        null,      // recordTypeId
        false,     // skip cache?
        $A.getCallback(function() {
            //var rec = component.get("v.clonedExamRecord");
            //var error = component.get("v.recordSaveError");
            //if(error || (rec === null)) {
             //   console.log("Error initializing record template: " + error);
             //   return;
            //}
            //console.log("Record template initialized: " + rec.sobjectType);
        })
    );


},

createNewExam : function(component, event, helper){
    component.find("ClonedExamCreator").saveRecord(function(saveResult) {
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                // record is saved successfully
                var resultsToast = $A.get("e.force:showToast");
                resultsToast.setParams({
                    "title": "Saved",
                    "message": "The record was saved."
                });
                resultsToast.fire();

            } else if (saveResult.state === "INCOMPLETE") {
                // handle the incomplete state
                console.log("User is offline, device doesn't support drafts.");
            } else if (saveResult.state === "ERROR") {
                // handle the error state
                console.log('Problem saving contact, error: ' + JSON.stringify(saveResult.error));
            } else {
                console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
            }
        });
    }

})

  • 7
    Does it work? If not, what behavior are you observing? – sfdcfox Dec 6 '17 at 22:01
1

To create a new record, recordId attribute must be empty and to load record, recordId must have some value. To attain this we need two force:recordData tags. So you can use two tags in one lightning component.

0

Yes it worked perfectly. You are right @Novice.

<aura:attribute name="clonedExamRecord" type="Object"/>
<aura:attribute name="recordSaveError" type="String"/>
<aura:attribute name="recordId" type="String"/>
<aura:attribute name="existingExam" type="Object"/>

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

<force:recordData aura:id="ClonedExamCreator"
    layoutType="FULL"
    targetFields="{!v.clonedExamRecord}"
    targetError="{!v.recordSaveError}"
    mode="EDIT" />  

<force:recordData aura:id="ExamLoader"
                  recordId="{!v.recordId}"
                  layoutType="FULL"
                  targetFields="{!v.existingExam}"
                  mode="VIEW"/>

<!-- Display an editing form -->
<div class="Record Details">
    <lightning:card iconName="action:edit" title="Cloned Exam">
        <div class="slds-p-horizontal--small">
            <lightning:input label="Name" value="{!v.clonedExamRecord.Name}" placeholder="{!v.existingExam.Name}"/>
            <br/>
            <lightning:input label="Number of Minutes" value="{!v.clonedExamRecord.Number_of_Minutes__c}" placeholder="{!v.existingExam.Number_of_Minutes__c}"/>
            <br/>
            <lightning:input label="Graded" type="checkbox" value="{!v.clonedExamRecord.Graded__c}"/>
            <br/>
            <lightning:input label="Show One Question at a Time" type="checkbox" value="{!v.clonedExamRecord.Show_One_Question_at_a_Time__c}"/>
            <br/>
            <lightning:input label="Show Score Upon Completion" type="checkbox" value="{!v.clonedExamRecord.Show_Score_Upon_Completion__c}"/>
            <br/>
            <lightning:input label="Randomize Question Order" type="checkbox" value="{!v.clonedExamRecord.Randomize_Question_Order__c}"/>
            <br/>
            <lightning:select label="Status" value="{!v.clonedExamRecord.Status__c}">
                <option value="Created">Created</option>
                <option value="Sent">Sent</option>
                <option value="Ungraded">Ungraded</option>
                <option value="Graded">Graded</option>
                <option value="Cancelled">Cancelled</option>
            </lightning:select>
            <lightning:button variant="brand" label="Clone" iconName="action:new_campaign" onclick="{!c.createNewExam}" />
        </div>
    </lightning:card>
</div>

<!-- Display Lightning Data Service errors, if any -->
<aura:if isTrue="{!not(empty(v.recordError))}">
    <div class="recordError">
        {!v.recordError}
    </div>
</aura:if>

Anyone know how to use placeholder with numbers and checkboxes ?

  • I've used force:recordData within an aura:iteration to create separate LDS components for multiple records (such as those in a list of records) so I can catch updates to any of those records and act on them (such as updating the list). Just a thought if you need to use LDS with multiple records within a component. – Florissant53 Dec 7 '17 at 20:15
  • Florissant53, How do you get the ID of a record you just inserted with force:recordData ? – SallyRothroat Dec 8 '17 at 16:40
  • I haven't used force:recordData for record inserts or updates yet, just for loading records and monitoring them for updates elsewhere in the app via standard or custom components, so I can react to those updates (such as refreshing a component). One of my components loaded dozens of records at a time, hence my need to put force:recordData within an aura:iteration. But it's just for monitoring updates, not for inserts or updates. – Florissant53 Dec 9 '17 at 18:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.