techie_28
techie_28

Reputation: 2133

Get the corresponding value of 2nd selector jQuery each

Corresponding fields

HTML is like:

<div class="sltbsummry collection">
    <div class="sltabsecondrow">
        <div> <small>Schedule</small>
        </div>
        <div> <small>Amount</small>
        </div>
    </div>
    <div class="planContainer">
        <div class="sltabsecondrow">
            <div>
                <span>
                    <input type="text" value="11-02-2019" class="schDate inputFld" readonly="">
                </span>
                <span class="pull-right">
                    <i class="fa fa-calendar"></i>
                </span>
            </div>
            <div>
                <span>
                    <input type="text" value="10000000" class="schAmt inputFld">
                </span>
                <span>
                    <a title="Remove Row" class="remRow" href="javascript:void(0);" style="display: inline;">
                        <i class="fas fa-times-circle"></i></a>
                </span>
            </div>
        </div>
        <div class="sltabsecondrow">
            <div>
                <span>
                    <input type="text" class="schDate" readonly="">
                </span>
                <span class="pull-right">
                    <i class="fa fa-calendar"></i>
                </span>
            </div>
            <div>
                <span>
                    <input type="text" class="schAmt">
                </span>
                <span>
                    <a title="Remove Row" class="remRowAdd" href="javascript:void(0);">
                        <i class="fas fa-times-circle"></i></a>
                </span>
            </div>
        </div>
        <div class="sltabsecondrow">
            <div>
                <span>
                    <input type="text" class="schDate" readonly="">
                </span>
                <span class="pull-right">
                    <i class="fa fa-calendar"></i>
                </span>
            </div>
            <div>
                <span>
                    <input type="text" class="schAmt">
                </span>
                <span>
                    <a title="Remove Row" class="remRowAdd" href="javascript:void(0);">
                        <i class="fas fa-times-circle"></i></a>
                </span>
            </div>
        </div>
        <div class="sltabsecondrow">
            <div>
                <span>
                    <input type="text" class="schDate" readonly="">
                </span>
                <span class="pull-right">
                    <i class="fa fa-calendar"></i>
                </span>
            </div>
            <div>
                <span>
                    <input type="text" class="schAmt">
                </span>
                <span>
                    <a title="Remove Row" class="remRowAdd" href="javascript:void(0);">
                        <i class="fas fa-times-circle"></i></a>
                </span>
            </div>
        </div>
    </div>
</div>

Above image shows a fieldset in which Schedule & Amount are interrelated to each other. A data set has to be formed with each row value like:

[
{date:11/02/2019,amt:1000000},
{date:13-02-2019,amt:1111},
{date:21-02-2019,amt:222}... so on
]

Following iteration was tried but I cant figure out how to get the corresponding value of the schAmt(.schDate is selector of date fields & .schAmt is of amount)

 jQuery('.schDate,.schAmt').each(function(){
       //when loop is over .schDate how to get corresponding .schAmt value?
 });

This can be done by assigning corresponding index but I was wondering if looping like this would save that overkill & always produce corresponding value set correctly?.

Upvotes: 0

Views: 88

Answers (3)

Terry
Terry

Reputation: 66133

What you need to do is to iterate through a common parent of the input elements, e.g. .sltabsecondrow, using .map() You will want to check if the element actually contains the input elements you want. If they do exist, you simply return the object, which will in turn create an array of objects as you have intended.

To access the correct input element in each iteration, you supply this as the second argument in the selector, which defines the context in which the element has to be found in, e.g. $('.schDate', this). This is equivalent to using $(this).find('.schDate'), just a bit less verbose.

Finally, you want to chain .get() at the end so that you convert the jQuery object back into a native JS array.

var data = jQuery('.sltabsecondrow').map(function() {
  var $date = $('.schDate', this);
  var $amt = $('.schAmt', this);

  // Check if both input elements exist
  // If not, return nothing
  if (!$date.length || !$amt.length)
    return;

  return {
    date: $date.val(),
    amt: $amt.val()
  };
}).get();

The advantage of using .map() over .each() is that you don't need to define another variable outside the loop to store your data.

See proof-of-concept below:

