2

I have a dynamic table as you see on the figure below :

enter image description here

I try to display the value of "Grand total", but it's still always 0. This is the sum of total for each row.

My code is below :

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

      displayedPrice: 0
    };

    this.handleRowDelete = this.handleRowDelete.bind(this);
    this.handleRowAdd = this.handleRowAdd.bind(this);
    this.getTotal = this.getTotal.bind(this);
    this.handleselectprdtChange = this.handleselectprdtChange.bind(this);
    this.PrixDisplay = this.PrixDisplay.bind(this);
    this.handleQuantiteChange = this.handleQuantiteChange.bind(this);
  }
  componentWillReceiveProps(nextProps) {
    console.log("nextProps", nextProps);
  }
  componentDidMount() {

    axios({
      method: "get",
      url: "/app/getNomprod/",
      withCredentials: true,
    }).then(response => {
      if (response && response.data) {
        this.setState({
          Produits: response.data
        });
      }
    }).catch(error => console.log(error));
  }

  handleQuantiteChange(index, value) {
    const rowDataCopy = this.state.rowData.slice(0);
    rowDataCopy[index] = Object.assign({}, rowDataCopy[index], {
      QuantiteF: parseInt(value, 10)
     // QuantiteF: value

    });

    this.setState({
      rowData: rowDataCopy
    });
  }

  handleselectprdtChange(index, value) {
    const rowDataCopy = this.state.rowData.slice(0);
    rowDataCopy[index] = Object.assign({}, rowDataCopy[index], {
      selectprdt: value
    });
    return axios
      .get('/app/getPrixprod/' + value)
      .then(response => {
        if (response && response.data) {
          this.setState(({Prix}) => ({
            rowData: rowDataCopy,
            Prix: [...Prix, ...response.data]

          }));
        }
      })
      .catch(error => {
        console.error(error);
      });
  }

  render() {
    let {
      Produits
    } = this.state;
    let {
      rowData
    } = this.state.rowData;
    let {
      Prix
    } = this.state.Prix;
    return (<div className="animated fadeIn">


 <h6>  <Label ><strong>Veuillez ajouter au moins un produit :  </strong></Label></h6>
        <Table responsive style={items} >
        <thead style={back}>
                  <tr>
                    <th>PRODUIT</th>
                    <th>QUANTITE</th>
                    <th>PRIX UNITAIRE</th>
                    <th>TOTAL</th>
                    <th></th>
                  </tr>
                  </thead>
                  <tbody>
                {this.state.rowData.map((data, index) => (
              <tr key={index} id={index}>
                <td>
                  {" "}  <Input type="select" name="selectprdt" id="selectprdt"
                          placeholder="Veuillez sélectionner un produit"  value={data.selectprdt}
                    onChange={(e) => this.handleselectprdtChange(index, e.target.value)} >
           <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="text" 
                          value={data.QuantiteF || 0} onChange={(e) => this.handleQuantiteChange(index, e.target.value)}/></td>


                    <td>


                    {<p key={index}>{this.state.Prix[index] && this.state.Prix[index].PrixV} </p>}

                        </td>

                <td  > 


                    { <p key={index} className='pa2 mr2 f6'>{(data.QuantiteF || 0) * ((this.state.Prix[index] && this.state.Prix[index].PrixV)|| 0)}  </p>}



                    </td>
                    <td>
                     <Button onClick={(e) => this.handleRowDelete(index)} active style={center}  size="sm" color="danger" className="btn-pill" aria-pressed="true">Effacer</Button>
      </td>{" "}
              </tr>
            ))}



                  <tr>

            <td/>
            <td/>
            <td/>
            <td/>
            <td><Button onClick={this.handleRowAdd} active style={center}  size="sm" color="info" className="btn-pill" aria-pressed="true">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 => (row.QuantiteF * row.Prix) || 0);
    if (rowTotals.length > 0) {
      grandTotal = rowTotals.reduce((acc, val) => acc + val);
    }
    return grandTotal;
  }
  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: "",
      QuantiteF: 0,
      Prix: ""
    });
    this.setState({
      rowData: rowDataCopy,
      id: id
    });
  }
}
export default AjouterFacture;

My backend :

exports.ajouterfact = function(req, res) {
    console.log("req", req.body);
    var today = new Date();

    var factures = {

        "Nomp": req.body.Nomp,
        "QuantiteF": req.body.QuantiteF,

    }
    connection.query('INSERT INTO factures SET ?', factures, function(error, results, fields) {
        if (error) {
            console.log("error ocurred", error);
            res.send({
                "code": 400,
                "failed": "error ocurred"
            })
        }
        else {
            //  console.log('The solution is: ', results);
            res.send({
                "code": 200,
                "success": "facture registered sucessfully"
            });
        }

    })
};

My table :

