javascriptjquerymeteorspacebars

convert dynamic table into array


I have a table that updates dynamic (thank you to those who helped with my last publish/subscription inquiry) and I would like to store the data of each updated row into an array which I will then insert into a mongodb collection. My Table is as follows:

<template name="choral">
<div class="container" style="padding-top: 25px">
  <div class="table-responsive">
    <form id="orderForm">
    <table id ="productList" class="table table-borderless table-dark">
      <thead class="thead-light">
        <tr>
            <th>Title:</th>
            <th>See the Music:</th>
            <th>Hear the Music:</th>
            <th>Format:</th>
            <th>Price (per copy):</th>
            <th>Quantity:</th>
        </tr>
      </thead>
      <tbody>
         {{#each pieces}}
        <tr id="itemList">
            <td id="name">{{name}}</td>
            <td id="pdf">PDF</td>
            <td id="audio">AUDIO</td>
            <td id="format">FORMAT</td>
            <td id="price">{{score}}</td>
            <td id="qty"><input type ="number" name ="quantity"></td>
        </tr>
        {{/each}}
      </tbody>
      <tfoot>
            <tr>
                <td colspan="5"></td>
                <td><button id ="#addItems" class="button" type ="submit">Add to Cart</button></td>
            </tr>
        </tfoot>
  </table>
  </form>
  </div>
</div>  

I would like to pull the data from each row in the body of the table and store the dynamic data into an array. something like this:

Template.choral.events({
'click #addItems': function(e){
    e.preventDefault();
    var cartItem =[];

    $('#itemList tr').each(function(){
        var item = [];
        var name = $('#name',this).val();
        var price = $('#price',this).val();
        var qty = $('#qty',this).val();
            item.push({name, price, qty});
            cartItem.push([item]);
    });
    console.log(cartItem)
}

});

I don't know if this idea works when a table is populated via spacebars calls to helpers or if this is even valid use of .each(). Ultimately, the end result of these queries should result in this:

cartItems [{name1, price1, qty},{name2, price2, qty}]

Solution

  • First of all, don't produce identical id properties in the generated HTML -- that is invalid. Use class instead, like this:

        {{#each pieces}}
        <tr class="itemList">
            <td class="name">{{name}}</td>
    

    ... etc.

    Secondly, the jQuery selector $('#itemList tr') is not selecting anything because #itemList does not contain any tr descendants, but is instead itself a tr. So together with the previous remark, the selector should be $('tr.itemList').

    Then, in your jQuery code select by class attribute (using .) and do it within the this context, so you match only within the current row:

    var cartItem =[];
    
    $('tr.itemList').each(function() {
        var name = $('.name', this).val();
        var price = +$('.price', this).val(); // convert to number?
        var qty = +$('.qty', this).val(); // (idem)
        var item = {name, price, qty}; // just assign to item
        cartItem.push(item); // don't use square brackets here
    });
    

    You might want the price and qty to be converted to numbers. In that case use the unary + (see above).

    I don't think you want item to be an array, but just the object with the three properties.

    Notice also the fix in the push argument.