1

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?

2 Answers 2

6

@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);        
    }
})
1
  • thanks for the answer, but with this was somehow not working for me. Also, the event listner was always there so it was a bit risky. So I added following code as below, though marking your's best as that gave the idea :) :
    – Sarang
    Mar 10, 2017 at 12:02
1

Component:

<div aura:id="dropdown" class="{!'slds-dropdown-trigger slds-dropdown-trigger--click ' + (v.isFilterClosed ? 'slds-is-closed': 'slds-is-open')}">
        <lightning:buttonIcon aura:id="filterIconID" iconName="utility:filterList" variant="container" alternativeText="filterList" class="slds-button" onclick="{!c.onFilterClick}"/>
        <div class="slds-dropdown slds-dropdown--right slds-nubbin--top-right slds-p-around--small" style= "top : 35px" onfocus="{!c.giveFocus}">
        <!-- furthur code-->

Helper:

closeDropdown : function(component){
        component.set('v.isFilterClosed', true);
    }

Renderer:

({

    afterRender : function( component, helper ) {
        this.superAfterRender();
        console.log('INSIDE AFTER RENDERER');
    },

    rerender : function( component, helper ) {
        this.superRerender();
        console.log('INSIDE Re-Renderer');
        helper.windowClick= function(e) {
            if(e.target.toString().includes('HTMLDivElement')) {           //If its normal div element, close drodown
               helper.closeDropdown(component);  
               document.removeEventListener('click',helper.windowClick);   //Remove event listner so that it doesn't interfere in other clicks in remaining document
            } 
            else{
                 //do nothing, helper methods will handle click of icon
            }
        }
        document.addEventListener('click',helper.windowClick);
    }
})

You must log in to answer this question.

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