Home > Software design >  Is there a way to populate an input field from a list of buttons in React?
Is there a way to populate an input field from a list of buttons in React?

Time:09-30

I am building a React application and I need to populate an input field from a list of predefined buttons (the text of the btn should be displayed on the input if the user clicks on the btn). For example: let's suppose the user sees 3 btns with the following text for each: 'Banana', 'Apple','Orange'. If the user clicks on the Banana btn, the world 'Banana' must appear on the input field. Here is the code of App.js :

function App() {
  const [suggestiveListBorder, setSuggestiveListBorder] = useState("");

  return (
    <div className="App">
      <Navbar />
      <ListOfExercises
        suggestiveListBorder={suggestiveListBorder}
      ></ListOfExercises>

      <div className="pages">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route
            path="/chest"
            element={
              <ChestWorkouts
                setSuggestiveListBorder={setSuggestiveListBorder}
              />
            }
          />
          <Route path="/hamstrings" element={<HamstringsWorkouts />} />

the code of ListOfExercises.js

export function ListOfExercises({ suggestiveListBorder }) {
  const currentLocation = useLocation();
  let currentLocat = currentLocation.pathname;
  const chestExos = exercisesData.exercises.chest_Exercises;

  return (
    <>
      {currentLocat === "/chest" ? (
        <ChestExosList
          suggestiveListBorder={suggestiveListBorder}
          chestExos={chestExos}
        />
      ) : currentLocat === "/hamstrings" ? (
        <span>hamstrings</span>
      ) : null}
    </>
  );
}

the code of ChestExosList.js

export function ChestExosList({ chestExos, suggestiveListBorder }) {
  const chestValues = Object.values(chestExos);

  return (
    <div
      className="chest-exos-list-container"
      style={{
        border: suggestiveListBorder,
      }}
    >
      <div>
        <p className="chest-exos-paragraph">
          Have no idea about the exercise you want to do ? Here are some
          suggestions :
        </p>
      </div>
      <Stack direction={"row"} spacing={2} sx={{ marginBottom: "30px" }}>
        {chestValues.map(
          (elem, index) =>
            index < 8 &&
            index >= 0 && (
              <Button type="secondary" key={index}>
                {elem}
              </Button>
            )
        )}
      </Stack>

the code of Chest page

const Chest = ({ setSuggestiveListBorder }) => {
  const { workouts, dispatch } = useWorkoutsContext();
  useEffect(() => {
    const fetchWorkouts = async () => {
      const response = await fetch("/api/workouts");
      const json = await response.json();

      if (response.ok) {
        dispatch({ type: "SET_WORKOUTS", payload: json });
      }
    };

    fetchWorkouts();
  }, [dispatch]);

  const antIcon = (
    <LoadingOutlined
      style={{
        fontSize: 50,
      }}
    />
  );

  return (
    <div className="chest-page-container">
      <div className="chest-page-workouts">
        {!workouts && <Spin spinning={true} indicator={antIcon}></Spin>}
        {workouts &&
          workouts.map((workout) => (
            <WorkoutDetails workout={workout} key={workout._id} />
          ))}
      </div>
      <WorkoutForm setSuggestiveListBorder={setSuggestiveListBorder} />
    </div>
  );
};

and a snippet of the code of WorkoutForm.js :

return (
    <form className="chest-workouts-form" onSubmit={handleSubmit}>
      <div className="chest-workouts-form-inner">
        <h3>Add a New Workout</h3>

        <label>Excercise Title : </label>

          <input
            onm ouseOver={() => {
              setSuggestiveListBorder("1.5px solid #1aac83");
            }}
            type="text"
            onChange={(e) => setTitle(e.target.value)}
            value={title}
            // value=""
            className={emptyFields.includes("title") ? "form-msg-error" : ""}
          />
        ...

thank you all.

CodePudding user response:

Yes, you can. You can add a different onClick event on each button (see first button in example) or a more generic one if you're planning on having many buttons (second button in example)

const Component = () => {
    const [inputValue, setInputValue] = useState("");
    const firstButtonText = "First button";

    return (
        <>
            <button onClick={() => setInputValue(firstButtonText)}>{firstButtonText}</button
            <button onClick={(e) => setInputValue(e.target.innerHTML)}>Second button</button>
            <input value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
    </>
    )

}

CodePudding user response:

Create state for you input value :

const [inputValue,setInputValue]=useState('');

Give this value to your input:

 <input
        onm ouseOver={() => {
          setSuggestiveListBorder("1.5px solid #1aac83");
        }}
        type="text"
        onChange={(e) => setTitle(e.target.value)}
        value={inputValue}
        className={emptyFields.includes("title") ? "form-msg-error" : ""}
      />

On your button click, you set this value:

<button onClick={()=> setInputValue("button one"}>...

Do the same for your other buttons

  • Related