jQuery(document).ready(function() {
  var data = jQuery('.sltabsecondrow').map(function() {
    var $date = $('.schDate', this);
    var $amt = $('.schAmt', this);
    
    // Check if both input elements exist
    // If not, return nothing
    if (!$date.length || !$amt.length)
      return;
    
    return {
      date: $date.val(),
      amt: $amt.val()
    };
  }).get();
  console.log(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sltbsummry collection">
  <div class="sltabsecondrow">
    <div> <small>Schedule</small>
    </div>
    <div> <small>Amount</small>
    </div>
  </div>
  <div class="planContainer">
    <div class="sltabsecondrow">
      <div>
        <span>
                    <input type="text" value="11-02-2019" class="schDate inputFld" readonly="">
                </span>
        <span class="pull-right">
                    <i class="fa fa-calendar"></i>
                </span>
      </div>
      <div>
        <span>
                    <input type="text" value="10000000" class="schAmt inputFld">
                </span>
        <span>
                    <a title="Remove Row" class="remRow" href="javascript:void(0);" style="display: inline;">
                        <i class="fas fa-times-circle"></i></a>
                </span>
      </div>
    </div>
    <div class="sltabsecondrow">
      <div>
        <span>
                    <input type="text" class="schDate" readonly="">
                </span>
        <span class="pull-right">
                    <i class="fa fa-calendar"></i>
                </span>
      </div>
      <div>
        <span>
                    <input type="text" class="schAmt">
                </span>
        <span>
                    <a title="Remove Row" class="remRowAdd" href="javascript:void(0);">
                        <i class="fas fa-times-circle"></i></a>
                </span>
      </div>
    </div>
    <div class="sltabsecondrow">
      <div>
        <span>
                    <input type="text" class="schDate" readonly="">
                </span>
        <span class="pull-right">
                    <i class="fa fa-calendar"></i>
                </span>
      </div>
      <div>
        <span>
                    <input type="text" class="schAmt">
                </span>
        <span>
                    <a title="Remove Row" class="remRowAdd" href="javascript:void(0);">
                        <i class="fas fa-times-circle"></i></a>
                </span>
      </div>
    </div>
    <div class="sltabsecondrow">
      <div>
        <span>
                    <input type="text" class="schDate" readonly="">
                </span>
        <span class="pull-right">
                    <i class="fa fa-calendar"></i>
                </span>
      </div>
      <div>
        <span>
                    <input type="text" class="schAmt">
                </span>
        <span>
                    <a title="Remove Row" class="remRowAdd" href="javascript:void(0);">
                        <i class="fas fa-times-circle"></i></a>
                </span>
      </div>
    </div>
  </div>
</div>


Bonus

You can also do the same logic above in vanilla JS ;)

ES5

var rows = document.querySelectorAll('.sltabsecondrow');
var data = Array.prototype.map.call(rows, function(row) {
    var date = row.querySelector('.schDate');
    var amt = row.querySelector('.schAmt');

    if (!date || !amt)
        return;

    return {
        date: date.value,
        amt: amt.value
    };
}).filter(function(datum) { return !!datum; });

ES6

const rows = document.querySelectorAll('.sltabsecondrow');
const data = Array.from(rows).map(row => {
    const date = row.querySelector('.schDate');
    const amt = row.querySelector('.schAmt');

    if (!date || !amt)
        return;

    return {
        date: date.value,
        amt: amt.value
    };
}).filter(datum=> !!datum);

Upvotes: 2

Lorenz Henk
Lorenz Henk

Reputation: 781

You can iterate over the dates and amounts:

var dates = jQuery('.schDate');
var amts = jQuery('.schAmt');

for(var i = 0; i < dates.length; i++ {
  var date = dates[i];
  var amt = amts[i];
  // ...
}

Upvotes: 0

Jorrit Schippers
Jorrit Schippers

Reputation: 1655

Add a class to the row containing a matching date and amount, let's call it schRow.

Then you can do:

jQuery('.schRow').each(function() {
  var $date = jQuery('.schDate', this);
  var $amount = jQuery('.schAmt', this);
  ... your code
});

Upvotes: 1

Related Questions