使用ReactJS的动态表中的列总计

时间:2018-08-16 10:39:43

标签: javascript reactjs html-table row

我的问题是,当我输入“数量”和“价格”的值来计算总数时,将对其进行计算,但是当我添加另一行时,总价值是根据“数量和价格”的最后输入值来计算的,如下图:

enter image description here

我的代码如下:

        class AjouterFacture extends Component {
          constructor(props) {
            super(props);
            this.state = {
              rowData: [],
              Produits: [],
              Quantite: "",
              Prix: ""
            };

            this.handleRowChange = this.handleRowChange.bind(this);
            this.handleRowDelete = this.handleRowDelete.bind(this);
            this.handleRowAdd = this.handleRowAdd.bind(this);
            this.getTotal = this.getTotal.bind(this);
            this.pushToCaller = this.pushToCaller.bind(this);
          }
  handleQuantiteChange(e) {
        this.setState({
          Quantite: e.target.value
        }, this.pushToCaller);
      }
      handleselectprdtChange(e) {
        this.setState({
          selectprdt: e.target.value
        }, this.pushToCaller);
      }
      handlePrixChange(e) {
        this.setState({
          Prix: e.target.value
        }, this.pushToCaller);
      }

          pushToCaller() {
            this.handleRowChange( {
              Quantite: parseInt(this.state.Quantite, 10),
              selectprdt: this.state.selectprdt,
              Prix: parseFloat(this.state.Prix),
            });
          }


          render() {

            return (<div className="animated fadeIn">


         <h6> Veuillez ajouter au moins un produit : </h6>
                <Table  >
                <thead >
                          <tr>
                            <th>PRODUIT</th>
                            <th>QUANTITE</th>
                            <th>PRIX UNITAIRE</th>
                            <th>TOTAL</th>
                            <th></th>
                          </tr>
                          </thead>
                          <tbody>
                        {this.state.rowData.map((index) =>

                        <tr key={index} id={index} 
                        onChange={this.handleRowChange}>


                 <td> <Input type="select" name="selectedcl" id="selectcl"
                                  placeholder="Veuillez sélectionner un produit"  value={this.state.rowData.selectprdt}
                  onChange={this.handleselectprdtChange} >
                   <option  key={-1} hidden>Choisisr un produit</option>


                             {  this.state.Produits.map((pdt, i) => 
                             <option key={i} >{pdt.Nomp}</option>
                             )} 


                              </Input>
                            </td>
                            <td><Input type="number" 
                                  placeholder="0" value={this.state.rowData.Quantite} onChange={this.handleQuantiteChange}/></td>
                            <td>
                                 <InputGroup ><Input type="text" 
                                  value={this.state.rowData.Prix} onChange={this.handlePrixChange} />
                                  <InputGroupAddon addonType="prepend">
                                      <InputGroupText><i ></i></InputGroupText>
                                    </InputGroupAddon>
                                         </InputGroup >
                                  </td>

                            <td >
                             <p >{this.state.Quantite * this.state.Prix}  </p>

                            </td>
                            <td>
                             <Button onClick={this.handleRowDelete} active style={center} >Effacer</Button>
              </td> </tr> )} 



                          <tr>

                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td><Button onClick={this.handleRowAdd} >Ajouter une ligne</Button></td>
                  </tr>
                </tbody>

                <tfoot>
                  <tr>

                    <th></th>
                    <th >Grand total :</th>
                    <th>{this.getTotal()} </th>
                    <th></th>
                  </tr>
        </tfoot>

                </Table>


                </div>);
          }
          getTotal() {
            let grandTotal = 0;
            const rowTotals = this.state.rowData.map(row => this.state.Quantite *  this.state.Prix);
            if (rowTotals.length > 0) {
              grandTotal = rowTotals.reduce((acc, val) => acc + val);
            }
            return grandTotal;
          }
         handleRowChange(row, data) {
            const rowDataCopy = this.state.rowData.slice(0);
            rowDataCopy[row] = data;
            this.setState({
              rowData: rowDataCopy

            });
          }  
          handleRowDelete(row) {
            const rowDataCopy = this.state.rowData.slice(0);
            rowDataCopy.splice(row, 1);
            this.setState({
              rowData: rowDataCopy
            });
          }
         handleRowAdd() {
            const rowDataCopy = this.state.rowData.slice(0);
            rowDataCopy.push({selectprdt:'', Quantite : "", Prix :"" });
            this.setState({
              rowData: rowDataCopy
            });
          }

        }
        export default AjouterFacture;

我希望将为每一行计算总列数。

请问如何纠正?

2 个答案:

答案 0 :(得分:2)

