2

I've built nested lightning components available for a contact page. There are three components: the Pane which sits on the record home page this has three tabs one tab is a text field, the other two tabs are used to display different nested components. One of these components is a list of tasks. Clicking on the subject of a task in the list fires an force:editRecord event. This successfully brings up the window and any changes are saved. However it does not refresh the view. I've tried accomplishing this in a couple ways.

I tried implementing the method suggested here, which handles a force:refreshView event and uses aura:dependency.

I also tried handling a force:saveRecordSuccess however the associated controller code was not being accessed as evidenced by no console logs.

I've attempted putting the handlers in both the child component and the parent Pane component with no difference in behavior.

Lastly I tried window.location.reload(); after firing the editRecord event but it reloads the page before bringing the edit page up.

List component markup

<aura:component controller="AccountDevelopmentTaskController" access="global" implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId">
<aura:attribute name="challenges" type="Task[]" access="GLOBAL"/>
<aura:attribute name="id" type="String" access="GLOBAL"/>
<aura:handler name="init" value="{!this}" action="{!c.start}"/>
<aura:dependency resource="markup://force:editRecord" type="EVENT"/>
<aura:handler event="force:refreshView" action="{!c.start}"/>

<div class="slds-container--fluid">
    <table class="slds-table slds-table_bordered slds-table_cell-buffer">
        <thead>
         ...
        </thead>
        <tbody>
            <aura:iteration var="chlng" items="{!v.challenges}">
                <tr>
                    <th scope="row" data-label="Challenge">
                        <div class="slds-truncate slds-text-link" title="">
                            <div data-record="{!chlng.Id}" onclick="{!c.showEditPanel}">
                                <ui:outputText value="{!chlng.Subject}" class="slds-text-link_reset" />
                            </div>
                        </div>
                    </th>
                    ...
                </tr>
            </aura:iteration>

List component controller

 start : function(component,event,helper) {
    var id = component.get("v.id");
    var action = component.get("c.loadChallenges");
    action.setParams({"tId":id});
    action.setCallback(this,function(response){
        var tasks = response.getReturnValue();
        component.set("v.challenges",tasks);
    });
    $A.enqueueAction(action);
},

showEditPanel : function(component,event,helper){
    var editRecordEvent = $A.get("e.force:editRecord");
    var selectedItem = event.currentTarget;
    var recId = selectedItem.dataset.record;
    component.set("v.currParamId",recId);
    editRecordEvent.setParams({
        "recordId" : recId
    });
    editRecordEvent.fire();

}

Here is the Pane component compacted to the relevant bits:

<aura:component controller="AccountDevelopmentTaskController" access="global" implements="force:appHostable,flexipage:availableForRecordHome,force:hasRecordId">
  <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
  <aura:attribute name="msg" type="String" access="GLOBAL"/>
  <lightning:tabset class="slds-box" >
    ...
     <lightning:tab label="Challenge">
        <c:ADChallengeList id="{!v.recordId}" /> ...
0

1 Answer 1

2

Update: I did not factor in the part that you are clicking on a specific record and geetting the record Id. updated the code to take in the selected record Id and pass it to the force:recordEdit component.

Note to others: The OP reported that this implementation was browser dependent, he was having issues on chrome v.61 /32 bit version, and had no issues on 64 bit version/IE

Here we go,, this is the craziest thing I have done in a long time. I recreated the whole $A.get("e.force:editRecord") event to gain control of the save button.

First the Output:

enter image description here

This code involves

1) Winter 18 developer edition.

2) Dynamically creating the force:recordedit component and save button and wiring the save button to call the recordsave (event). Because I used force:recordedit component I now get to use recordsavesuccess.

<aura:handler name="onSaveSuccess" event="force:recordSaveSuccess" action="{!c.start}"/>

3) An event that can self handle itself : I created the custom event just to call the handleedit function by passing the selected record ID from the list of challenge records in my component. From here we can start creating the dynamic components as required.

Ref: https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/events_component_fire.htm

4)Idea taken from this post (Aura Id of dynamic component is coming back as undefined) Aura:Id of dynamically created compontns cannot be accessed

5) A modal concept to mimic force:recordedit event (note I have created force:recordedit component and mimicked it to look like $A.get("e.force:editRecord") event)

http://www.sfdcmonkey.com/2017/04/15/modal-box-lightning-component-salesforce/

Now to the code

App:

<aura:application extends="force:slds">
    <c:forceeditsavesuccesscomp></c:forceeditsavesuccesscomp>
</aura:application>

