How to choose an option from a dropdown menu using React

In a React application, I am creating a straightforward autocomplete feature. The code is outlined below.

index.js

import React from 'react';
import { render } from 'react-dom';
import Autocomplete from './Autocomplete';

const styles = {
  fontFamily: 'sans-serif',
  textAlign: 'left',
};

const items = ['Moscow', 'Ufa', 'Tver', 'Alma ata'];

function onAutoCompleteHandle(val) {
  alert(val);
}

const App = () => (
  <div style={styles}>
    <Autocomplete items={items} onAutocomplete={onAutoCompleteHandle.bind(this)}/>
  </div>
);

render(<App />, document.getElementById('root'));

autocomplete.js

Show Suggest Method:

const showSuggest = {
      display: this.state.show ? 'block' : 'none',
    }
    return (
      <div>
      <input type="text" 
        className="autoCompleteInput"
        onChange={this.handleChange}
        ref={input => { this.textInput = input; }} 
        onClick={this.handleClick}
        onKeyPress={this.handleKeyPress}
      />
      <span className='suggestWrapper' style={showSuggest}>
          <ul className='suggestAutocomplete'>
          {this.state.items.map((item, i) => {
            return 
            <li key={i} onClick={this.selectSuggestion}>
              {item}
            </li>
          })}
        </ul>
      </span>
      </div>
    )

For a complete working demonstration, visit: https://codesandbox.io/s/react-autocomplete-nbo3n

To reproduce the issue in the provided sandbox example:

-> Click inside the input box.

-> Type a single alphabet such as, a.

-> This will prompt two results: Ufa, Alma ata.

-> Press the down arrow key on your keyboard.

Despite attempting to navigate with the keyboard, it is not possible to select any of the dropdown items.

The current functionality only allows for mouse selection, which means that there is a need to incorporate keyboard navigation and selection using keys like the arrow keys and enter key.

Expected Behavior:

-> Users should be able to navigate through the dropdown list using the keyboard.

-> Selecting an item by pressing the enter key should highlight it.

I have attempted assigning

ref={input => { this.textInput = input; }}
to the ul list items suggestAutocomplete, but this did not resolve the issue.

I have been struggling with this problem for quite some time. Any assistance or modifications to the existing code that enable both mouse and keyboard selection within the autocomplete feature would be greatly appreciated.

Answer №1

  1. Begin by setting the state to -1

  2. Create an event listener for keyDown

Here is an example code snippet:

handleKeyDown(e) {
  if (e.keyCode == 40) { //down
    this.setState({active: ++this.state.active})
  } else if (e.keyCode == 38) { //up
    this.setState({active: --this.state.active})
  } else if (e.keyCode == 13) { //enter
    e.preventDefault();
    if (this.state.active > -1) {
      this.selectSuggestion();
    }
  }
};
  1. Upon clicking, reset the state back to -1.

Take a look at this resource: https://codesandbox.io/s/react-autocomplete-cf2yd

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

What's the process for browsers to render the 'span' element?

<p> <span>cancel</span><span>confirm</span> </p> <hr> <p> <span>cancel</span> <span>confirm</span> </p> Both should display the same result. However, in the ...

How can animations be disabled in Angular/Javascript?

I have been assigned the task of developing an Angular component for my company's applications that will include a toggle to disable all animations within the app for accessibility purposes. It is important to note that I am unable to go into each in ...

Troubleshooting issues with AJAX script and JSON formatted data

Here is my complete script: <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/E ...

implementing the CSS property based on the final value in the loop

I have created multiple divs with a data-line attribute. I am trying to loop through each div, extract the individual values from the data-line attribute, and apply them as percentages to the width property. However, it seems to only take the last value an ...

Learn how to set a global background color by utilizing MuiCssBaseline along with styleOverrides

I am trying to implement a global background color for my app using ThemeProvider, but I am encountering a strange issue that I cannot seem to resolve. In the image below, you can see that the body component is not extending to cover all the components in ...

Is it advisable to incorporate vue-resource in Vuex actions?

