[SalesForce] How to add onblur events in div tags in lightning component

I have a menu dropdown on click of filter icon. When I am done with applying filters, if user clicks outside menu dropdown, it should get closed. Can't apply onblur to any ui:input element as I want to add multiple values from filter and if onblur is added to any input element, the menu will close when I will go to add any other value due to onblur. Also, can't apply onblur event on lightning:buttonIcon for same reason. Hence, I want onblur event on div so that when user is done adding filter values, and clicks outside OR, just clicks on icon AND THEN click outside, the menu should close. But applying onblur on div has a drawback that when I click on any element INSIDE div, its getting closed.

How can I make this work?

Best Answer

@Sarang Try this.. i hope it solves your issue

toggleApplication :

<aura:application extends="force:slds">

    <aura:attribute name="ListOfItems" type="List" default="[1,2,3]"/>

    <aura:attribute name="index" type="String"/>
    <table>
        <tr>
            <th>
                Actions
            </th>
        </tr>
        <aura:iteration items="{!v.ListOfItems}" var="item" indexVar="index">
            <tr>
                <td>
                    <div aura:id="dropdown" class="slds-dropdown-trigger slds-dropdown-trigger--click">
                        <a data-index="{!index}" onclick="{!c.showAction}">
                            <lightning:icon iconName="utility:down" size="xx-small"/>
                        </a>
                        <div class="slds-dropdown slds-dropdown--left">
                            <ul class="slds-dropdown__list" role="menu">
                                <li class="slds-dropdown__item" role="presentation">
                                    <a href="javascript:void(0);" role="menuitem" data-index="{!index}" onclick="{!c.cloneSobjectRecord}">
                                        <span class="slds-truncate">Clone</span>
                                    </a>
                                </li>
                                <li class="slds-dropdown__item" role="presentation">
                                    <a href="javascript:void(0);" role="menuitem" data-index="{!index}" onclick="{!c.changeArchive}">
                                        <span class="slds-truncate">Archive</span>
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </td>
            </tr>
        </aura:iteration>
    </table>
</aura:application>

toggleAppController.js :

({
    showAction : function(cmp, event, helper) {
        helper.toggleDropdown(cmp,event);
    },
    cloneSobjectRecord : function(cmp,event,hepler){
        console.log("cloneSobjectRecord");
    },
    changeArchive : function(cmp,event,helper){
        console.log("Archive record");
    }
})

toggleAppHelper.js

    ({
    toggleDropdown : function(cmp,event){
        var index = cmp.get("v.index");

        if(index){
            this.closeDropdown(cmp,event);
        }

        var dropdown = cmp.find('dropdown');

        if(!Array.isArray(dropdown)){
            dropdown = [dropdown];
        }

        var index = event.currentTarget.getAttribute("data-index");
        cmp.set("v.index",index);
        $A.util.toggleClass(dropdown[index], 'slds-is-open');
        event.stopPropagation();
    },
    closeDropdown: function(cmp,event) {
        var dropdown = cmp.find('dropdown');

        if(!Array.isArray(dropdown)){
            dropdown = [dropdown];
        }

        var index = cmp.get("v.index");
        for(var i = 0; i < dropdown.length; i++){
            if(i != parseInt(index)){
                $A.util.removeClass(dropdown[index], 'slds-is-open'); 
            }
        }
    }
})

toggleAppRenderer.js :

({
    afterRender: function (cmp,helper) {
        this.superAfterRender();

        helper.windowClick = $A.getCallback(function(event){
            if(cmp.isValid()){
                helper.closeDropdown(cmp,event);
            }
        });
        document.addEventListener('click',helper.windowClick);      

    },
    unrender: function (cmp,helper) {

        this.superUnrender();
        document.removeEventListener('click',helper.windowClick);        
    }
})