1

I have a table of invoice, and i got problem with checked or not. If checked i want all type number of tag td all calculated, if not checked dont calculated, but now, value has calculated for all. For example if I check the design and don't check the freelencer then the calculation is 10 + 0 and if I check the design and the freelencer there are 10 + 12

 $('table').on('mouseup keyup', 'input[type=number]', () => calculateTotals());

$('.btn-add-row').on('click', () => {
  const $lastRow = $('.item:last');
  const $newRow = $lastRow.clone();

  $newRow.find('input').val('');
  $newRow.find('td:last').text('$0.00');
  $newRow.insertAfter($lastRow);

  $newRow.find('input:first').focus();
});

function calculateTotals() {
  const subtotals = $('.item').map((idx, val) => calculateSubtotal(val)).get();
  const total = subtotals.reduce((a, v) => a + Number(v), 0);
  $('.total td:eq(1)').text(formatAsCurrency(total));
}

function calculateSubtotal(row) {
  const $row = $(row);
  const inputs = $row.find('input[type=number]');
  const subtotal = inputs[0].value + inputs[1].value;

  $row.find('td:last').text(formatAsCurrency(subtotal));

  return subtotal;
}

function formatAsCurrency(amount) {
  return `$${Number(amount).toFixed(2)}`;
}
.invoice-box {
  max-width: 800px;
  margin: auto;
  padding: 30px;
  border: 1px solid #eee;
  box-shadow: 0 0 10px rgba(0, 0, 0, .15);
  font-size: 16px;
  line-height: 24px;
  font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
  color: #555;
}

.invoice-box table {
  width: 100%;
  line-height: inherit;
  text-align: left;
}

.invoice-box table td {
  padding: 5px;
  vertical-align: top;
}

.invoice-box table tr td:nth-child(n+2) {
  text-align: right;
}

.invoice-box table tr.top table td {
  padding-bottom: 20px;
}

.invoice-box table tr.top table td.title {
  font-size: 45px;
  line-height: 45px;
  color: #333;
}

.invoice-box table tr.information table td {
  padding-bottom: 40px;
}

.invoice-box table tr.heading td {
  background: #eee;
  border-bottom: 1px solid #ddd;
  font-weight: bold;
}

.invoice-box table tr.details td {
  padding-bottom: 20px;
}

.invoice-box table tr.item td{
  border-bottom: 1px solid #eee;
}

.invoice-box table tr.item.last td {
  border-bottom: none;
}

.invoice-box table tr.item input {
  padding-left: 5px;
}

.invoice-box table tr.item td:first-child input {
  margin-left: -5px;
  width: 100%;
}

.invoice-box table tr.total td:nth-child(2) {
  border-top: 2px solid #eee;
  font-weight: bold;
}

.invoice-box input[type=number] {
  width: 60px;
}

@media only screen and (max-width: 600px) {
  .invoice-box table tr.top table td {
      width: 100%;
      display: block;
      text-align: center;
  }
  
  .invoice-box table tr.information table td {
      width: 100%;
      display: block;
      text-align: center;
  }
}

/** RTL **/
.rtl {
  direction: rtl;
  font-family: Tahoma, 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
}

.rtl table {
  text-align: right;
}

