Error iterating through TR elements & building concatenated string values

41 Views Asked by At

I am trying to write a javascript function that iterates through the rows of a table, picks up modified input values and builds a concatenated string of pipe delimited values onclick. Here is an example of the table which can vary in the number of rows ...

The result is no alertbox ... please can someone let me know why the alerts work in the each function but not outside that function and how to build these strings which ultimately will be passed via ajax.

The alert boxes work at the point of collection for each TR, however the concatenation and ultimately the alert outside of the each function does not work.

function test() {
  //alert("The button was clicked.");

  var scf = '';
  var qtyf = '';
  var i = 1;
  var t = document.getElementById('my_id');

  $("#my_id tr").each(function() {
    var sc = $(t.rows[i].cells[0]).text(); //this works and returns the stockcode
    var qty = $(t.rows[i].cells[3]).find("input").val();

    //alert(sc);
    //alert(qty);

    scf = scf + '|' + sc;
    qtyf = qtyf + '|' + qty;
    i++;
  });

  alert(scf);
  alert(qtyf);
};
<table>
  <thead>
    <tr>
      <th class="column-code">Code</th>
      <th class="column-attribute">Colour</th>
      <th class="column-attribute">Size</th>
      <th class="column-qty">Qty</th>
      <th class="column-remove">&nbsp;</th>
    </tr>
  </thead>
  <tbody class="product-queue-rows">
    <tr>
      <td class="product-sku">CZSPRBP32</td>
      <td><span class="swatch swatch-royal-blue"></span> <span class="swatch-title">Royal Blue</span></td>
      <td>32</td>
      <td><label class="fancy-quantity"><input type="number" class="product-quantity" value="1" data-sku="CZSPRBP32"><a href="#" class="fq-up" title="Increase"></a><a href="#" class="fq-down" title="Decrease"></a></label></td>
      <td><a href="#" class="remove-button" title="Remove item" aria-label="Remove item" data-sku="CZSPRBP32"><svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><polygon class="svg-cross" points="17.744 20 12 14.256 6.256 20 4 17.744 9.744 12 4 6.256 6.256 4 12 9.744 17.744 4 20 6.256 14.256 12 20 17.744"></polygon></svg></a></td>
    </tr>
    <tr>
      <td class="product-sku">CZSPRBP34</td>
      <td><span class="swatch swatch-royal-blue"></span> <span class="swatch-title">Royal Blue</span></td>
      <td>34</td>
      <td><label class="fancy-quantity"><input type="number" class="product-quantity" value="1" data-sku="CZSPRBP34"><a href="#" class="fq-up" title="Increase"></a><a href="#" class="fq-down" title="Decrease"></a></label></td>
      <td><a href="#" class="remove-button" title="Remove item" aria-label="Remove item" data-sku="CZSPRBP34"><svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><polygon class="svg-cross" points="17.744 20 12 14.256 6.256 20 4 17.744 9.744 12 4 6.256 6.256 4 12 9.744 17.744 4 20 6.256 14.256 12 20 17.744"></polygon></svg></a>
      </td>
    </tr>
  </tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

1

There are 1 best solutions below

2
mplungjan On

You are not actually calling test and the selector is not targeting the rows.

jQuery can be used more efficiently. Since you have data-sku on everything, I suggest the following

const $table = $('.product-queue-rows');
const $rows = $table.find("tr");
const getVals = () => {
  const result = $rows.map(function() {
    return { [$('.product-sku',this).text()] : $('.product-quantity',this).val() }
  }).get()
  //console.log(result);
  fetch('https://httpbin.org/post', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(result)
  })
  .then(response => response.json())
  .then(data => console.log(data));
}
$table.on('change', getVals);
<table>
  <thead>
    <tr>
      <th class="column-code">Code</th>
      <th class="column-attribute">Colour</th>
      <th class="column-attribute">Size</th>
      <th class="column-qty">Qty</th>
      <th class="column-remove">&nbsp;</th>
    </tr>
  </thead>
  <tbody class="product-queue-rows">
    <tr>
      <td class="product-sku">CZSPRBP32</td>
      <td><span class="swatch swatch-royal-blue"></span> <span class="swatch-title">Royal Blue</span></td>
      <td>32</td>
      <td><label class="fancy-quantity"><input type="number" class="product-quantity" value="1" data-sku="CZSPRBP32"><a href="#" class="fq-up" title="Increase"></a><a href="#" class="fq-down" title="Decrease"></a></label></td>
      <td><a href="#" class="remove-button" title="Remove item" aria-label="Remove item" data-sku="CZSPRBP32"><svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><polygon class="svg-cross" points="17.744 20 12 14.256 6.256 20 4 17.744 9.744 12 4 6.256 6.256 4 12 9.744 17.744 4 20 6.256 14.256 12 20 17.744"></polygon></svg></a></td>
    </tr>
    <tr>
      <td class="product-sku">CZSPRBP34</td>
      <td><span class="swatch swatch-royal-blue"></span> <span class="swatch-title">Royal Blue</span></td>
      <td>34</td>
      <td><label class="fancy-quantity"><input type="number" class="product-quantity" value="1" data-sku="CZSPRBP34"><a href="#" class="fq-up" title="Increase"></a><a href="#" class="fq-down" title="Decrease"></a></label></td>
      <td><a href="#" class="remove-button" title="Remove item" aria-label="Remove item" data-sku="CZSPRBP34"><svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><polygon class="svg-cross" points="17.744 20 12 14.256 6.256 20 4 17.744 9.744 12 4 6.256 6.256 4 12 9.744 17.744 4 20 6.256 14.256 12 20 17.744"></polygon></svg></a>
      </td>
    </tr>
  </tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>