Home > Enterprise >  How to reset value of <select> tag on a button click?
How to reset value of <select> tag on a button click?

Time:01-13

I have DATA - array of objects. Each object has answers and their isCorrect boolean prop that defines whether that options is truthy or not.

I collect each option correctness in isCorrect state and then show correct answers by changing border-color.

How to make tag controlled and reset its value after a button click in this scenario?

Edit nameless-star-s8xl0f

  const DATA = [
  {
    sentenceFirstPart: "It takes a lot of",
    sentenceSecondPart: "to learn how to waterski properly",
    answerOptions: [
      { answerText: "", isCorrect: false },
      { answerText: "attempt", isCorrect: false },
      { answerText: "effort", isCorrect: true },
      { answerText: "trial", isCorrect: false },
      { answerText: "try", isCorrect: false }
    ]
  },
  {
    sentenceFirstPart: "It was Thomas Edison who ",
    sentenceSecondPart: "electricity",
    answerOptions: [
      { answerText: "", isCorrect: false },
      { answerText: "detected", isCorrect: false },
      { answerText: "invented", isCorrect: true },
      { answerText: "found", isCorrect: false },
      { answerText: "discovered", isCorrect: false }
    ]
  }
];

export default function App() {
  const [isCorrect, setIsCorrect] = useState({});
  const [isChecked, setIsChecked] = useState(false);

  const handleValueChange = (value, index) => {
    setIsCorrect((prev) => ({
      ...prev,
      [index]: value === "true" ? true : false
    }));
  };

  return (
    <Wrapper>
      {DATA.map((sentence, index) => (
        <Sentence
          isChecked={isChecked}
          isCorrect={isCorrect[index]}
          key={index}
        >
          <span>
            {index   1}. {sentence.sentenceFirstPart}
          </span>
          <select onChange={(e) => handleValueChange(e.target.value, index)}>
            {sentence.answerOptions.map((option, index) => (
              <option value={option.isCorrect} key={index}>
                {option.answerText}
              </option>
            ))}
          </select>
          <span>{sentence.sentenceSecondPart}</span>
        </Sentence>
      ))}
      <div>
        <button onClick={() => setIsChecked(true)}>Check</button>
        <button>Reset</button>
      </div>
    </Wrapper>
  );
}

const Wrapper = styled.div`
  display: flex;
  flex-direction: column;
  gap: 1rem;

  button {
    padding: 0rem 1rem;
    width: 6rem;
  }
`;

export const Sentence = styled.div`
  display: flex;
  align-items: center;
  span {
    font-size: 1.2rem;
  }

  select {
    margin: 0 0.5rem;
    border: 1px solid;
    padding: 0.2rem;
    border-radius: 4px;
    font-weight: 500;
    border-color: ${({ isChecked, isCorrect }) =>
      !isChecked ? "currentColor" : isCorrect ? "green" : "red"};
  }
`;

CodePudding user response:

Since the select in posted code is not controlled I think it would be suitable to create reference of these with useRef and reset the values.

Forked demo with modification: codesandbox

Create an array ref and handling function for reset:

const selectsRef = useRef([]);
const handleReset = () => {
  setIsChecked(false);
  setIsCorrect({});
  selectsRef.current.forEach((item) => {
    if (!item) return;
    item.value = "";
  });
};

Assign the ref for each select in the output to create reference:

<Wrapper>
  {DATA.map((sentence, index) => (
    <Sentence isChecked={isChecked} isCorrect={isCorrect[index]} key={index}>
      <span>
        {index   1}. {sentence.sentenceFirstPart}
      </span>
      <select
        ref={(node) => (selectsRef.current[index] = node)}
        onChange={(e) => handleValueChange(e.target.value, index)}
      >
        {sentence.answerOptions.map((option, index) => (
          <option value={option.isCorrect} key={index}>
            {option.answerText}
          </option>
        ))}
      </select>
      <span>{sentence.sentenceSecondPart}</span>
    </Sentence>
  ))}
  <div>
    <button onClick={() => setIsChecked(true)}>Check</button>
    <button onClick={handleReset}>Reset</button>
  </div>
</Wrapper>

CodePudding user response:

You can simply get a selection of the inputs and place an onClick event handler on the reset button itself. Then set It's value as nothing.

Here's the forked sandbox with the updates made. https://codesandbox.io/s/bold-hypatia-tkprkc

The function I used to reset the values:

  const resetApp = () => {
    const selects = document.querySelectorAll('Select');
    selects.forEach(select => {
      select.value = "";
    });
  }

for the button, the function is called here:

<button onClick={() => resetApp()}>Reset</button>
  • Related