.rtl table tr td:nth-child(2) {
  text-align: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="invoice-box">
    <table cellpadding="0" cellspacing="0">
      <tr class="top">
        <td colspan="4">
          <table>
            <tr>
              <td class="title">
                <img src="https://www.sparksuite.com/images/logo.png" style="width:100%; max-width:300px;">
              </td>
  
              <td>
                Invoice #: 123<br> Created: January 1, 2015<br> Due: February 1, 2015
              </td>
            </tr>
          </table>
        </td>
      </tr>
  
      <tr class="information">
        <td colspan="4">
          <table>
            <tr>
              <td>
                Sparksuite, Inc.<br> 12345 Sunny Road<br> Sunnyville, CA 12345
              </td>
  
              <td>
                Acme Corp.<br> John Doe<br> [email protected]
              </td>
            </tr>
          </table>
        </td>
      </tr>
  
      <tr class="heading">
        <td colspan="3">
          Payment Method
        </td>
  
        <td>
          Check #
        </td>
      </tr>
  
      <tr class="details">
        <td colspan="3">
          Check
        </td>
  
        <td>
          1000
        </td>
      </tr>
  
      <tr class="heading">
        <td>
          Item
        </td>
  
        <td>
          Unit Cost
        </td>
  
        <td>
          Quantity
        </td>
  
        <td>
          Price
        </td>
      </tr>
  
      <tr class="item">
        <td>
          <input value="Website design" />
        </td>
  
        <td>
          $<input type="number" value="10" />
          <input type="checkbox" value="Design"> Design<br>
          $<input type="number" value="12" />
          <input type="checkbox" value="Freelencer">  Freelencer
        </td>
  
        <td>
          <input type="number" value="1" />
        </td>
  
        <td>
          $300.00
        </td>
      </tr>
  
      <tr class="item">
        <td>
          <input value="Programmer" />
        </td>
  
        <td>
          $<input type="number" value="10" />
          <input type="checkbox" value="Design"> Coding<br>
          $<input type="number" value="12" />
          <input type="checkbox" value="Freelencer">  Freelencer
        </td>
  
        <td>
          <input type="number" value="1" />
        </td>
  
        <td>
          $75.00
        </td>
      </tr>
  
      <tr class="item">
        <td>
          <input value="Server Administrator" />
        </td>
  
        <td>
          $<input type="number" value="10" />
          <input type="checkbox" value="Design"> Design<br>
          $<input type="number" value="12" />
          <input type="checkbox" value="Freelencer">  Freelencer
        </td>
  
        <td>
          <input type="number" value="1" />
        </td>
  
        <td>
          $10.00
        </td>
      </tr>
  
      <tr>
        <td colspan="4">
          <button class="btn-add-row">Add row</button>
        </td>
      </tr>
  
      <tr class="total">
        <td colspan="3"></td>
  
        <td>
          Total: $385.00
        </td>
      </tr>
    </table>
  </div>
</body>

</html>

1 Answer 1

1

The first issue you have is that you're using the + operator on two string values so it concatenates them. To perform addition you need to convert them to numeric values which can be done in this case by using parseFloat().

With regard to the issue of only calculating checked values, you can use the :checkbox:checked selector to only retrieve those boxes and then add up their values. In addition you need to multiply the result of that by the Quantity field in the same row. To make that easier I added a .quantity class to that input.

Finally, you also need to invoke calculateTotals when the page loads in order to show the correct totals for the current form state, and also when any of the checkboxes are changed.

With all that said, try this:

$('table')
  .on('input', 'input[type="number"]', () => calculateTotals())
  .on('change', ':checkbox', () => calculateTotals());
  
calculateTotals();

$('.btn-add-row').on('click', () => {
  const $lastRow = $('.item:last');
  const $newRow = $lastRow.clone();

  $newRow.find('input').val('');
  $newRow.find('td:last').text('$0.00');
  $newRow.insertAfter($lastRow);
  $newRow.find('input:first').focus();
});

function calculateTotals() {
  const subtotals = $('.item').map((idx, val) => calculateSubtotal(val)).get();
  const total = subtotals.reduce((a, v) => a + Number(v), 0);
  $('.total td:eq(1)').text(formatAsCurrency(total));
}

function calculateSubtotal(row) {
  const $row = $(row);
  let subtotal = 0;
  let qty = parseInt($row.find('.quantity').val(), 10);
  $row.find(':checkbox:checked').each(function() {
    subtotal += (parseFloat($(this).closest('label').prev().val()) * qty) || 0;
  })
  $row.find('td:last').text(formatAsCurrency(subtotal));
  return subtotal;
}

function formatAsCurrency(amount) {
  return `$${parseFloat(amount).toFixed(2)}`;
}
.invoice-box {
  max-width: 800px;
  margin: auto;
  padding: 30px;
  border: 1px solid #eee;
  box-shadow: 0 0 10px rgba(0, 0, 0, .15);
  font-size: 16px;
  line-height: 24px;
  font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
  color: #555;
}

.invoice-box table {
  width: 100%;
  line-height: inherit;
  text-align: left;
}

.invoice-box table td {
  padding: 5px;
  vertical-align: top;
}

.invoice-box table tr td:nth-child(n+2) {
  text-align: right;
}

.invoice-box table tr.top table td {
  padding-bottom: 20px;
}

.invoice-box table tr.top table td.title {
  font-size: 45px;
  line-height: 45px;
  color: #333;
}

.invoice-box table tr.information table td {
  padding-bottom: 40px;
}

.invoice-box table tr.heading td {
  background: #eee;
  border-bottom: 1px solid #ddd;
  font-weight: bold;
}

.invoice-box table tr.details td {
  padding-bottom: 20px;
}

.invoice-box table tr.item td {
  border-bottom: 1px solid #eee;
}

.invoice-box table tr.item.last td {
  border-bottom: none;
}

.invoice-box table tr.item input {
  padding-left: 5px;
}

.invoice-box table tr.item td:first-child input {
  margin-left: -5px;
  width: 100%;
}

.invoice-box table tr.total td:nth-child(2) {
  border-top: 2px solid #eee;
  font-weight: bold;
}

.invoice-box input[type=number] {
  width: 60px;
}

@media only screen and (max-width: 600px) {
  .invoice-box table tr.top table td {
    width: 100%;
    display: block;
    text-align: center;
  }
  .invoice-box table tr.information table td {
    width: 100%;
    display: block;
    text-align: center;
  }
}


/** RTL **/

.rtl {
  direction: rtl;
  font-family: Tahoma, 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
}

.rtl table {
  text-align: right;
}

.rtl table tr td:nth-child(2) {
  text-align: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <div class="invoice-box">
    <table cellpadding="0" cellspacing="0">
      <!-- irrelevant rows removed -->
      <tr class="heading">
        <td colspan="3">Payment Method</td>
        <td>Check #</td>
      </tr>
      <tr class="details">
        <td colspan="3">Check</td>
        <td>1000</td>
      </tr>
      <tr class="heading">
        <td>Item</td>
        <td>Unit Cost</td>
        <td>Quantity</td>
        <td>Price</td>
      </tr>
      <tr class="item">
        <td>
          <input value="Website design" />
        </td>
        <td>
          $<input type="number" value="10" />
          <label><input type="checkbox" value="Design"> Design</label><br>           
          $<input type="number" value="12" />
          <label><input type="checkbox" value="Freelencer"> Freelencer</label>
        </td>
        <td>
          <input type="number" value="1" class="quantity" />
        </td>
        <td></td>
      </tr>
      <tr class="item">
        <td>
          <input value="Programmer" />
        </td>
        <td>
          $<input type="number" value="10" />
          <label><input type="checkbox" value="Design"> Design</label><br>           
          $<input type="number" value="12" />
          <label><input type="checkbox" value="Freelencer"> Freelencer</label>
        </td>
        <td>
          <input type="number" value="1" class="quantity" />
        </td>
        <td></td>
      </tr>
      <tr class="item">
        <td>
          <input value="Server Administrator" />
        </td>
        <td>
          $<input type="number" value="10" />
          <label><input type="checkbox" value="Design"> Design</label><br>           
          $<input type="number" value="12" />
          <label><input type="checkbox" value="Freelencer"> Freelencer</label>
        </td>
        <td>
          <input type="number" value="1" class="quantity" />
        </td>
        <td></td>
      </tr>
      <tr>
        <td colspan="4">
          <button class="btn-add-row">Add row</button>
        </td>
      </tr>
      <tr class="total">
        <td colspan="3"></td>
        <td></td>
      </tr>
    </table>
  </div>

Sign up to request clarification or add additional context in comments.

Comments

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.