CREATE TABLE factures (
 Nomp varchar(20) REFERENCES produits (Nomp),
 QuantiteF  varchar(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;

I want to get the sum of the total for each row ! My scenario is when I choise the product name, it's price will be displayed, and when I put the quantity number, the total column will be displayed ! I want to display the sum of the total for each row.

How can I fix that please ?

Ichrak Mansour
  • 1,850
  • 11
  • 34
  • 61
  • try deleting the `|| 0` in `const rowTotals = this.state.rowData.map(row => (row.QuantiteF * row.Prix) || 0);` – evgeni fotia Sep 05 '18 at 16:08
  • @evgenifotia it's still `0` – Ichrak Mansour Sep 05 '18 at 16:11
  • do this and check the console `const rowTotals = this.state.rowData.map(row =>{ console.log(row.QuantiteF +"//"+row.Prix) return (row.QuantiteF * row.Prix) });` – evgeni fotia Sep 05 '18 at 16:19
  • @evgenifotia when I put `1` on the quantity, it's just returns `1//` and doesn't return the price, because it's getting by axios on the `handleselectprdtChange` method – Ichrak Mansour Sep 05 '18 at 16:25
  • can you console log the rowData in `handleselectprdtChange` after setState like this `this.setState(({Prix}) => ({ rowData: rowDataCopy, Prix: [...Prix, ...response.data] }),()=>{ console.log(this.state.rowData) });` I want to know how does rowData look there – evgeni fotia Sep 05 '18 at 16:35
  • @evgenifotia it returns `[{…}]0: Prix: ""QuantiteF: 1selectprdt: "BBG"__proto__: Objectlength: 1__proto__: Array(0)` – Ichrak Mansour Sep 05 '18 at 17:05
  • it doesn't seem to me that you are updating the price in rowData. it's always equal to empty string thats way when you multiply price with any number it return 0 – evgeni fotia Sep 05 '18 at 17:07
  • @evgenifotia but it's displayed for each row ! – Ichrak Mansour Sep 05 '18 at 17:08
  • because you are getting it from `this.state.Prix` and not `this.state.rowData` – evgeni fotia Sep 05 '18 at 17:11
  • @evgenifotia How can I fix that please ? – Ichrak Mansour Sep 05 '18 at 17:12
  • 1
    try adding this `rowDataCopy[index].Prix = response.data;` before `this.setState(({Prix}) => ({ rowData: rowDataCopy, Prix: [...Prix, ...response.data] }));` – evgeni fotia Sep 05 '18 at 17:17
  • @evgenifotia it returns `[{…}] 0 : {selectprdt: "Ultimaker", QuantiteF: 2, Prix: Array(1)} length : 1 __proto__ : Array(0)` – Ichrak Mansour Sep 05 '18 at 17:23
  • 1
    Ah, your reponse.data is an array just do `rowDataCopy[index].Prix = response.data[0];` – evgeni fotia Sep 05 '18 at 17:25
  • @evgenifotia it returns `[{…}] 0 : Prix : {PrixV: "310.000"} QuantiteF : 0 selectprdt : "BBG" __proto__ : Object length : 1 __proto__ : Array(0)` But about the quantity, it returns the number of quantity if I put the number before I select the name of product, if not, it returns it to `0` that's way I returns NaN on my Grand total – Ichrak Mansour Sep 05 '18 at 17:31
  • first is seem that you should do `rowDataCopy[index].Prix = response.data[0].PrixV;` as for the second problem can you console log rowDataCopy in `handleQuantiteChange` – evgeni fotia Sep 05 '18 at 17:39
  • @evgenifotia the two console returns `[{…}] 0 : {selectprdt: "Canon", QuantiteF: 0, Prix: "900.000"} length : 1 __proto__ : Array(0)` but, after I select the name of prodcut, I put the quantity `1` and not `0` – Ichrak Mansour Sep 05 '18 at 18:31
  • 1
    can you console log ` rowDataCopy[index]` after `rowDataCopy[index] = Object.assign({}, rowDataCopy[index], { QuantiteF: parseInt(value, 10) // QuantiteF: value });` in `handleQuantiteChange` because it's the only place where the quantity is update and console log the `value` too – evgeni fotia Sep 05 '18 at 18:42
  • @evgenifotia it works well ! Thank you .. but, why when I submit it, Quantity will be saved as `' '` and Name of product `null` on the table mySQL – Ichrak Mansour Sep 05 '18 at 20:19
  • I can't know that from this code you have to upload the code of submitting and the backend – evgeni fotia Sep 05 '18 at 20:39
  • @evgenifotia I updated my code such as the backend works well with Postman. – Ichrak Mansour Sep 05 '18 at 20:56
  • I don't see any issue maybe the `,` after `"QuantiteF": req.body.QuantiteF` try deleting it. (PS: I never used mysql with nodejs) – evgeni fotia Sep 05 '18 at 21:28
  • @evgenifotia It doesn't work, ah okey no problem. Thank you. – Ichrak Mansour Sep 05 '18 at 21:39

0 Answers0