0

I'm a beginner in js and someone helped me to make a js code to calculate columns when you modify quantity and calculate the total of columns. This code work fine but not for 2 things. I get the result NaN when the field is a text like "nc" (line 26 of the html exemple, it can be also other text) but i need the text displayed in the field, and also when the default value is a decimal number (like 0,9 line 20 of the html exemple). How can i modify the code to resolve these 2 options ?

(function() {
  let table = document.querySelector('#nutrition')
  let tBodyElems = table.querySelector('tbody')
  let trElems = [...tBodyElems.querySelectorAll('tr')].map(tr => {
    let td = [...tr.querySelectorAll('td')]
    td.input = tr.querySelector('input')
    td.tr = tr
    return td
  })

  let tFoot = table.querySelector('tfoot')
  let tFootTd = [...tFoot.querySelectorAll('td')]

  const updateTotal = function() {
    tFootTd.forEach((tdFoot, i) => {
      if (i === 0) {
        return
      }
      if (i === 1) {
        let total = trElems.reduce((a, e) => {
          return a + (parseInt(e.input.value))
        }, 0)
        tdFoot.textContent = total
      } else {
        let total = trElems.reduce((a, e) => {
          return a + (parseFloat(e[i].dataset.curValue) || parseFloat(e.input))
        }, 0)
        tdFoot.textContent = Math.ceil(total * 1000) / 1000
      }
    })
  }
  const updateRow = function(trElement) {
    let value = parseFloat(trElement.input.value.replace(',', '.'))
    if (value === NaN) {
      return
    }

    [...trElement].splice(2).forEach(e => {
      let newValue = Math.ceil(parseFloat(e.dataset.for100) * value) / 100
      e.textContent = newValue
      e.dataset.curValue = newValue
    })
  }
  const updateAll = function() {
    trElems.forEach(updateRow)
    updateTotal()
  }
  const debounce = function(func, wait, immediate) {
    var timeout;
    return function() {
      var context = this,
        args = arguments;
      var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
      };
      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) func.apply(context, args);
    };
  };
  window.addEventListener('DOMContentLoaded', updateAll)
  trElems.forEach(tr => {
    tr.input.addEventListener('keydown', debounce(() => {
      updateRow(tr), updateTotal()
    }, 250))
  })
})()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="container">
    <div class="row col-md-offset-2 col-md-14">
      <table class="table table-striped" id="nutrition">
        <thead>
          <tr>
            <th>Aliments</th>
            <th>Poids (Gr)</th>
            <th>Energie kJ</th>
            <th>Energie kcal</th>
            <th>Proteines</th>
        </thead>
        <tbody class="text-primary">
          <tr>
            <td>Pain grillé, domestique:</td>
            <td><input type="text" value="20gr"></td>
            <td data-for100="1430">1430</td>
            <td data-for100="336">336</td>
            <td data-for100="0,9">0,9</td>
          </tr>
          <tr>
            <td>Cabillaud, cuit à la vapeur:</td>
            <td><input type="text" value="40gr"></td>
            <td data-for100="350">350</td>
            <td data-for100="nc">nc</td>
            <td data-for100="18.6">18,6</td>
          </tr>
        </tbody>
        <tfoot>
          <td>Total</td>
          <td><strong>60gr</strong></td>
          <td data-for100="350">350</td>
          <td data-for100="82.7">82,7</td>
          <td data-for100="18.6">18,6</td>
        </tfoot>
      </table>
    </div>
  </div>
</div>
ginette
  • 55
  • 1
  • 7

1 Answers1

0

replace your statement if (value === NaN) { ... } with if (isNaN(value)) { ... }

Sventies
  • 2,314
  • 1
  • 28
  • 44