thank_K
thank_K

Reputation: 71

Open menu on click close other menus

I have been working on getting a popup menu on a button. There are 7 buttons with this menu, on the page in different containers. So far you can click the button and the menu opens.

Each menu opens with its own version of this, which works but not efficient:

$('.country-btn-portugal').click(()=>{
      $(".dropdowna").toggleClass('active'); 
    });
 $('.country-btn-uk').click(()=>{
          $(".dropdowna").toggleClass('active'); 
        });

....etc... x7, one for each button menu.

I have tried to close the menu if an item is clicked but doesnt function with:

//close if menu <a> is clicked
    $('#mclose').click(()=>{ 
    $('.dropdown').removeClass('active');
    });

And using the following to close the menu if an item that is not this element is clicked (does not work):

$(document).mouseup(function (e)
{
    var container = $("#oclick");

    if (!container.is(e.target) // if the target of the click isn't the container...
        && container.has(e.target).length === 0) // ... nor a descendant of the container
    {
        container.hide();
    }
});

which i was hoping would also fix the issue when 1 menu is open and your next click is another menu, so you have both open.

The menu buttons will be serving separate divs (or card like boxes and are not siblings next to eachother. Hence finding it hard to compact the code. had to give each menu its own click functions.

it is a mess sorry. would be nice to see where im going wrong here.

fiddle --> https://jsfiddle.net/s4nk1zev/118/

html structure for one "card" with one "menu button".

 <div class="country_card">
        <span class="cc-t goth upperC">Portugal </span> <span class="cc-t goth upperC blued">Visa</span>
        <div class="cc-txt">
        text in here
        </div>
        <div class="cc-btn">            
            <button class="tablabel country-btn-portugal" id="portimg"></button>
            <div id="mcontainer" class="dropdowna">
                <a id="mclose" class="mclose" href="#home">Overview</a>
                <a id="mclose" href="#about">Application Process</a>
                <a id="mclose" href="#contact">Investment Options</a>
            </div>
        </div>      
    </div>   

Upvotes: 1

Views: 1817

Answers (3)

ufollettu
ufollettu

Reputation: 882

You can try using promise().done(), and reviewing the html class. This is a fiddle for you: https://jsfiddle.net/zxoLmf71/

using a promise on an element let you wait for the code to finish execution before start the new one. this is the code:

     //open menu
     const buttons = $('.country-btn');
     const dropDownMenus = $('.dropdownmenu');
     const dropDownItems = $('.dropDownItem')

     buttons.click(function() {
       dropDownMenus.removeClass('active');
       $(this).next('div').promise().done(function() {
         $(this).toggleClass('active');
       });
     });
     //close if menu clicked
     dropDownItems.click(function() {
       dropDownMenus.removeClass('active');
     });

Hope it helps

Upvotes: 0

Muhammad Usman
Muhammad Usman

Reputation: 10148

Well, this is how I would have done that.

Here is the updated fiddle

And this script would do enough

	     //open menu
		$('.tablabel').click(function(event){
      $('.tablabel').not(this).next().removeClass("active")
       $(this).next().toggleClass("active")
	     
	});
	 
	//close if menu clicked
	$(".dpd").click(function(e){
  
    $(this).toggleClass("active")
  })

	//close if anything  but menu clicked

What it does is, just listen for any click on the button and add active class to the next of it. Removing active class from all the active elements if there is any.

Secondly, you can use a class (as I've added one dpd) on the menue items to detect a click on them to close the open menu.

One more thing. Identifiers must be unique for each element you use. I've also updated them to be unique

Hope that helps

Upvotes: 1

David784
David784

Reputation: 7474

SInce your button and menu tags appear to always be siblings, if you add a common class to all your dropdowns, you can get a list of all of them more easily. Like this:

<div id="mcontainer" class="dropdown dropdowna">

Also as a suggestion, it's really not a very good idea to have duplicate ids in your document. It's against the html standard, and it can cause strange issues with getting tags by id.

Once you have a common class on all your dropdowns, you can do something like this to close all others, and toggle the one related to the button you're clicking.

function fnClick(e){
    var $dd = $(this).next();
    $('.dropdown').not($dd).removeClass('active');
    $dd.toggleClass('active');
}

//open menu
$('.country-btn-portugal').click(fnClick);
$('.country-btn-uk').click(fnClick);

here's an update of your fiddle to demonstrate: https://jsfiddle.net/s4nk1zev/143/

Upvotes: 0

Related Questions