The drop-down list unexpectedly closes at the most inconvenient moment

I am looking to create a search input with a drop-down list. The requirement is for the list to close when the focus or click is anywhere except the search input.

I have added a function listClose() to the "blur" listener, but now I am unable to capture the click event from the drop-down elements. What event listener do I really need for this functionality? Or should I consider a different approach?

Please try running the code snippet below, as I have tried to make it as clear as possible.

document.addEventListener("DOMContentLoaded", function() {
  var inputElement = document.getElementById("input_word-search");
  var listElement = document.getElementById("dd-menu_search-input");

  // Focusing on the input element when the document is ready.
  inputElement.focus();

  listOpen = function() {
    listElement.classList.add('dd-open');
  };

  listClose = function() {
    listElement.classList.remove('dd-open');
  };

  inputElement.addEventListener("focus", function(e) {
    listOpen();
  });

  inputElement.addEventListener("blur", function(e) {
    listClose();
  });
})
.dd-menu {
  padding: 8px 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 5px;
  box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
  position: absolute;
  display: none;
}

.dd-suggestion {
  cursor: pointer;
  text-align: left;
  padding: 3px 20px;
  line-height: 24px;
}

.dd-suggestion:hover {
  color: #fff;
  background-color: #697981;
}

.dd-open {
  display: block;
}

.dd-empty {
  display: none;
}

#dd-menu_search-input {
  width: 74%;
}
<body>

  <div id="input-group">
    <input id="input_word-search" class="input_search suggest__field" type="search" autocomplete="off" name="q" placeholder="Search">
    <div id="dd-menu_search-input" class="dd-menu dd-open">
      <div class="dd-dataset">
        <div class="dd-suggestion" onclick="alert('Click!')">
          suggestion-1
        </div>
        <div class="dd-suggestion" onclick="alert('Click!')">
          suggestion-2
        </div>
        <div class="dd-suggestion" onclick="alert('Click!')">
          suggestion-3
        </div>
        <div class="dd-suggestion" onclick="alert('Click!')">
          suggestion-4
        </div>
        <div class="dd-suggestion" onclick="alert('Click!')">
          suggestion-5
        </div>
      </div>
    </div>
  </div>

</body>

Answer №1

One way to address this issue (or perhaps a workaround) is by utilizing the onmousedown event instead of onclick. The modified version would appear as follows (Please note that I have replaced alert() with console.log()):

<body>

  <div id="input-group">
    <input id="input_word-search" class="input_search suggest__field" type="search" autocomplete="off" name="q" placeholder="Seach">
    <div id="dd-menu_search-input" class="dd-menu dd-open">
      <div class="dd-dataset">
        <div class="dd-suggestion" onmousedown="console.log('Click!')">
          suggestion-1
        </div>
        <div class="dd-suggestion" onmousedown="console.log('Click!')">
          suggestion-2
        </div>
        <div class="dd-suggestion" onmousedown="console.log('Click!')">
          suggestion-3
        </div>
        <div class="dd-suggestion" onmousedown="console.log('Click!')">
          suggestion-4
        </div>
        <div class="dd-suggestion" onmousedown="console.log('Click!')">
          suggestion-5
        </div>
      </div>
    </div>
  </div>

</body>

Answer №2

The issue arises when the textbox loses focus because it triggers the blur function, leading to the immediate disappearance of the list. This results in the inability to click on the list. A solution to this problem is implementing a workaround using setTimeout to execute the listClose() function in the following manner:

listClose = function() {
    setTimeout(()=>{
      listElement.classList.remove('dd-open');
    },100)
};

Answer №3

To ensure accurate tracking of mousedown events on the drop-down list, I implemented a boolean variable called "mousedownOnNodeCalee". This variable will be set to true when a mousedown event occurs on the list element.

    var mousedownOnNodeCalee = false;

    listElement.addEventListener("mousedown", function (e) {
        mousedownOnNodeCalee = true;
    });

    inputElement.addEventListener("blur", function (e) {
        if(!mousedownOnNodeCalee) {
            closeDropDownList();
            return;
        }
        inputElement.focus();
        mousedownOnNodeCalee = false;
    });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Automatically save user input in form fields with the help of jQuery and AJAX technology

I'm working on a form that has various input fields, and I need the data entered by the user to be automatically stored in the database every minute. After the user submits the request, it will be processed in a struts file where database interactions ...

Reset the queue for the slideDown animation using jQuery

I am experiencing an issue with my code where multiple animation effects are running simultaneously. Specifically, when I hover over navbarli1 and then move to another li element with the same navbarli1 class, the slide-down effect is not working as expect ...

Integrating Facebook login with Cordova using the cordovaOauth plugin

