34 - Search Bar with Filtering and Suggestions

Description

Develop a React component for searching, filtering, and displaying data, with dynamic suggestions.

  • Allows users to enter search terms.

  • Provides real-time search suggestions based on entered text.

  • Filters displayed data based on the search term and additional filters (optional).

  • Displays relevant suggestions and filtered results clearly.

Algorithm

  1. Component Structure:

    • Define a functional component named SearchBar.

    • Accept props for:

      • data: Array of data items.

      • filterOptions: Object defining available filters (optional).

      • onSelectSuggestion: Function to handle suggestion selection.

      • onFilterChange: Function to handle filter changes (optional).

    • Maintain internal state for:

      • searchTerm: Entered search text.

      • suggestedItems: Array of suggested data items.

      • filteredItems: Array of filtered data items (optional).

      • selectedFilter: Currently selected filter value (optional).

  2. Search and Suggestions:

    • Use a useEffect hook to update suggestions based on searchTerm changes.

    • Filter the data based on the search term and filter selection (if applicable).

    • Limit the number of displayed suggestions for performance.

  3. Filter Handling (optional):

    • Render filter options and handle user selections.

    • Update the selected filter state (selectedFilter) and re-filter the data accordingly.

  4. Rendering:

    • Render the search input field with suggestions dropdown (conditionally).

    • Display the filtered data items below the search bar.

    • Style the search bar, suggestions, and filter options for desired UI.

Code

import React, { useState, useEffect } from 'react';

const SearchBar = ({ data, filterOptions, onSelectSuggestion, onFilterChange }) => {
  const [searchTerm, setSearchTerm] = useState('');
  const [suggestedItems, setSuggestedItems] = useState([]);
  const [filteredItems, setFilteredItems] = useState(data); // or [] if optional

  useEffect(() => {
    const filteredData = data.filter((item) =>
      item.name.toLowerCase().includes(searchTerm.toLowerCase())
    ); // Replace `.name` with your data access path

    if (filterOptions && selectedFilter) {
      // Include filter logic only if filter options are provided
      setFilteredItems(filteredData.filter((item) => item.type === selectedFilter));
    } else {
      setFilteredItems(filteredData);
    }

    const suggestions = filteredData.slice(0, 5); // Limit suggestions for performance
    setSuggestedItems(suggestions);
  }, [searchTerm, selectedFilter]);

  const handleInputChange = (event) => {
    setSearchTerm(event.target.value);
  };

  const handleSuggestionClick = (item) => {
    // Use item data based on your implementation
    setSearchTerm(item.name);
    onSelectSuggestion(item); // Call prop function if needed
  };

  const handleFilterChange = (filter) => {
    // Optionally implement filter selection logic if provided
    setSelectedFilter(filter);
    if (onFilterChange) onFilterChange(filter);
  };

  return (
    <div className="search-bar">
      <input
        type="text"
        placeholder="Search..."
        value={searchTerm}
        onChange={handleInputChange}
      />
      {searchTerm && (
        <ul className="suggestions">
          {suggestedItems.map((item) => (
            <li key={item.id} onClick={() => handleSuggestionClick(item)}>
              {item.name}
            </li>
          ))}
        </ul>
      )}
      {filterOptions && (
        <select onChange={(event) => handleFilterChange(event.target.value)}>
          <option value="">All</option>
          {Object.keys(filterOptions).map((key) => (
            <option key={key} value={key}>
              {filterOptions[key]}
            </option>
          ))}
        </select>
      )}
      <ul className="results">
        {filteredItems.map((item) => (
          <li key={item.id}>{item.name}</li> // Use item data as needed
        ))}
      </ul>
    </div>
  );
};

export default SearchBar;

Explanation

  • State Management: searchTerm, suggestedItems, filteredItems, and selectedFilter (optional) are used to track search progress and data.

  • Search and Suggestions: useEffect updates suggestions based on searchTerm changes and filters data accordingly.

  • Filter Handling (optional): Filter options and selection logic are included if filterOptions prop exists.

  • Rendering: Search bar, suggestions dropdown, and filtered results are rendered based on search and filter selections.

Additional Notes

  • This is a basic example and can be customized further, like adding pagination for large datasets, styling options, and more complex filtering logic.

  • Consider performance optimization techniques like debouncing search input and lazy loading results.

Last updated