UbuntuNewb
UbuntuNewb

Reputation: 411

Reactjs dropdown menu not displaying when hovered over the word

can someone tells me why the dropdown menu is not displaying in this demo? the dropdown menu should show when I hover over the word 'collective'?

https://codesandbox.io/s/funny-river-c76hu

For the app to work, you would have to type in the input box "collective", click analyse, then a progressbar will show, click on the blue line in the progressbar, an underline would show under the word "collective" then you should hover over "collective" word and a drop down menu should be displayed but the whole window disappears when I hover over the word "collective" instead of the drop down menu

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { Content, Dropdown, Label, Progress, Button, Box } from "rbx";

import "rbx/index.css";

function App() {
  const [serverResponse, setServerResponse] = useState(null);
  const [text, setText] = useState([]);
  const [loading, setLoading] = useState(false);
  const [modifiedText, setModifiedText] = useState(null);
  const [selectedSentiment, setSentiment] = useState(null);
  const [dropdownContent, setDropdownContent] = useState([]);
  const [isCorrected, setIsCorrected] = useState(false);
  const [displayDrop, setDisplayDrop] = useState(false);
  useEffect(() => {
    if (serverResponse && selectedSentiment) {
      const newText = Object.entries(serverResponse[selectedSentiment]).map(
        ([word, recommendations]) => {
          const parts = text[0].split(word);
          const newText = [];
          parts.forEach((part, index) => {
            newText.push(part);
            if (index !== parts.length - 1) {
              newText.push(
                <u
                  className="dropbtn"
                  data-replaces={word}
                  onMouseOver={() => {
                    setDropdownContent(recommendations);
                    setDisplayDrop(true);
                  }}
                >
                  {word}
                </u>
              );
            }
          });

          return newText;
        }
      );

      setModifiedText(newText.flat());
    }
  }, [serverResponse, text, selectedSentiment]);

  const handleAnalysis = () => {
    setLoading(true);

    setTimeout(() => {
      setLoading(false);
      setServerResponse({ joy: { collective: ["inner", "constant"] } });
    }, 1500);
  };

  const handleTextChange = event => {
    setText([event.target.innerText]);
  };

  const replaceText = wordToReplaceWith => {
    const replacedWord = Object.entries(serverResponse[selectedSentiment]).find(
      ([word, recommendations]) => recommendations.includes(wordToReplaceWith)
    )[0];

    setText([
      text[0].replace(new RegExp(replacedWord, "g"), wordToReplaceWith)
    ]);
    setModifiedText(null);
    setServerResponse(null);
    setIsCorrected(true);
    setDropdownContent([]);
  };

  const hasResponse = serverResponse !== null;

  return (
    <Box>
      <Content>
        <div
          onInput={handleTextChange}
          contentEditable={!hasResponse}
          style={{ border: "1px solid red" }}
        >
          {hasResponse && modifiedText
            ? modifiedText.map((text, index) => <span key={index}>{text}</span>)
            : isCorrected
            ? text[0]
            : ""}
        </div>
        <br />
        {displayDrop ? (
          <div
            id="myDropdown"
            class="dropdown-content"
            onClick={() => setDisplayDrop(false)}
          >
            dropdownContent.map((content, index) => (
            <>
              <strong onClick={() => replaceText(content)} key={index}>
                {content}
              </strong>{" "}
            </>
            ))
          </div>
        ) : null}
        <br />
        <Button
          color="primary"
          onClick={handleAnalysis}
          disabled={loading || text.length === 0}
        >
          analyze
        </Button>
        <hr />
        {hasResponse && (
          <Label>
            Joy{" "}
            <Progress
              value={Math.random() * 100}
              color="info"
              onClick={() => setSentiment("joy")}
            />
          </Label>
        )}
      </Content>
    </Box>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

css file

.App {
  font-family: sans-serif;
  text-align: center;
}
.highlight {
  background: red;
  text-decoration: underline;
}

.dropbtn {
  color: white;

  font-size: 16px;
  border: none;
  cursor: pointer;
}

.dropbtn:hover,
.dropbtn:focus {
  background-color: #2980b9;
}

.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  position: relative;
  background-color: #f1f1f1;
  min-width: 160px;
  overflow: auto;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  z-index: 1;
}

.show {
  display: block;
}

Upvotes: 1

Views: 375

Answers (1)

user2340824
user2340824

Reputation: 2152

The problem is this:

{displayDrop ? (
      <div
        id="myDropdown"
        class="dropdown-content"
        onClick={() => setDisplayDrop(false)}
      >
        dropdownContent.map((content, index) => (
        <>
          <strong onClick={() => replaceText(content)} key={index}>
            {content}
          </strong>{" "}
        </>
        ))
      </div>
    ) : null}

You are missing a pair of curly brackets around dropdownContent. It should be:

    {displayDrop ? (
      <div
        id="myDropdown"
        class="dropdown-content"
        onClick={() => setDisplayDrop(false)}
      >
        {dropdownContent.map((content, index) => (
        <>
          <strong onClick={() => replaceText(content)} key={index}>
            {content}
          </strong>{" "}
        </>
        ))}
      </div>
    ) : null}

A working sandbox here https://codesandbox.io/embed/fast-feather-lvpk7 which is now displaying this content.

Upvotes: 2

Related Questions