1

I am trying to dynamically add and delete table rows using ReactJS. But the problem is once I added few rows, the values in each column in each rows are the same even if I change them randomly.

Below screen shot will clarify further of my problem.

screenshot

The steps of what I am trying to do is:

1) Select an item from the dropdown

2) Enter the qty

3) Press + button

It works, but the next time I try to select an item or enter the quantity for an item, it updates every column

This is my code sample:

import React, { Component } from "react";
import {
  MDBRow,
  MDBCol,
  MDBCard,
  MDBCardBody,
  MDBMask,
  MDBIcon,
  MDBView,
  MDBBtn,
  MDBTable,
  MDBTableBody,
  MDBTableHead,
  MDBContainer
} from "mdbreact";
import { NavLink } from "react-router-dom";

import GetTable from "./table";
import GetTable2 from "./table2";

export default class CreateInvoiceForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      vendorName: "",
      itemID: "",
      qty: "",
      rows: [{}]
    };

    this.onSubmit = this.onSubmit.bind(this);
    this.vendorOnChange = this.vendorOnChange.bind(this);
    this.itemorOnChange = this.itemorOnChange.bind(this);
    this.quantityOnChange = this.quantityOnChange.bind(this);
    this.onHandleAddRow = this.onHandleAddRow.bind(this);
  }

  onHandleAddRow() {
    const itemDetails = {
      itemID: this.state.itemID,
      itemName: "",
      qty: this.state.qty,
      unitPrice: "",
      linePrice: ""
    };

    this.setState({
      rows: [...this.state.rows, itemDetails]
    });
  }

  onSubmit(e) {
    e.preventDefault();
    alert(this.state.vendorName);
  }

  vendorOnChange(e) {
    this.setState({
      vendorName: e.target.value
    });
  }

  quantityOnChange(e) {
    this.setState({
      qty: e.target.value
    });
  }

  itemorOnChange(e) {
    this.setState({
      itemID: e.target.value
    });
  }

  render() {
    return (
      <div>
        <MDBCard className="my-12 px-12 pb-12">
          <MDBCardBody className="">
            <h2 className="h1-responsive font-weight-bold text-center my-5">
              Create a Purchase Invoice
            </h2>
            <p className="text-center w-responsive mx-auto mb-5">
              Creating purchase invoices
              <strong>Without having a Purchase Order</strong>
            </p>

            {/* form starts here */}
            <form onSubmit={this.onSubmit}>
              <MDBRow>
                <MDBCol lg="6" md="6" className="mb-lg-0 mb-6">
                  <p className="h6 mb-4">
                    {" "}
                    <i className="fa fa-info-circle"></i> Invoice Details
                  </p>
                  <label
                    htmlFor="defaultFormRegisterNameEx"
                    className="grey-text"
                  >
                    Invoice No:
                  </label>
                  <input
                    type="text"
                    id="defaultFormRegisterNameEx"
                    className="form-control"
                  />
                  <br />
                  <label
                    htmlFor="defaultFormRegisterEmailEx"
                    className="grey-text"
                  >
                    Vendor
                  </label>
                  <div class="form-group">
                    <select
                      class="form-control"
                      id="exampleSelect1"
                      onChange={this.vendorOnChange}
                    >
                      <option disabled selected>
                        - Select vendor -{" "}
                      </option>
                      <option value="2">2</option>
                      <option value="3">3</option>
                      <option value="4">4</option>
                      <option value="5">5</option>
                    </select>
                  </div>

                  <label
                    htmlFor="defaultFormRegisterConfirmEx"
                    className="grey-text"
                  >
                    Invoice Date:
                  </label>
                  <input
                    type="date"
                    id="defaultFormRegisterConfirmEx"
                    className="form-control"
                  />
                  <br />
                  <label
                    htmlFor="defaultFormRegisterPasswordEx"
                    className="grey-text"
                  >
                    Expected Delievery Date:
                  </label>
                  <input
                    type="date"
                    id="defaultFormRegisterPasswordEx"
                    className="form-control"
                  />
                </MDBCol>
                <MDBCol lg="6" md="6" className="mb-lg-0 mb-6">
                  <p className="h6 mb-4">
                    {" "}
                    <i className="fa fa-truck"></i> Delievery Details
                  </p>
                  <label
                    htmlFor="defaultFormRegisterNameEx"
                    className="grey-text"
                  >
                    Billing Address
                  </label>
                  <textarea className="form-control"> </textarea>

                  <label
                    htmlFor="defaultFormRegisterEmailEx"
                    className="grey-text"
                  >
                    Contact Person:
                  </label>
                  <input
                    type="text"
                    id="defaultFormRegisterEmailEx"
                    className="form-control"
                  />
                  <br />
                  <label
                    htmlFor="defaultFormRegisterConfirmEx"
                    className="grey-text"
                  ></label>
                  <input
                    hidden
                    type="email"
                    id="defaultFormRegisterConfirmEx"
                    className="form-control"
                  />
                  <br />
                  <label
                    htmlFor="defaultFormRegisterPasswordEx"
                    className="grey-text"
                  ></label>
                  <input
                    hidden
                    type="password"
                    id="defaultFormRegisterPasswordEx"
                    className="form-control"
                  />
                  <br />
                  <br />
                  <br />
                  <br />
                  <br />
                  <br />
                </MDBCol>
              </MDBRow>
              <hr />
              {/* new row======================================================= */}

              <MDBRow>
                <MDBCol lg="5" md="5" className="mb-lg-0 mb-5 text-center">
                  <div class="form-group">
                    <label
                      htmlFor="defaultFormRegisterEmailEx"
                      className="grey-text"
                    >
                      Select an Item:
                    </label>
                    <select class="form-control" onChange={this.itemorOnChange}>
                      <option disabled selected>
                        - Select Item -
                      </option>
                      <option value="2">2</option>
                      <option value="3">3</option>
                      <option value="4">4</option>
                      <option value="5">5</option>
                    </select>
                  </div>
                </MDBCol>
                <MDBCol lg="5" md="5" className="mb-lg-0 mb-5 text-center">
                  <div class="form-group">
                    <label
                      htmlFor="defaultFormRegisterEmailEx"
                      className="grey-text"
                    >
                      Quantity:
                    </label>
                    <input
                      type="text"
                      id="defaultFormRegisterEmailEx"
                      className="form-control"
                      onChange={this.quantityOnChange}
                    />
                  </div>
                </MDBCol>
                <MDBCol lg="2" md="2" className="mb-lg-0 mb-2 text-center">
                  <div className="form-group">
                    <label
                      htmlFor="defaultFormRegisterEmailEx"
                      className="grey-text"
                    ></label>
                    <button
                      style={{ height: "40px" }}
                      name="subject"
                      type="button"
                      className="btn btn-success btn-sm form-control"
                      onClick={this.onHandleAddRow}
                    >
                      <i className="fa fa-plus fa-lg"></i>
                    </button>
                  </div>
                </MDBCol>
              </MDBRow>

              <MDBRow>
                <MDBCol lg="12" md="12" className="mb-lg-0 mb-12 text-center">
                  <MDBTable
                    className="container-fluid"
                    striped
                    bordered
                    hover
                    responsive
                  >
                    <MDBTableHead color="primary-color" textWhite>
                      <tr>
                        <th>Item ID</th>
                        <th>Item Name</th>
                        <th>Qty</th>
                        <th>Unit Price (R.s)</th>
                        <th>Line Price (R.s)</th>
                        <th><i className="fa fa-cog"></i></th>
                      </tr>
                    </MDBTableHead>
                    <MDBTableBody>

                        {this.state.rows.length > 1
                        ? this.state.rows.map((item, id) => (
                          <tr key={id}>
                            <td>{this.state.itemID}</td>
                            <td>{this.state.itemID}</td>
                            <td>{this.state.qty}</td>
                            <td>price</td>
                            <td>Line</td>
                            <MDBBtn><i className="fa fa-times"></i></MDBBtn>
                          </tr>
                        ))
                        : <tr></tr>
                        }
                    </MDBTableBody>
                  </MDBTable>
                </MDBCol>
              </MDBRow>
            </form>
            {/* form ends here */}
          </MDBCardBody>
        </MDBCard>
        <br />
        <MDBContainer>
          <MDBRow>
            <MDBCol className="col-12 col-md-12 text-center">
              <GetTable2 />
            </MDBCol>
          </MDBRow>
        </MDBContainer>
      </div>
    );
  }
}