您在提供的代码方面遇到了一些问题,我将尝试在下面列出其中的大多数问题:

  • 不建议使用用于更新行的方法,它可能会引入很多错误,而不是暂时设置价格/数量并稍后再更新数据,您应该直接在状态下对其进行更新。
  • 您没有绑定几种方法:

    v-for

  • 在总计列中,您应该打印此特定行的价格,而不是临时变量的价格。您还应该列出特定行的价格/数量。

  • this.handleQuantiteChange = this.handleQuantiteChange.bind(this); this.handlePrixChange = this.handlePrixChange.bind(this); this.handleselectprdtChange = this.handleselectprdtChange.bind(this);函数不仅用map来用(data, index)调用

  • 您需要将(index)绑定到index处理程序的调用中,以获取目标行。 onChange也是如此。

这是您的更正代码:

handleRowDelete

答案 1 :(得分:1)

请尝试以下更新的代码。

class AjouterFacture extends Component {
          constructor(props) {
            super(props);
            this.state = {
              rowData: [],
              Produits: [],
              Quantite: "",
              Prix: "",
              id:0
            };

            this.handleRowChange = this.handleRowChange.bind(this);
            this.handleRowDelete = this.handleRowDelete.bind(this);
            this.handleRowAdd = this.handleRowAdd.bind(this);
            this.getTotal = this.getTotal.bind(this);
            this.pushToCaller = this.pushToCaller.bind(this);
          }
  handleQuantiteChange(e) {
        this.setState({
          Quantite: e.target.value
        }, this.pushToCaller);
      }
      handleselectprdtChange(e) {
        this.setState({
          selectprdt: e.target.value
        }, this.pushToCaller);
      }
      handlePrixChange(e) {
        this.setState({
          Prix: e.target.value
        }, this.pushToCaller);
      }

          pushToCaller() {
            this.handleRowChange(this.state.id, {
              Quantite: parseInt(this.state.Quantite, 10),
              selectprdt: this.state.selectprdt,
              Prix: parseFloat(this.state.Prix),
            });
          }


          render() {

            return (<div className="animated fadeIn">


         <h6> Veuillez ajouter au moins un produit : </h6>
                <Table  >
                <thead >
                          <tr>
                            <th>PRODUIT</th>
                            <th>QUANTITE</th>
                            <th>PRIX UNITAIRE</th>
                            <th>TOTAL</th>
                            <th></th>
                          </tr>
                          </thead>
                          <tbody>
                        {this.state.rowData.map((index) =>

                        <tr key={index} id={index} 
                        onChange={this.handleRowChange}>


                 <td> <Input type="select" name="selectedcl" id="selectcl"
                                  placeholder="Veuillez sélectionner un produit"  value={this.state.rowData.selectprdt}
                  onChange={this.handleselectprdtChange} >
                   <option  key={-1} hidden>Choisisr un produit</option>


                             {  this.state.Produits.map((pdt, i) => 
                             <option key={i} >{pdt.Nomp}</option>
                             )} 


                              </Input>
                            </td>
                            <td><Input type="number" 
                                  placeholder="0" value={this.state.rowData.Quantite} onChange={this.handleQuantiteChange}/></td>
                            <td>
                                 <InputGroup ><Input type="text" 
                                  value={this.state.rowData.Prix} onChange={this.handlePrixChange} />
                                  <InputGroupAddon addonType="prepend">
                                      <InputGroupText><i ></i></InputGroupText>
                                    </InputGroupAddon>
                                         </InputGroup >
                                  </td>

                            <td >
                             <p >{this.state.Quantite * this.state.Prix}  </p>

                            </td>
                            <td>
                             <Button onClick={this.handleRowDelete} active style={center} >Effacer</Button>
              </td> </tr> )} 



                          <tr>

                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td><Button onClick={this.handleRowAdd} >Ajouter une ligne</Button></td>
                  </tr>
                </tbody>

                <tfoot>
                  <tr>

                    <th></th>
                    <th >Grand total :</th>
                    <th>{this.getTotal()} </th>
                    <th></th>
                  </tr>
        </tfoot>

                </Table>


                </div>);
          }
          getTotal() {
            let grandTotal = 0;
            const rowTotals = this.state.rowData.map(row => this.state.Quantite *  this.state.Prix);
            if (rowTotals.length > 0) {
              grandTotal = rowTotals.reduce((acc, val) => acc + val);
            }
            return grandTotal;
          }
         handleRowChange(row, data) {
            const rowDataCopy = this.state.rowData.slice(0);
            rowDataCopy[row] = data;
            this.setState({
              rowData: rowDataCopy

            });
          }  
          handleRowDelete(row) {
            const rowDataCopy = this.state.rowData.slice(0);
            rowDataCopy.splice(row, 1);
            this.setState({
              rowData: rowDataCopy
            });
          }
         handleRowAdd() {
            let id = this.state.id;
                id = id++;
            const rowDataCopy = this.state.rowData.slice(0);
            rowDataCopy.push({selectprdt:'', Quantite : "", Prix :"" });
            this.setState({
              rowData: rowDataCopy,
              id: id
            });
          }

        }
        export default AjouterFacture;