0

I'm a total javascript newbie. I'm trying to create a search bar that appears when the user clicks on the search icon I've added to the topbar. I used this tutorial

I adapted the HTML markup to my needs, however, when I add the code below (same as in the tutorial), something seems to be going wrong.

// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {

  if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
  var openDropdown = dropdowns[i];
  if (openDropdown.classList.contains('show')) {
    openDropdown.classList.remove('show');
  }
}

The search bar appears when the user taps the icon, but if I try to select the search field to write something, it disappears. I checked, and I noticed the same behavior with the tutorial above (if you click one of the links inside the dropdown menu, the dropdown menu disappears).

I know it has something to do with the event target. Does anyone have any idea what should I change and where? The HTML markup is the same, with the exception that, instead of a dropdown menu, I added a search form.

Thank you!

RonyLoud
  • 2,408
  • 2
  • 20
  • 25
  • Possible duplicate of [Use jQuery to hide a DIV when the user clicks outside of it](http://stackoverflow.com/questions/1403615/use-jquery-to-hide-a-div-when-the-user-clicks-outside-of-it) – Yan Mayatskiy Dec 01 '16 at 12:31
  • Its working fine as in tutorial. Check this [fiddle](https://jsfiddle.net/pandeyvishal1986/y598xd5d/#&togetherjs=a0mpQAwpVc) – RonyLoud Dec 01 '16 at 12:33
  • your title is misleading, because you are trying to do the opposite, what is the class of your search box? – Yan Mayatskiy Dec 01 '16 at 12:33
  • @Yan Mayatskiy, I wouldn't say it's misleading. I'd like the search box to disappear when either the user clicks/taps the search icon (the same that triggers it to appear), or when the user taps outside the search box. The first one is easily achievable (and it's working nicely). However, the javascript provided in the tutorial isn't working for my purpose as the searchbox disappears when the user clicks the input field (and I don't want that). The class is "mobile-search". – Lucrezia van Necker Dec 01 '16 at 19:58

3 Answers3

0

This piece of code remove show class in every div that don't have dropbtn class.

you can do something like that

if (!event.target.matches('.dropbtn') && !event.target.matches('.searchBox')) {
  var dropdowns = document.getElementsByClassName("dropdown-content");
  var i;
  for (i = 0; i < dropdowns.length; i++) {
    var openDropdown = dropdowns[i];
    if (openDropdown.classList.contains('show')) {
      openDropdown.classList.remove('show');
    }
}

and add .searchBox class to your search box element, or change that to the class it already have.

Yan Mayatskiy
  • 353
  • 3
  • 12
0

event.target.matches is not working. Use this fiddle. May it Help!

JS:

/* When the user clicks on the button, 
toggle between hiding and showing the dropdown content */
function myFunction() {
    document.getElementById("myDropdown").classList.toggle("show");
}

// Close the dropdown menu if the user clicks outside of it
 window.onclick = function(event) {
  if (event.target.className.indexOf('dropbtn') == -1) {
    var dropdowns = document.getElementsByClassName("dropdown-content");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
      var openDropdown = dropdowns[i];
      if (openDropdown.classList.contains('show')) {
        openDropdown.classList.remove('show');
      }
    }
  }
}
RonyLoud
  • 2,408
  • 2
  • 20
  • 25
0

None of the above worked for me, so I ended up putting together a solution myself. I replaced the javascript with the jQuery below.

This is to toggle between slideUp and slideDown when the user clicks on the search icon:

$( "#mobile-search-ico" ).click(function() {
  $( ".mobile-search-inner" ).slideToggle(400);
});

This is to toggle slideUp when the user clicks outside of the search box:

$(document).mouseup(function (e)
{
    var container = $(".mobile-search-inner");

    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.slideUp(400);
    }
});

$("#mobile-search-ico").click(function() {
  $(".mobile-search-inner").slideToggle(400);
});
$(document).mouseup(function(e) {
  var container = $(".mobile-search-inner");

  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.slideUp(400);
  }
});
form#menu-mobile-search-main {
  width: 97.6%;
  margin-right: auto;
  margin-left: auto;
}
input.menu-mobile-searchform-main {
  border: 1px solid #000 !important;
  background: #fff !important;
  font-family: "classico-urw" !important;
  color: #000 !important;
  font-size: 13px !important;
  height: 37.33px !important;
  padding: 10px !important;
  padding-right: 47px !important;
  margin: 0 !important;
}
input.menu-mobile-searchform-main:focus,
button.mobile-search-submit-main:focus {
  outline: none !important;
}
button.mobile-search-submit-main {
  background: #fff;
  border: none;
  padding: 0px;
  position: absolute;
  top: 15.5px;
  right: 20px;
}
i.mobile-search-submit-icon {
  font-family: 'cj-icons' !important;
  font-size: 17px;
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  display: inline-block;
  line-height: 1;
  letter-spacing: 0;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  -webkit-font-feature-settings: "liga";
  -moz-font-feature-settings: "liga=1";
  -moz-font-feature-settings: "liga";
  -ms-font-feature-settings: "liga" 1;
  font-feature-settings: "liga";
  -webkit-font-variant-ligatures: discretionary-ligatures;
  font-variant-ligatures: discretionary-ligatures;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #000;
  cursor: pointer;
}
.mobile-search-inner {
  position: fixed;
  left: 0px;
  width: 100%;
  top: 49px;
  right: auto;
  background: #fff;
  height: 47.5px;
  padding-top: 5.083px;
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div class="mobile-search-relative">
  <div id="mobile-search" class="mobile-search"><i id="mobile-search-ico" class="mobile-search-ico">ICON</i>
    <div id="mobile-search-show" class="mobile-search-inner">
      <div class="mobile-search-hide">
        <form id="menu-mobile-search-main" role="search" method="get" action="<?php echo home_url( '/' ); ?>">
          <input type="text" value="" name="s" placeholder="" class="menu-mobile-searchform-main">
          <button type="submit" rel="nofollow" class="mobile-search-submit-main"><i class="fa fa-search"></i>
          </button>
        </form>
      </div>
    </div>
  </div>
</div>

Note: The search icon that toggles the search box was created using linea icon font, and the search button was created using FontAwesome. I wasn't sure how to add those here, so I've left them out. "ICON" replaces the search icon (not button). Also, the styling is a bit different.