Can someone please help me?

Jee Mok
  • 6,157
  • 8
  • 47
  • 80

2 Answers2

0

You have a single state value for qty and itemID so it'll render every row with a single value. If you need a quantity and item ID for each item (which seems reasonable) then you need to keep that in state per item.

Your map should be changed to use the value from each row, e.g., item.qty (oddly a string), and your quantity update should change that row's data.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
0
import React, { Component } from 'react'

class Table extends Component {
   constructor(props) {
      super(props) //since we are extending class Table so we have to use super in order to override Component class constructor
      this.state = { //state is by default an object
         students: [
            { id: 1, name: 'Wasif', age: 21, email: 'wasif@email.com' },
            { id: 2, name: 'Ali', age: 19, email: 'ali@email.com' },
            { id: 3, name: 'Saad', age: 16, email: 'saad@email.com' },
            { id: 4, name: 'Asad', age: 25, email: 'asad@email.com' }
         ]
      }
   }

   render() { //Whenever our class runs, render method will be called automatically, it may have already defined in the constructor behind the scene.
      return (
         <div>
            <h1>React Dynamic Table</h1>
         </div>
      )
   }
}

export default Table //exporting a component make it reusable and this is the beauty of react
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • This isn't helpful as-is. Unrelated, but it's not "whenever our class runs", it's when its state or props change, which you don't show. Answers should directly address the question; while creating a table component might help, it's unrelated to the question. – Dave Newton Sep 29 '19 at 18:42