Encountering issues while setting up FB login for my cordova mobile app. A tutorial followed: http://www.codeproject.com/Tips/1031475/How-to-Integrate-Facebook-Login-into-a-Cordova-App#_comments <script src="js/angular.js"></script> <scrip ...

Understanding the concept of mutable properties in Typescript

Why can the property 'name' in the class 'PersonImpl' be reassigned even though it is not declared as read-only in the Person interface? interface Person { readonly name: string; } interface Greeting extends Person { greet( ...

Fade the current Div out and fade in the following Div while also animating its child element

Looking to achieve a fade in and out effect for 3 divs, with the child element animating its way up from the bottom right once the divs have faded in. I've been working on it but haven't made much progress, does anyone have any ideas? Check out ...

Identify unique MongoDb instances within an array of data

My list contains various unique items - search = alluk.distinct('Object of search') I am interested in counting each item individually. Presently, I am counting them manually in the following way - alluk.find({'Object of search':&ap ...

Where to begin with Angular materials?

Here is a snippet of my Angular materials test code: <div class="radioButtondemoBasicUsage" ng-app="MyApp"> <form ng-submit="submit()" ng-controller="AppCtrl"> <p>Selected Value: <span class="radioValue">{{ data.group1 }}< ...

When the enter key is pressed, scope.$watch() does not trigger, and location.path does not function as expected

I've encountered a peculiar problem with AngularJS that I need help with. Here's the situation: Using scope.watch to monitor text changes in a text field (searchloco). <input class="typeahead" ng-model="searchloco" data="{{varu}}" search-ba ...

Avoid using <input oninput="this.value = this.value.toUpperCase()" /> as it should not convert the text displayed on the "UI", rather it should send the uppercase value

<input oninput="this.value = this.value.toUpperCase()" type="text" id="roleName" name="roleName" class="form-control width200px" [(ngModel)]="role.roleName"> Even though the UI is changing ...

Testing an async function with Jest - Jest failed to exit within one second of completing the test

Looking to validate the functionality of my Next.js API functions using Jest along with node-mocks-http. The specific function I aim to test is as follows: export default async ( req: NextApiRequest, res: NextApiResponse ): Promise<void> => { ...

Error encountered with Content Security Policy while utilizing react-stripe

I am currently in the process of developing a React application that incorporates Stripe payments utilizing the @stripe/react-stripe-js (version "^1.9.0") and @stripe/stripe-js (version "^1.32.0") npm packages. While the payments are functioning correctly, ...

Unique 15-character code following email address

I've noticed a strange 15-character code that keeps attaching itself to the end of my outgoing emails. https://i.sstatic.net/tZdQo.png This mysterious code seems to change with each batch of emails I send out. Even though multiple emails sent in a l ...

Is it possible to upload numerous profiles into the MYSQL database using this WP template?

Apologies in advance if my question is unclear, but in simple terms, I am looking to automate the process of uploading hundreds of profiles and jobs to this WP template: The developer of this template has stated that it is not possible to do this through ...

The Art of CSS Arrangement

I'm experiencing an issue on my website PSR Is there a way to ensure that the Footer always appears below the content div automatically? Both the Content and the Footer have relative positioning. Additionally, how can I make the Footer the same siz ...

A function injected into a constructor of a class causes an undefined error

As I delve into learning about utilizing typescript for constructing API's, I have encountered a couple of challenges at the moment. Initially, I have developed a fairly straightforward PostController Class that has the ability to accept a use-case wh ...

What could be the reason for encountering the 'SyntaxError: Cannot use import statement outside a module' when trying to utilize the cloudinary module?

I am facing an issue while trying to utilize the Cloudinary module for resizing an image. Below is the code snippet I have: import cloudinary from 'cloudinary'; var cl = new cloudinary.Cloudinary({ cloud_name: "username", secure: true } ...

Having difficulty accessing the Material UI Icons

I encountered an issue when attempting to utilize Material UI icons - as soon as I added the icon component, an error occurred. https://i.stack.imgur.com/issmm.png For reference, you can find the code on CodeSandbox at the following link: https://codesand ...

The Pin property in GSAP is behaving unexpectedly when used in NextJS

I recently tried to learn gsap and wanted to create a smooth animation where I could scroll down a page and have a long word scroll horizontally and get pinned while scrolling using the scrollTrigger plugin of gsap. I followed a tutorial but ran into an is ...

The Json parsing failed to deserialize the API response

Struggling to send a JSON to my API, I've tried various solutions but still can't figure out what's going wrong. I'm stuck on this post call function: @PostMapping(path = "ts/sts") public void saveTestStep(@RequestBody Tes ...

displaying a div as a pop-up within an ASP.NET MVC 4 web application

One aspect of my asp.net MVC 4 application involves a partial view structured like so: <form class="qty-add" action="#" method="POST"> <label>Qty:</label> <div class="inp-controller"> <a href="#" c ...