Open Report in New Window on Record Page In Lightning

We can open report in new window from record page in lightning Experience. We will pass report id 00O0K00000B0Egn from ShowReport.cmp.

In NavigateToReport.cmp we will get record details of current page. We can fetch any fields on record using force:recordData.

In controller, we can form url to navigate and pass paramters to filter values.

We can open report in new window using,
window.open(url ,'_blank','toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width='+ w +'px,height='+ h +'px,top=50px,left=100px');

After this we will close modal using force:closeQuickAction.

We need to create quick action to call ShowReport.cmp on record page button. Don't forget to add quick action in Mobile & Lightning Actions section in page layout.

Loading Records - Make a record available for your UI components is to load it. Load the record by including force:recordData in your component while specifying the recordId, mode, and layoutType or fields attributes.

targetRecord - targetRecord is populated with the current record, containing the fields relevant to the requested layoutType or the fields listed in the fields attribute. targetFields is populated with a simplified view of the loaded record. For example, for the Name field, v.targetRecord.fields.Name.value is equivalent to v.targetFields.Name.

recordUpdated - force:recordData loads data asynchronously by design since it may go to the server to retrieve data. To track when the record is loaded or changed, use the recordUpdated event

Cmp Name: NavigateToReport.cmp

<aura:component extensible="true" >

    <aura:attribute name="reportId" type="String" />

    <aura:attribute name = "record" type="Object"/>

    <force:recordData aura:id="recordLoader"

                      recordId="{!v.recordId}"

                      layoutType="FULL"

                      targetRecord="{!v.record}"

                      recordUpdated="{!c.recordLoaded}" />

</aura:component>

JS Controller: NavigateToReportController.js

({

    recordLoaded: function(component, event, helper) {

        var eventParams = event.getParams();

        if(eventParams.changeType === "LOADED") {

            var record = component.get("v.record");

            var parentId = record.fields.ParentId.value;

            var url = '/one/one.app#/sObject/'+component.get("v.reportId") + '/view?';

            //fv0 and fv1 are filter values in report

            if(parentId != undefined){

                url += 'fv0='+ parentId +'&fv1='+parentId;

            }else{

                var recordId = component.get("v.recordId");

                url += 'fv0='+recordId+'&fv1='+recordId;

            }

            var h = screen.height-200;

            var w = screen.width-200;

            //https://www.w3schools.com/js/tryit.asp?filename=tryjs_openallwindow

            window.open(url ,'_blank','toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width='+ w +'px,height='+ h +'px,top=50px,left=100px');

            setTimeout(

                function() {

                    $A.get("e.force:closeQuickAction").fire()

                }, 3000);

        }else if(eventParams.changeType === "ERROR") {

            component.find('recordLoader').reloadRecord(true);

        }

    }

})

Aura:set - <aura:set > is use to set the value of an attribute inherited from a parent component, event or to set the value of attribute of a component reference.

Here, NavigateToReport.cmp is parent component and ShowReport.cmp is child component

Cmp Name: ShowReport.cmp

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

 <aura:set attribute="reportId" value="00O0K00000B0Egn"/>

</aura:component>

Show different reports on different button without using hard coded ids    

Cmp Name: ShowReport.cmp

<aura:component extensible="true" controller="ShowReportController">
    <aura:attribute name="reportDeveloperName" type="String" />
    <aura:attribute name = "record" type="Account"/>
    <aura:attribute name = "isShowMessage" type="boolean" default="false"/>
    <aura:attribute name = "errorMessage" type="String" default=""/>

    <aura:handler name="init" value="{!this}" action="{!c.doInIt}"/>
    <aura:if isTrue="{!v.isShowMessage}">
        <div class="slds-card toastMessage slds-text-heading_medium" style="background-color:#c23934;color:white;">
            <h2 class="message"><b>{!v.errorMessage}</b></h2>
        </div>
    </aura:if>
</aura:component>

JS Controller: NavigateToReportController.js

({
    doInIt: function(component, event, helper) {
        helper.doInIt(component, event, helper);
    }
})

Helper : NavigateToReportController.helper

({
    doInIt : function(component,event,helper){
        var action = component.get("c.getAccountAndReportId");
        action.setParams({  recordId: component.get("v.recordId"),reportName:component.get("v.reportDeveloperName")});
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var returnResponse = response.getReturnValue();
                var parentId =returnResponse.account.ParentId;
                var reportId  = returnResponse.reportId;
                var url = '/one/one.app#/sObject/'+reportId + '/view?';
                if(parentId != undefined){
                    url += 'fv0='+ parentId +'&fv1='+parentId;
                }else{
                    var recordId = returnResponse.account.Id;
                    url += 'fv0='+recordId+'&fv1='+recordId;
                }
                var h = screen.height-200;
                var w = screen.width-200;
                window.open(url ,'_blank','toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width='+ w +'px,height='+ h +'px,top=50px,left=100px');
                setTimeout(
                    function() {
                        $A.get("e.force:closeQuickAction").fire()
                    }, 3000);
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        component.set("v.isShowMessage",true);
                        component.set("v.errorMessage",errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        $A.enqueueAction(action);
    }
});

Apex Controller : ShowReportController

public with sharing class ShowReportController {    @AuraEnabled    public static ShowReportWrapper getAccountAndReportId(Id recordId, String reportName){        ShowReportWrapper showReportWrapper = new ShowReportWrapper();        Account account = [Select Id,ParentId from Account where Id = :recordId Limit 1];        showReportWrapper.account = account;        List<Report> reports = [Select Id,Name,DeveloperName from Report where DeveloperName = :reportName Limit 1];        if(reports.isEmpty()){            throw new AuraHandledException('ERROR : Report Not found.');        }        showReportWrapper.reportId =reports.get(0).Id;        return showReportWrapper;    }
    public class ShowReportWrapper {        @AuraEnabled public String reportId;        @AuraEnabled public Account account;        public ShowReportWrapper(){}    }}

Cmp Name: NavigateToReport.cmp

    <aura:set attribute="reportDeveloperName" value="Corporate_Roll_Up_Reports_AMIs_Lex" />
</aura:component>                                                                                                                                                           



Comments

Popular posts from this blog

Syncing And Unsyncing Quote With Opportunity Using Flow And Process Builder