I am currently working on a web application that retrieves airport data from the backend. To manage states and data sharing, I am utilizing Vuex. My dilemma is whether to load the airports in my Vuex actions or within a method of my Vue instance which will ...

Tips for enabling auto-scroll feature in MuiList

Currently, I am working on a chat window component that utilizes Material UI for styling. I expected that setting a height or max-height on either the MuiList or MuiBox encapsulating the list would automatically scroll to the new message when it's sen ...

Determine the week number based on a specified starting day for the week

If I have a custom week start day other than Monday, how should the getWeekNumber() prototype for the Date class be modified? Here is the existing code for calculating the ISO Week Number: Date.prototype.getWeekNumber = function() { // Create a dupli ...

Attempting to add additional content in the "prepareHeaders" method within React Toolkit Query

After spending a considerable amount of time struggling with a problem, I've turned to seeking help here. The issue revolves around populating the extra property of the prepareHeaders function, and I'm unsure about where to define it. I've ...

Having trouble with Selenium and Java when sending keys to a text field - no errors though

I am currently using Selenium with Java in Eclipse for automating test cases on a website as a way to improve my skills. Below is the HTML code snippet. https://i.sstatic.net/I2lCP.jpg My project is set up using Page Object Model in Maven, however, I am ...

Running nodejs scripts within my HTML and JavaScript code

Using express, I send an HTML file to incoming GET requests: app.get('/', function(req, res) { res.sendFile(path.join(__dirname + '/public/index.html')); }); Within that HTML file, I included another JavaScript file, script.js, us ...

Is Apache required for running NodeJs?

Recently, I set up a web project on my local machine following a tutorial. With the help of XAMPP, I was able to install MySQL and Apache to run my Node.JS backend. Now, I'm looking into hosting the project on an external server to make it accessible ...

Navigate to a different page using an AJAX request

Is it possible to use ajax for redirecting to another page? Here's the code I've been working on: <script type="text/javascript"> $(document.body).on('click', '#btnPrintPrev', function() { $.ajax({ url: &apo ...

How can I combine multiple textures from mtlLoader and objLoader in three.js?

I have the files .mtl, .obj, and several .jpg textures. I have been attempting to use different textures in the export loader OBJ, and while I can see my object on the scene, it appears as a black color. Can anyone spot what might be incorrect or missing ...

To redirect to a webpage in PHP, incorporate nested if statements and override the meta HTML

I am looking for a way to automatically redirect to another webpage when a certain condition is met. Currently, I have set up a meta redirect in case the condition is not satisfied. <meta http-equiv="refresh" content="4; url=form3.html" /> <?ph ...

"Interactive jQuery feature allows users to edit table content live with the ability to update and delete data via

I am working on implementing live editing, updating, and deleting functionality in a table using jQuery. However, I have encountered two problems: When clicking the pen icon from order #3 to #1, it requires 3 clicks, but when clicking from order #1 to ...

Adding a custom class to the body element for specific routes in Next.js can be achieved by utilizing the features of

I am looking to apply my custom class to certain pages, with the exception of specific routes. For example, all pages should have the class fixed-header, except for the following routes: /cart/step-1 /login This class should be added or removed from the ...

Tips for utilizing CSS flexbox to create a row of squares that can scale while maintaining their aspect ratios

Struggling with this issue has me on the verge of pulling my hair out. It seems like a simple task, yet I can't seem to achieve perfection. My goal is to create a row of squares that maintain their aspect ratio but scale down in size as their containe ...

The partition.nodes(root) function in d3.js does not assign values to the x or dx properties of the nodes

I am currently experimenting with d3.js to create a unique icicle tree visualization using data sourced from a .json file. The challenge I'm facing lies in the fact that the x and dx attributes of the partition nodes are consistently being set to 0. M ...

Setting a value programmatically in a Material-UI Autocomplete TextField

In my React application, I am using material-ui Autocomplete and TextField components to allow users to select values from a dropdown list. However, I am looking for a way to programmatically set the input value by clicking a button, without having to choo ...