How to select content by rows?

Viewed 66

I am creating and deleting rows dynamically, while create rows I create dropdown on the selection of dropdown the next field html changes i.e. INPUT LNAME .

As the rows are creating and deleting dynamically so when I add a new row and when I select the value from dropdown all the html get changes in INPUT LNAME. Instead only that row html in INPUT LNAME should get changed not all the html of al the rows

working code

import React from "react";
import "./styles.css";

export default function App() {
  const [state, setState] = React.useState({
    rows: [{}]
  });

  const handleChange = idx => e => {
    const { name, value } = e.target;
    const rows = [...state.rows];
    rows[idx] = { ...rows[idx], [name]: value }; //here
    setState({
      rows
    });
  };

  const handleAddRow = () => {
    const item = {
      fname: "",
      lname: ""
    };
    setState({
      rows: [...state.rows, item]
    });
  };

  const handleRemoveSpecificRow = idx => () => {
    const rows = [...state.rows];
    rows.splice(idx, 1);
    setState({ rows });
  };

  React.useEffect(() => {
    console.log(state);
  }, [state]);

  const [ddlSelectedid, setDdlSelectedId] = React.useState("");
  console.log(ddlSelectedid);

  const handleSelect = event => {
    setDdlSelectedId(event.target.value);
    setShow(false);
  };

  const [show, setShow] = React.useState(true);
  const selectionContent = idx => {
    if (ddlSelectedid === "INPUT") {
      return (
        <input
          type="text"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    } else if (ddlSelectedid === "RADIO") {
      return (
        <input
          type="radio"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    } else if (ddlSelectedid === "CHECKBOX") {
      return (
        <input
          type="checkbox"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    }
  };

  return (
    <div className="App">
      <table>
        <thead>
          <tr>
            <th>#</th>
            <th>INPUT FNAME</th>
            <th>Dropdown</th>
            <th>INPUT LNAME</th>
            <th>Button</th>
          </tr>
        </thead>
        <tbody>
          {state.rows.map((item, idx) => (
            <tr id="addr0" key={idx}>
              <td>{idx}</td>
              <td>
                <input
                  type="text"
                  name="fname"
                  value={state.rows[idx].name}
                  onChange={handleChange(idx)}
                />
              </td>
              <td>
                <select name="cars" id="cars" onChange={handleSelect}>
                  <option defaultValue="INPUT">INPUT</option>
                  <option value="RADIO">RADIO</option>
                  <option value="CHECKBOX">CHECKBOX</option>
                </select>
              </td>
              <td>
                {show && (
                  <input
                    type="text"
                    name="lname"
                    value={state.rows[idx].name}
                    onChange={handleChange(idx)}
                  />
                )}

                {!show && selectionContent(idx)}
              </td>
              <td>
                <button className="btn" onClick={handleRemoveSpecificRow(idx)}>
                  Remove
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      <button onClick={handleAddRow} className="btn">
        Add Row
      </button>
    </div>
  );
}
1 Answers

Add array for ddlSelectedid & show. You assigning single value in ddlSelectedid & show. When you change dropdown, that updates for all rows.

you can check working code here codesandbox

import React from "react";
import "./styles.css";

export default function App() {
  const item = {
    fname: "",
    lname: ""
  };
  const [rows, setRows] = React.useState([item]);

  const handleChange = idx => e => {
    const { name, value } = e.target;
    rows[idx] = { ...rows[idx], [name]: value }; //here
    setRows([...rows]);
  };

  const handleAddRow = () => {
    setRows([...rows, item]);
    setDdlSelectedId([...ddlSelectedid, "INPUT"]);
    setShow([...show, true]);
  };

  const handleRemoveSpecificRow = idx => () => {
    rows.splice(idx, 1);
    setRows([...rows]);
    ddlSelectedid.splice(idx, 1);
    setDdlSelectedId([...ddlSelectedid]);
    show.splice(idx, 1);
    setShow([...show]);
  };

  React.useEffect(() => {
    console.log(rows);
  }, [rows]);

  const [ddlSelectedid, setDdlSelectedId] = React.useState(["INPUT"]);

  const handleSelect = (event, idx) => {
    event.preventDefault();
    ddlSelectedid[idx] = event.target.value;
    setDdlSelectedId([...ddlSelectedid]);
    show[idx] = false;
    setShow([...show]);
  };

  const [show, setShow] = React.useState([true]);
  const selectionContent = idx => {
    if (ddlSelectedid[idx] === "INPUT") {
      return (
        <input
          type="text"
          name="lname"
          value={rows[idx].lname}
          onChange={handleChange(idx)}
        />
      );
    } else if (ddlSelectedid[idx] === "RADIO") {
      return (
        <input
          type="radio"
          name="lname"
          value={rows[idx].lname}
          onChange={handleChange(idx)}
        />
      );
    } else if (ddlSelectedid[idx] === "CHECKBOX") {
      return (
        <input
          type="checkbox"
          name="lname"
          value={rows[idx].lname}
          onChange={handleChange(idx)}
        />
      );
    }
  };

  return (
    <div className="App">
      <table>
        <thead>
          <tr>
            <th>#</th>
            <th>INPUT FNAME</th>
            <th>Dropdown</th>
            <th>INPUT LNAME</th>
            <th>Button</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((item, idx) => (
            <tr id="addr0" key={idx}>
              <td>{idx}</td>
              <td>
                <input
                  type="text"
                  name="fname"
                  value={rows[idx].fname}
                  onChange={handleChange(idx)}
                />
              </td>
              <td>
                <select
                  name="cars"
                  id="cars"
                  onChange={e => handleSelect(e, idx)}
                >
                  <option defaultValue="INPUT">INPUT</option>
                  <option value="RADIO">RADIO</option>
                  <option value="CHECKBOX">CHECKBOX</option>
                </select>
              </td>
              <td>
                {show[idx] && (
                  <input
                    type="text"
                    name="lname"
                    value={rows[idx].lname}
                    onChange={handleChange(idx)}
                  />
                )}

                {!show[idx] && selectionContent(idx)}
              </td>
              <td>
                <button className="btn" onClick={handleRemoveSpecificRow(idx)}>
                  Remove
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      <button onClick={handleAddRow} className="btn">
        Add Row
      </button>
    </div>
  );
}
Related