Component: I have defaulted the task Id, you can use {!v.recordId} or however you want to populate the Id of the record. Used some SLDS html to mimic the modal like feeling.

<aura:component controller="AccountDevelopmentTaskController" access="global" implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId">
    <aura:registerEvent name="handleedit" type="c:handleeditevent"/>

    <aura:attribute name="challenges" type="Task[]" access="GLOBAL"/>
    <aura:attribute name="id" type="String" access="GLOBAL" default="00TB0000005p4cVMAQ"/>
    <aura:handler name="init" value="{!this}" action="{!c.start}"/>
    <aura:handler name="handleedit" event="c:handleeditevent" action="{!c.handleedit}" />
    <aura:handler name="onSaveSuccess" event="force:recordSaveSuccess" action="{!c.start}"/>

    <aura:attribute name="isOpen" type="boolean" default="false"/>

    <div class="slds-container--fluid">
        <table class="slds-table slds-table_bordered slds-table_cell-buffer">
            <thead>
                Subject
            </thead>
            <tbody>
                <aura:iteration var="chlng" items="{!v.challenges}">
                    <tr>
                        <th scope="row" data-label="Challenge">
                            <div class="slds-truncate slds-text-link" title="">
                                <div data-record="{!chlng.Id}" onclick="{!c.showEditPanel}">
                                    <ui:outputText value="{!chlng.Subject}" class="slds-text-link_reset" />
                                </div>
                            </div>
                        </th>
                        ...
                    </tr>
                </aura:iteration>
            </tbody>
        </table>
    </div>
    <aura:if isTrue="{!v.isOpen}">
    <div class="demo-only" style="height: 640px;">
        <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
            <div class="slds-modal__container">
                <header class="slds-modal__header">
                    <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close">
                        <span class="slds-assistive-text">Close</span>
                    </button>
                    <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Modal Header</h2>
                </header>
                <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                    {!v.body}
                </div>
            </div>
        </section>
        <div class="slds-backdrop slds-backdrop_open"></div>
    </div>
    </aura:if>
</aura:component>

Controller:

    ({
    start : function(component,event,helper) {
        var id = component.get("v.id");
        var action = component.get("c.loadChallenges");
        action.setParams({"tId":id});
        action.setCallback(this,function(response){
            var tasks = response.getReturnValue();
            component.set("v.challenges",tasks);
        });
        $A.enqueueAction(action);
    },

    showEditPanel : function(component,event,helper){
        var selectedItem = event.currentTarget;
        var recId = selectedItem.dataset.record;
        component.set("v.isOpen", true);        
        var compEvent = component.getEvent("handleedit");
        compEvent.setParams({
            "selectedId": recId
        }).fire();
    },
    handleedit: function(component,event,helper){
        /*createComponentController.js*/

        $A.createComponents([
            ["force:recordEdit",
             {
                 "aura:id": 'editrecord',
                 "recordId": event.getParam("selectedId")
             }],
            ["lightning:button",
             {
                 "aura:id" : 'savebutton',
                 "label": "Save record", 
                 "onclick": component.getReference("c.handlePress")
             }]
        ],
                            function(editcomp, status, errorMessage){
                                //Add the new button to the body array
                                if (status === "SUCCESS") {
                                    var editval = editcomp[0];
                                    var button = editcomp[1];
                                    var body = component.get("v.body");
                                    body.push(editval);
                                    body.push(button);
                                    component.set("v.body", body);
                                }
                                else if (status === "INCOMPLETE") {
                                }
                                    else if (status === "ERROR") {

                                    }
                            }
                           );
    },
    handlePress : function(component) {
        //component.find always comes back as undefined. Look at point 4.
        console.log('#######'+ component.find("editrecord"));
        component.find({ instancesOf : "force:recordEdit" })[0].get("e.recordSave").fire();
        component.set("v.isOpen", false);
        // the body was rendering differently on second click after saving the modal ( assuming this could be due the way the component's init is being handled by calling the start method, but as a dirty fix I used location.reload() to get back to original state)
        window.location.reload();

    }

})

Event:

<aura:event type="COMPONENT" description="Event template" >
    <aura:attribute Name="selectedId" type="String" access="global"/>
</aura:event>

controller:

//I am returning a bunch of tasks here, I am assuming you are passing a contact/account Id and gathering the tasks related to the selected record.Rewire this controller as required.

public class AccountDevelopmentTaskController {

    @AuraEnabled
    public static Task loadChallenges(id tId){
        return [select id,Subject from task where Id=:tId];
    }
}
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .