I'm new to using lightning and am writing a component that overrides a custom object detail button. I'm able to successfully override the detail view with my component using: <force:recordView recordId="{!v.recordId}" type="FULL"/>
I have two buttons that I have added, which call action methods in my apex controller. Each button returns a record id that I will use to navigate to when the methods are executed.
My question, is how can I pass a value to my action method from the recordView?
Here is my component:
<aura:component implements="lightning:actionOverride,force:hasRecordId,force:hasSObjectName" controller="SSOViewOverrideController" access="global">
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<div class="slds-card">
<div class="slds-m-around--xx-large">
<div class="slds-form--stacked">
<div class="slds-m-around--medium">
<button class="slds-button slds-button--brand" onclick="{!c.gotoContact}">Go To Contact</button>
<button class="slds-button slds-button--brand" onclick="{!c.createCase}">Create Case</button>
</div>
</div>
</div>
<lightning:recordEditForm recordId="{!v.recordId}" objectApiName="SSO__x" />
</div>
</aura:component>
Here is my component controller:
({
doInit: function(cmp) {
var navEvt = $A.get("e.force:navigateToSObject");
navEvt.setParams({
"recordId": cmp.get("v.recordId"),
"slideDevName": "detail"
});
navEvt.fire();
},
gotoContact: function(cmp) {
var action = ccmp.get('c.getContact');
action.setParams({ guidId : cmp.get("v.guid__c") });
},
createCase: function(cmp) {
}
})
Here is my apex controller action method:
@auraEnabled
public static Id getContact(string guidId) {
Id retval;
Contact[] cList = CreateCaseContactUtil.searchContactByGUID(guidId);
if(cList.size() > 0) {
retval = cList[0].Id;
}
return retval;
}
I need to pass the record field value guid__c
into my apex controller action method, which returns a contact Id that I will then want to navigate to that record when the button is clicked.
The recordView is showing the guid__c
value on the page, but have not been able to pass it to my action method and get the id back to navigate to contact record.
Best Answer
If I am reading your implementation right, then you have got few things wrong here in your implementation. You are not really viewing what is in your component, rather when your component is initialized, you are actually redirecting the flow using
force:navigateToSobject
in yourdonInit
function to the record id mentioned in the function. So you never are in your component.Going back to
force:recordView
, it is a read only representation and does not let you to fetch any further details on the rendered layout viz., fetch specific field values from the view. Though you will have access to the body of the component, but traversing through it to find a field's value will be more cumbersome. If you refer to the documentation, it mentions as below.As for your issue of passing a value from your view to the controller, you have got couple of options.
Option 1 - Modification in your current implementation
Assuming that you want a detail layout using
force:recordView
, you can make a server call in yourdoInit
function to fetch the guid field and populate it on your component. And then when you click the button, use this field's value to pass on to apex controller. Your code will look something like this:Attribute declaration on component:
In your existing doInit, modify it as:
And in your apex controller:
Now you have guid available with your component as an attribute on it, which you can use anywhere in any of the JS function.
So when you click the button, you can fetch the guid in your JS function:
Using this approach, you are using recordView along with a bit of your customization. However note that this may not be most efficient way as this approach is actually making a server trip twice, once for loading the fields with record view and then in your doInit function. But with this approach you easily achieve the detail layout functionality without writing anything around how to render the fields.
Option 2 - Implement using lightning:recordEditForm
With this approach, you will need to write all your fields which you want to display on the page. You can use lightning:inputField with some styling to make it read only, so that it aligns with detail layout, associate the input fields with an aura:id and then retrieve the values in your JS function. You can find more details using lightning:recordEditForm and how to fetch values from it in JS function in this answer here.