How to Create an Autocomplete Multi-Select Component with Next.js and NextUI

In modern web development, building intuitive and user-friendly UI components is crucial. One such component is an autocomplete multi-select dropdown, which allows users to select multiple options from a list. In this blog post, we will walk through how to build an autocomplete multi-select component using Next.js and NextUI. We’ll explore handling user input, filtering options, and managing selected items.

Prerequisites

Before we start, ensure you have the following setup:

  1. Next.js Project: You should have a Next.js project initialized. If not, you can create one using the following command:

     npx create-next-app my-nextjs-app
     cd my-nextjs-app
    
  2. NextUI Library: Install NextUI, which provides components like Input and Chip that we'll use in our project. Install it with:

     npm install @nextui-org/react
    

Component Overview

We will build an AutocompleteMultiple component that allows users to search and select multiple options from a dropdown list. The component will include:

  • Input Field: For user search input.

  • Dropdown List: Shows filtered options based on user input.

  • Selected Options Display: Shows selected items as chips.

Here is the step-by-step implementation of the component.

1. Setup the Component

First, create a new file for your component, e.g., AutocompleteMultiple.tsx. Import necessary modules and define the Option interface.

import { useState, ChangeEvent } from "react";
import { Input, Chip } from "@nextui-org/react";

interface Option {
  label: string;
  value: string;
}

const options: Option[] = [
  { label: "Apple", value: "apple" },
  { label: "Banana", value: "banana" },
  { label: "Orange", value: "orange" },
  { label: "Pineapple", value: "pineapple" },
  { label: "Strawberry", value: "strawberry" }
];

export default function AutocompleteMultiple() {
  const [selectedOptions, setSelectedOptions] = useState<Option[]>([]);
  const [inputValue, setInputValue] = useState<string>("");

2. Handle User Interaction

Define functions to handle selecting, removing, and input changes.

  const handleSelect = (option: Option) => {
    if (!selectedOptions.some((o) => o.value === option.value)) {
      setSelectedOptions([...selectedOptions, option]);
    }
    setInputValue(""); // Clear input after selection
  };

  const handleRemove = (option: Option) => {
    setSelectedOptions(selectedOptions.filter((o) => o.value !== option.value));
  };

  const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    setInputValue(event.target.value); // Extract value from event
  };

3. Filter Options

Filter the available options based on user input and ensure selected options are excluded from the dropdown list.

  const filteredOptions = options.filter(
    (option) =>
      option.label.toLowerCase().includes(inputValue.toLowerCase()) &&
      !selectedOptions.some((o) => o.value === option.value)
  );

4. Render the Component

Render the input field, dropdown list, and selected options display.

  return (
    <div>
      <Input
        name="q_list"
        placeholder="Type to search and select..."
        value={inputValue}
        onChange={handleInputChange} // Corrected this line
      />

      {/* Custom Dropdown List for Autocomplete */}
      {inputValue && (
        <div>
          {filteredOptions.map((option) => (
            <div
              key={option.value}
              style={{
                padding: "8px",
                cursor: "pointer",
                backgroundColor: "#f0f0f0",
                marginTop: "4px"
              }}
              onClick={() => handleSelect(option)}
            >
              {option.label}
            </div>
          ))}
        </div>
      )}

      <div style={{ marginTop: "10px" }}>
        {selectedOptions.map((option) => (
          <Chip
            key={option.value}
            onClose={() => handleRemove(option)} // Remove item from list
            color="primary"
            variant="flat"
            size="sm"
            style={{ margin: "0 5px 5px 0" }}
          >
            {option.label}
          </Chip>
        ))}
      </div>
    </div>
  );
}

Conclusion
The AutocompleteMultiple component we built demonstrates a practical approach to handling user input and selections in a multi-select autocomplete dropdown. By leveraging React hooks and NextUI components, we created a robust and user-friendly interface. With enhancements and customizations, you can adapt this component to fit various use cases and improve user experience in your applications.
0
Subscribe to my newsletter

Read articles from ByteScrum Technologies directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

ByteScrum Technologies
ByteScrum Technologies

Our company comprises seasoned professionals, each an expert in their field. Customer satisfaction is our top priority, exceeding clients' needs. We ensure competitive pricing and quality in web and mobile development without compromise.