Michael Angelo
Michael Angelo

Reputation: 49

Selecting one row in table without using extra npm packages

I'm trying to build a reusable table from scratch without using extra npm packages. The problem I've been trying to solve all day is selecting one row on checkbox click. I wanted to achieve this by changing className to 'blue' on state change. className={selectValue ? "blue" : null} What's happening right now is whichever row I select its selecting all of the rows. I was hoping you could point me into the right direction. What are some other ways of changing background color when clicking checkbox?

I appreciate the help.

Code and Codesandbox below.

https://codesandbox.io/s/friendly-resonance-48iu3?file=/src/App.js

import React, { useState, useEffect } from "react";
import "../../App.css";

function Student() {
  const [studentState, setStudentState] = useState([]);
  const [selectValue, setSelectValue] = useState("");

  useEffect(() => {
    let studentState = [
      { id: 1, firstname: "Stone", lastname: "Cold", major: "wwf" },
      { id: 2, firstname: "Addrian", lastname: "Fox", major: "wwf" },
      { id: 3, firstname: "Harry", lastname: "Pit", major: "wwf" },
    ];

    setStudentState(
      studentState.map((d) => {
        return {
          select: false,
          id: d.id,
          firstname: d.firstname,
          lastname: d.lastname,
          major: d.major,
        };
      })
    );
  }, []);


  return (
    <div className="container">
      <table className="table table-bordered">
        <thead>
          <tr>
            <th scope="col">
              <input
                type="checkbox"
                onChange={(e) => {
                  let checked = e.target.checked;
                  setStudentState(
                    studentState.map((d) => {
                      d.select = checked;
                      return d;
                    })
                  );
                  
                }}
              ></input>
            </th>
            <th scope="col">First</th>
            <th scope="col">Last</th>
            <th scope="col">Handle</th>
          </tr>
        </thead>
        <tbody>
          {studentState.map((d, i) => (
            <tr key={d.id} className={selectValue ? "blue" : null}>
              <th scope="row">
                <input
                  onChange={(event) => {
                    let checked = event.target.checked;
                    setStudentState(
                      studentState.map((data) => {
                        if (d.id === data.id) {
                          data.select = checked;
                        }
                        return data;
                      })
                    );
                    setSelectValue(checked)
                  }}
                  type="checkbox"
                  checked={d.select}
                  id={d.id}
                ></input>
              </th>
              <td>{d.firstname}</td>
              <td>{d.lastname}</td>
              <td>{d.major}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

export default Student;

Upvotes: 0

Views: 69

Answers (1)

Avaneesh Tripathi
Avaneesh Tripathi

Reputation: 194

you are using a single state to check the selected row which cant be done as a single state can not hold the value for all the rows. I see you also have a status select inside each object which you use to check/uncheck the checkboxes. We can use the same to show colored rows as well. Here is an updated codesandbox you can have a look at. Let me know if any questions.

export default function App() {
  const [studentState, setStudentState] = useState([]);

  useEffect(() => {
    let studentState = [
      { id: 1, firstname: "Stone", lastname: "cold", major: "wwf" },
      { id: 2, firstname: "Addrian", lastname: "Fox", major: "wwf" },
      { id: 3, firstname: "Harry", lastname: "Pit", major: "wwf" }
    ];

    setStudentState(
      studentState.map((d) => {
        return {
          select: false,
          id: d.id,
          firstname: d.firstname,
          lastname: d.lastname,
          major: d.major
        };
      })
    );
  }, []);

  return (
    <div className="container">
      <table className="table table-bordered">
        <thead>
          <tr>
            <th scope="col">
              <input
                type="checkbox"
                onChange={(e) => {
                  let checked = e.target.checked;
                  setStudentState(
                    studentState.map((d) => {
                      d.select = checked;
                      return d;
                    })
                  );
                }}
              ></input>
            </th>
            <th scope="col">First</th>
            <th scope="col">Last</th>
            <th scope="col">Handle</th>
          </tr>
        </thead>
        <tbody>
          {studentState.map((d, i) => (
            <tr key={d.id} className={d.select ? "blue" : null}>
              <th scope="row">
                <input
                  onChange={(event) => {
                    let checked = event.target.checked;
                    setStudentState(
                      studentState.map((data) => {
                        if (d.id === data.id) {
                          data.select = checked;
                        }
                        return data;
                      })
                    );
                  }}
                  type="checkbox"
                  checked={d.select}
                  id={d.id}
                ></input>
              </th>
              <td>{d.firstname}</td>
              <td>{d.lastname}</td>
              <td>{d.major}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

Upvotes: 1

Related Questions