0

I try to close a dropdown menu and it's difficult for me. I manage to open the menu, to chose a currency and move the right label to the top of the div.

But how to close it by removing .expanded if I click anywhere (outside the div, on a label, on the top label) ? I also have to reopen if I click on the container (by toggling .expanded again)

var $container = $('.maincar__currency')
$container.click(function() {
  $(this).addClass('expanded');
});
$(".maincar__currency label").click(function() {
  $container.prepend($(this));
});
//$(document).click(function() {
//  $container.removeClass('expanded');
//});
.maincar__currency {
  display: flex;
  flex-direction: column;
  min-height: 32px;
  max-height: 32px;
  margin-left: auto;
  margin-bottom: 10px;
  overflow: hidden;
  border-radius: 6px;
  font-size: 14px;
}

input {
  display: none
}

.maincar__currency label {
  display: flex;
  width: 65px;
  height: 32px;
  padding: 6px;
  margin-right: 0 auto;
  text-align: center;
  cursor: pointer;
}

.maincar__currency label:first-child::after {
  content: "▾";
  margin-top: -1px;
  font-size: 15px;
}

.expanded {
  max-height: 132px;
  position: relative;
  right: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="maincar__currency" id="currency-drop-is">
  <label for="euro-radio-is">
        <div class="currency currency__euro">
          <input type="radio" name="currency-is" value="euro" id="euro-radio-is" class="euro_radio_is" checked>
          <span class="default">EUR</span>
        </div>
      </label>
  <label for="dollar-radio-is">
        <div class="currency currency__dollar">
          <input type="radio" name="currency-is" id="dollar-radio-is" class="dollar_radio_is" value="dollar">
          <span>USD</span>
        </div>
      </label>
</div>
lf_celine
  • 653
  • 7
  • 19

1 Answers1

1

When you add an onclick event on your label, it actually triggers twice, because of the "connection" you have added between label and input. Have a look at this example:

label {
  background:rgba(0,0,0,0.3);
}

input {
  position:absolute;
  left:10%;
  top:30px;
}
<label for="test">Click me, it will select checkbox</label>
<input type="checkbox" id="test"/>

Once you fix that problem, you need to attach a click handler on the document, that will check if the actual click contains your dropdown element, and if it doesn't it will close it.

$(".maincar__currency label input[type='radio']").on("click", function (event) {
    var $container = $(this).closest(".maincar__currency");
    if ($container.hasClass("expanded")) {
      $container.prepend($(this).closest("label"));
    }
    $container.toggleClass("expanded");
});
function handleDropdownClickOutside(e) {
  var $container = $(".maincar__currency");
  if (!$container[0].contains(e.target) && $container.hasClass("expanded")) {
    $container.removeClass("expanded");
  }
};

document.addEventListener("mousedown", handleDropdownClickOutside, false);
.maincar__currency {
  display: flex;
  flex-direction: column;
  min-height: 32px;
  max-height: 32px;
  /* margin-left: auto; */
  margin-bottom: 10px;
  overflow: hidden;
  border-radius: 6px;
  font-size: 14px;
  width: 64px;
}

input {
   display: none;
}

.maincar__currency label {
  display: flex;
  width: 100%;
  height: 32px;
  padding: 6px;
  margin-right: 0 auto;
  text-align: center;
  cursor: pointer;
}

.maincar__currency label:first-child::after {
  content: "▾";
  margin-top: -1px;
  font-size: 15px;
}

.expanded {
  max-height: 132px;
  position: relative;
  right: 0;
}

/* Visual purpose only: */

.maincar__currency {
  border:1px solid red;
}

.maincar__currency label {
  border:1px solid black;
}

.maincar__currency input {
  display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="maincar__currency" id="currency-drop-is">
  <label for="euro-radio-is">
    <div class="currency currency__euro">
      <input type="radio" name="currency-is" value="euro" id="euro-radio-is" class="euro_radio_is" checked>
      <span class="default">EUR</span>
    </div>
  </label>
  <label for="dollar-radio-is">
    <div class="currency currency__dollar">
      <input type="radio" name="currency-is" id="dollar-radio-is" class="dollar_radio_is" value="dollar">
      <span>USD</span>
    </div>
  </label>
</div>

So the way I did it, you only want to update/prepend the value, if the container has the .expanded class, otherwise clicking on the radio will open the dropdown.

dw_
  • 1,707
  • 1
  • 7
  • 13
  • Wow it's perfect, thank you so much ! I have another question. If I use two same dropdowns on the same page (The other is displayed when I wriite something in a search bar for example), can I just change the class of the second one and paste this code by modifying the variable ? It's a rhetorical question because it doesn't to work. – lf_celine Dec 05 '19 at 18:58
  • You can use the same function (no need to copy), and modify `handleDropdownClickOutside` to check through a list of elements, not just one. – dw_ Dec 05 '19 at 19:18