Wednesday, 10 July 2019

Display "mini page layout" on hover in Lightning Component

Requirement:
There was a requirement, while working with one of the clients, to provide an interface which would display mini page layout on hover of the Lightning component. This layout had to be customized and shown on MouseHover of the Contact object field.

Challenge: 

In Lightning, the mini page layout is only available for the fields which have a lookup or have a master-detail relationship. There is no out-of-the-box (OOTB) functionality available to display linked record field values in the pop-up in lightning component.

Solution:

To overcome this limitation, we developed a custom solution which involved creating an apex class called ContactsController. This class contains the mechanism to retrieve the list of contacts along with related accounts. This class is used by Custom Lightning Component to display the list of contacts with a pop-up functionality.


ContactsController class

public class ContactsController {
    @AuraEnabled
    public static List <contact> getContacts() {
        return [SELECT Id, name,phone, Contact.account.Name, Contact.account.industry, Contact.account.Type,
                Contact.account.Phone  FROM contact ORDER BY createdDate ASC];
    }
}

ContactsController class is referenced by MouseHover component to display retrieved contacts as a data table and use JavaScript Controller to illustrate contacts only from the list.

MouseHover.cmp

<aura:component controller="ContactsController">
    <aura:attribute name="contacts" type="List" />
    <aura:attribute name="conAccLst" type="List" />
    <aura:attribute name="reId" type="Id" />
    <aura:attribute name="mouseHoverData" type="object" />
    <aura:attribute name="togglehover" type="boolean" default="false"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="hoverRow" type="Integer" default="-1" />
    <!-- Use a data table from the Lightning Design System: https://www.lightningdesignsystem.com/components/data-tables/ -->
    <table class="slds-table slds-table_bordered slds-table_striped slds-table_cell-buffer slds-table_fixed-layout">
        <thead>
            <tr class="slds-text-heading_label">
                <th scope="col"><div class="slds-truncate" title="Name" style="text-align: center">Contact Name</div></th>
                <th scope="col"><div class="slds-truncate" title="Phone" style="text-align: center">Phone</div></th>
            </tr>
        </thead>
        <tbody>
            <!-- Use the Apex model and controller to fetch server side data -->
            <aura:iteration items="{!v.contacts}" var="contact" indexVar="index">
                <tr data-selected-Index="{!index}">
                    <td><div class="slds-truncate" title="{!contact.Name}" style="text-align: center">
                        <a id="{!contact.Id}" onmouseenter="{!c.handleMouseHover}" onmouseout="{!c.handleMouseOut}" data-index="{!index}" tabindex="-1">{!contact.Name}</a></div>
                        <aura:if isTrue="{!v.hoverRow==index}">
                            <aura:if isTrue="{!v.togglehover==true}">
                                <div   class="slds-popover slds-nubbin_bottom"
                                     role="tooltip" id="help" style="position: absolute; right: 225px; bottom: 100%; width: 22rem; padding: inherit;">
                                    Account Name: {!v.mouseHoverData.Name}<br/>
                                    Phone:{!v.mouseHoverData.Phone}<br/>
                                    Type:{!v.mouseHoverData.Type}<br/>
                                  
                                </div>
                            </aura:if>
                        </aura:if>
                    </td>
                    <td><div class="slds-truncate" title="{!contact.Phone}" style="text-align: center">{!contact.Phone}</div></td>
                </tr>
            </aura:iteration>
        </tbody>
    </table>
</aura:component>

MouseHoverController.js retrieves all contacts on the load event of MouseHover Component and call MouseHoverHelper javascript file on hover of any contact name to display a pop-up with related account details.

MouseHoverController.js


({
    doInit: function(component, event, helper) {
        // Fetch the Contact list from the Apex controller
        helper.getAccountList(component);
    },
    handleMouseHover: function(component, event, helper) {
        var my = event.srcElement.id;
        component.set("v.reId",my);
        helper.getMiniLayout(component, event, helper)
    },
    handleMouseOut: function(component, event, helper) {
        component.set("v.hoverRow",-1);
        component.set("v.togglehover",false);
    }
})

MouseHoverHelper fetches the related account details as a pop-up on hover of a contact name.

MouseHoverHelper.js 


({
    // Fetch the Contact from the Apex controller
    getAccountList: function(component) {
        var action = component.get('c.getContacts');
        // Set up the callback
        var self = this;
        action.setCallback(this, function(actionResult) {
            var result = actionResult.getReturnValue();
            component.set('v.contacts', result);
            var conAccList = [];
            for(var i=0 ; i<result.length;i++){
                conAccList.push({"Id":result[i].Id, "value":result[i]});
            }
            component.set('v.conAccLst', conAccList);
        });
        $A.enqueueAction(action);
    },
    //Fetch the releted account on mouseHover 
    getMiniLayout:function(component, event, helper){
        
        var getAccount = component.get('v.conAccLst');
        for(var i=0;i<getAccount.length;i++){
            if(getAccount[i].Id == component.get("v.reId")){
                component.set('v.mouseHoverData', getAccount[i].value.Account);
                break;
            }
        }
        component.set("v.hoverRow", parseInt(event.target.dataset.index));
        component.set("v.togglehover",true);
    }
})

After this, we have created a Lightning App to integrate all of the files as a solution

Sample.app 

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


Output :



If you have any questions you can reach out our Salesforce Consulting team here.