0

I am trying to get the checked values of a checkbox and then display them in a field. I have two files the index which has the input field and then the checkbox is made in a modal which is a different component, the selectlanguage. I want that when a user checks one or more checkbox(es), the value(s) appears on the input and when unchecked, the value leaves the field.

Presently, what I am able to achieve is only a single value appearing on the input field.

Here is a snippet of the code.

index.js

import React, { useState } from "react";
import SelectLanguage from "../../components/modal/selectLanguage";

const index = () => {
const [chosenLanguage, setChosenLanguage] = useState([]);

function checkLanguage(e) {
  setChosenLanguage(e.target.name);
};

<label className="relative block p-3 border-b-2 border-gray-200 w-full" for="languages">
  <span for="languages">languages</span>
  <input
    id="languages"
    type="text"
    placeholder="Spanish, Arabic"
    autoComplete="off"
    onClick={languageShowModal}
    value={chosenLanguage}
  />
</label>
}

export default index;

selectlanguage.js

import { useState } from "react";

export default function SelectLanguage({ open, handleClose, checkLanguage }) {
  const handleCheckbox = (e) => {
    alert(e.target.name);
  };

  return open ? (
    <div>
      <label>
        <input type="checkbox" name="spanish" onChange={checkLanguage} />
        <span>spanish</span>
      </label>
      <label>
        <input type="checkbox" name="spanish" onChange={checkLanguage} />
        <span>french</span>
      </label>
      <label>
        <input type="checkbox" name="spanish" onChange={checkLanguage} />
        <span>arabic</span>
      </label>
    </div>
  ) : (
    ""
  );
}

2
  • I think the way you call setChosenLanguage(e.target.name) is incorrect. You set it to an array initially, but then you just override it with a single value. You might want to add/remove the value to the array instead. setChosenLanguage([...chosenLanguage, e.target.name]); Commented May 17, 2022 at 14:14
  • @szczocik, thanks for that, it works to an extent, but now, after I check a box, it adds it to the list and I uncheck it, it still adds it to the list. How can I only add the checked items? Commented May 17, 2022 at 14:46

1 Answer 1

1

It isn't exactly clear to me how you have things hooked up, but a good strategy is to reflect the state of the DOM into your React state (Controlled Components), and then have a way of displaying that state. In your case, you want to store the state of a bunch of checkboxes, and one way to do this is with a map.

export const MyComponent = () => {
  const [ chosenLanguages, setChosenLanguages ] = useState({})

  const checkLanguage = (e) => {
    setChosenLanguages(prev => ({
      ...prev,
      [e.target.value]: e.target.checked,
    }))
  }

  const showLanguages = () => {
    return Object.entries(chosenLanguages)
      .filter(([_, checked]) => checked)
      .map(([name, _]) => name)
      .join(', ')
  }

  return (
    <input value={showLanguages()} />
  )
}

Instead of an array, chosenLanguages is a map of language names to their checked state, for example:

{
  arabic: true,
  spanish: false,
  french: true,
}

When you've stored your state like this, you can transform it in whatever way you want when you render.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer. Using "e.target.value" didn't work as I was only getting "on" on the field, I had to change it to, "e.target.name" since I already had the name attribute on the different input tags. Was that a good way to go about it ?
Also, I would like to ask, I have the first value of the input tags to be checked by default, how can I ensure it is already listed on the field, or do I need to hard-code it in the "chosenLanguage" state.
Good questions, normally checkboxes that are related to each other have the same name, but different value which is why I used value here. See: developer.mozilla.org/en-US/docs/Web/HTML/Element/Input/…
Regarding the second question, the link I provided on Controlled Components should provide a hint. Providing the default state to chosenLanguage is good practice, as long as you force the checkbox inputs to have its state also, for instance checked={chosenLanguages.arabic}.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.