0

I created a react js app and have a table and it contains a button "Add Available Day" when I click it checkbox with days will show and when I choose a day it will automatically put in the table, however instead of updating specific row, changes are applied in all row. What I want to happen is for example I click add available day in first row then first row data must be updated not second and third row

This is my code:

import React from 'react';
import { Table, Button } from 'react-bootstrap';

const personData = [
    { id: 1, firstName: 'test1', lastName: 'test', day: [] },
    { id: 2, firstName: 'Jane', lastName: 'Doe', day: [] },
    { id: 3, firstName: 'John', lastName: 'Doe', day: [] },
    { id: 4, firstName: 'Clint', lastName: 'test', day: [] }
]

export default class App extends React.Component {
    constructor() {
        super();
        this.state = {
            day: [],
            isSelectDay: false,
            person: personData
        }
    }
    

    handleSelectDay = (event) => {
        let dayArr = [...this.state.day]
        const value = event.target.value
        const index = dayArr.findIndex(day => day === value);
        if (index > -1) {
            dayArr = [...dayArr.slice(0, index), ...dayArr.slice(index + 1)]
        } else {
            dayArr.push(value)
        }
        this.setState({ day: dayArr });
    }

    handleAddDay = () => {
        this.setState({ isSelectDay: true })
    }

    render() {
        const { isSelectDay, day } = this.state
        


        const dayOptions = ["Monday, ", "Tuesday, ", "Wednesday", "Thursday, ", "Friday"].map((cur, ind) => {
                return (
                    <div key={ind} className="checks" >
                        <label>
                            <input type="checkbox" name={cur} value={cur}
                                onChange={this.handleSelectDay} />{cur}
                        </label>
                    </div>
                )
            })

        return (
            <>
                <Table striped bordered hover>
                    <thead>
                        <tr>
                            <th>First Name</th>
                            <th>Last Name</th>
                            <th>Days Available</th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.state.person.length > 0 ? (
                            this.state.person.map((person) => (
                                <tr key={person.id}>
                                    <td>{person.firstName}</td>
                                    <td>{person.lastName}</td>
                                    <td>{day}<Button variant="success" onClick={this.handleAddDay}>Add Available Day</Button></td>
                                </tr>
                            ))
                        ) : (
                                <tr>
                                    <td colSpan={3}>No Data</td>
                                </tr>
                            )}
                    </tbody>

                </Table>
                <div style={{ display: isSelectDay ? 'block' : 'none' }}>
                    {dayOptions}
                </div>
            </>
        )
    }
}

1 Answer 1

1

Is this something you're after?

Demo

Full Code

I changed isSelectDay to personSelected so when you click 'Add Available Day' it'll switch to the correct person object from personData. I then used this to update the people object in the state (a copy of personData) to add/remove days from day array. The day array was then used to output the days.

import React from "react";
import { Table, Button } from "react-bootstrap";

var personData = [
  { id: 1, firstName: "test1", lastName: "test", day: [] },
  { id: 2, firstName: "Jane", lastName: "Doe", day: [] },
  { id: 3, firstName: "John", lastName: "Doe", day: [] },
  { id: 4, firstName: "Clint", lastName: "test", day: [] }
];

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      personSelected: null,
      people: personData
    };
  }

  handleSelectDay = (event) => {
    let dayArr = [...this.state.personSelected.day];
    const value = event.target.value;
    const index = dayArr.findIndex((day) => day === value);
    if (index > -1) {
      dayArr = [...dayArr.slice(0, index), ...dayArr.slice(index + 1)];
    } else {
      dayArr.push(value);
    }

    let newPeople = this.state.people;
    newPeople.find((x) => x === this.state.personSelected).day = dayArr;

    this.setState({ people: newPeople });
  };

  handleAddDay = (person) => {
    this.setState({ personSelected: person });
    document
      .querySelectorAll("input[type=checkbox]")
      .forEach((el) => (el.checked = false));
  };

  render() {
    const { personSelected } = this.state;

    const dayOptions = [
      "Monday, ",
      "Tuesday, ",
      "Wednesday",
      "Thursday, ",
      "Friday"
    ].map((cur, ind) => {
      return (
        <div key={ind} className="checks">
          <label>
            <input
              type="checkbox"
              name={cur}
              value={cur}
              onChange={this.handleSelectDay}
            />
            {cur}
          </label>
        </div>
      );
    });

    return (
      <>
        <Table striped bordered hover>
          <thead>
            <tr>
              <th>First Name</th>
              <th>Last Name</th>
              <th>Days Available</th>
            </tr>
          </thead>
          <tbody>
            {this.state.people.length > 0 ? (
              this.state.people.map((person) => (
                <tr key={person.id}>
                  <td>{person.firstName}</td>
                  <td>{person.lastName}</td>
                  <td>
                    {person.day}
                    <Button
                      variant="success"
                      onClick={() => this.handleAddDay(person)}
                    >
                      Add Available Day
                    </Button>
                  </td>
                </tr>
              ))
            ) : (
              <tr>
                <td colSpan={3}>No Data</td>
              </tr>
            )}
          </tbody>
        </Table>
        {personSelected !== null && (
          <div style={{ display: "block" }}>{dayOptions}</div>
        )}
      </>
    );
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, It's exactly what Im looking for. Thank you so much really helped me

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.