Rails Jquery compute total from selected checkboxes in a table

假如想象 提交于 2021-02-19 05:30:26

问题


So here is my rails view which has a form which pulls the product_items and lets the user check all the items they want to buy and display the total order amount underneath the table. (attached pic)

My code looks like below. The server side is good (where I can save the order) but I need some help on the client side js to compute the order total and displaying the order total underneath the table.

    <tbody>
    <% @cause.product.product_items.each do |item|  %>
    <tr>
      <td width="60%"><label class="checkbox"><%= f.check_box(:items, { multiple:true, class: 'item_checkbox' }, item.id, nil) %><i></i><%= item.title %></label></td>

      <td>
        <label class="select">
        <select name="items[<%= item.id %>][qty]">
        <option value="0" selected disabled>Qty</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6</option>
        <option value="7">7</option>
        <option value="8">8</option>
        <option value="9">9</option>
        <option value="10">10</option>

        </select>
        <i></i>
        </label>
      </td>
      <td><b><big><%= number_to_currency(item.price, precision: 0) %></big></b></td>
    </tr>
    <% end %>

</tbody>
</table>
</div>
<label><strong>Total order amount: </strong><span class="lead" id="order_amount"></span></label>

Here is some js, I wanted to identify the checkbox which is checked and grab the qty in that table row (again not sure how to do this)

$(".item_checkbox").change(function() {
  if ($(this).is(":checked")) {

   alert($(this).siblings($('#select option:selected').text()));
  }
});

回答1:


In order to calculate the total amount, you will have to watch for changes for products that get selected/unselected and products quantity that gets changed as well.

You could update your view to look like this (things were left out for the sake of simplicity):

<table id="product-items">
  <tbody>
    <% @cause.product.product_items.each do |item|  %>
      <%= tag :tr, data: { price: item.price } do %>
        <td>
          <label class="checkbox">
           <%= f.check_box(:items, class: 'item_checkbox', item.id) %>
           <%= item.title %>
          </label>
        </td>
        <td>
          <label class="select">
          <select>...</select>
        </td>
        <td>
          <%= number_to_currency(item.price, precision: 0) %>
        </td>
      <% end %>
    <% end %>
  </tbody>
</table>
<div id='total-amount'></div>

As you noticed, I used the tag helper in order to create an HTML5 data attribute with the name price. I did that in order to make it easier to get the product value later on.

Now, since you have your view in place, all you have to do is calculate iterate through the item list every time a product checkbox gets checked/unchecked or a product's quantity changes. You could have something like this:

// This line will add event listeners both to your inputs and selects
// under the #products-items table
$('#product-items input[type=checkbox], #product-items select').change(function(e) {

  // Initialize vars
  var totalAmount = 0;

  // We need only rows that have checked checkboxes
  var $tableRows = $('#product-items tr').has('input[type=checkbox]:checked');

  // Iterate through each row in order get all needed info
  $.each($tableRows, function(i, row) {
    var $row = $(row);

    // Get the quantity for current product
    var quantity = row.find('select').val();

    // You could uncheck the product if quantity is set to 0
    // for better user experience
    if (quantity === 0) {
      $row.find('input').prop('checked', false);
    } else {
      // Get the product price from the data-price attribute
      var price = $row.data('price');

      // I am converting the price to an integer, but you could
      // change that and use parseFloat if you want to
      totalAmount += parseInt(price) * parseInt(quantity);
    }
  });

  $('#total-amount').text('$' + totalAmount);
});

This way every time you change the quantity or check/uncheck a product, the total amount will be calculated from the beginning.




回答2:


Thanks for the help form @ioannis, here is my final answer which solved my problem. This also displays an order summary.

$('#product-items input[type=checkbox], #product-items select').change(function(e) {

  // Initialize vars
  var totalAmount = 0;
  var totalItemAmount = 0;
  $('#order_summary').text('');
  // We need only rows that have checked checkboxes

  $("input:checkbox:not(:checked)")

  var $tableRowsNotChecked = $('#product-items tr').has('input[type=checkbox]:not(checked)');

  $.each($tableRowsNotChecked, function(i, row) {
    var $row1 = $(row);
    $row1.find('.item_qty').hide();

  });

  var $tableRows = $('#product-items tr').has('input[type=checkbox]:checked');

  // Iterate through each row in order get all needed info
  $.each($tableRows, function(i, row) {

    // Get the quantity for current product
    var $row = $(row);
    var qty = $row.find('select').val();
    $row.find('.item_qty').show();

    // You could uncheck the product if quantity is set to 0
    // for better user experience
    if (qty === 0) {
      $row.find('input').prop('checked', false);
    } else {
      // Get the product price from the data-price attribute
      var price = $row.data("price");
      var item = $row.data("item-name");

      // I am converting the price to an integer, but you could
      // change that and use parseFloat if you want to
      totalItemAmount = parseInt(price) * parseInt(qty);
      totalAmount += totalItemAmount;
      $('#order_summary').append( "<tr><td>" + item + "</td><td>" + qty + "</td><td>$" + parseInt(totalItemAmount) + "</td></tr>");
    }
  });
  $('#order_summary').append( "<tr><td></td><td><strong>Total Amount:</td><td>$" + totalAmount + "</td></strong></tr>");
  $('#order-amount').text(totalAmount);
  $('#cause_amount').val(totalAmount);
  $( "#cause_amount" ).trigger( "change" );
  // $('input.submit_contribution').val('Buy Now');
});


来源:https://stackoverflow.com/questions/36704155/rails-jquery-compute-total-from-selected-checkboxes-in-a-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!