Tom Reeve
Tom Reeve

Reputation: 107

jQuery iterate through elements within another element

I have HTML like this:

<div class="foo">
    <div class="bar1">A</div>
    <div class="bar2">B</div>
    <div class="bar3">C</div> 
</div>
<div class="foo">
    <div class="bar1">D</div>
    <div class="bar2">E</div>
    <div class="bar3">F</div> 
</div>
<div class="foo">
   ...etc.

I am trying to iterate through the "foo" divs to create objects like {bar1: A, bar2: B, bar3: C} with code sort of like this:

var arrayOfObjects= [];
var rows = $(".foo");

for (var i=0; i<rows.length; i++) {
    var row = rows[i];

    arrayOfObjects.push(
        { 
            bar1: row.find(".bar1").text(),
            bar2: row.find(".bar2").text(),
            bar3: row.find(".bar3").text()
        }
    );
}

I understand that this doesn't work because the original var rows = $(".foo"); creates an array of DOM elements, which don't have find() as a function. I also know that within the loop, I could start using elementByClass and innerHtml, but I feel like my brain starts crying whenever I start mixing jQuery-style and DOM-style selectors in the same code.

Is there a way to fix my code above so that I'm using jQuery selectors within the loop?

Upvotes: 2

Views: 52

Answers (5)

Taplar
Taplar

Reputation: 24965

             //find all the foo, and map them into new elements
var result = $('.foo').map(function(index, element){
  //we want to map all the children of the element into a single object
  return $(element).children().get().reduce(function(aggregate, childElement){
    //get the class off of the child and it's value, put them in the object
    aggregate[childElement.className] = childElement.innerText;
    
    return aggregate;
  }, {}); //second argument to the reduce() is the starting element
}).get(); //use get() to break the array out of the jQuery object

console.log(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo">
    <div class="bar1">A</div>
    <div class="bar2">B</div>
    <div class="bar3">C</div> 
</div>
<div class="foo">
    <div class="bar1">D</div>
    <div class="bar2">E</div>
    <div class="bar3">F</div> 
</div>

Upvotes: 1

Anjana Silva
Anjana Silva

Reputation: 9191

You can easily iterate through .row divs by using each(),

 var arrayOfObjects= [];   
 $(".foo").each(function(){
      var items = {"bar1" : $(this).find('.bar1').text(),"bar2" : $(this).find('.bar2').text(), "bar3" : $(this).find('.bar3').text()};    
      arrayOfObjects.push(items); //If you want to push all into an object and then into an array

      //or to use it on its own
      $(this).find('.bar1').text();
      $(this).find('.bar2').text();
      $(this).find('.bar3').text();
 });

Hope this helps.

Upvotes: 1

D Lowther
D Lowther

Reputation: 1619

Something along these lines with .each would probably work

const $rows = $('.foo');
let arrayOfObjects = [];

$rows.each(function(i) {
  const $row = $(this);
  let obj = {};
  $row.children().each(function(ch) {
    obj = { ...obj, [this.className]: $(this).text() };
  });
  arrayOfObjects = [ ...arrayOfObjects, obj ];
});

console.log(arrayOfObjects);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo">
    <div class="bar1">A</div>
    <div class="bar2">B</div>
    <div class="bar3">C</div> 
</div>
<div class="foo">
    <div class="bar1">D</div>
    <div class="bar2">E</div>
    <div class="bar3">F</div> 
</div>

Upvotes: 0

fanjabi
fanjabi

Reputation: 1675

$(document).ready(() => {
  var arrayOfObjects = $('.foo').map(function() {
    return $(this).find('>*').map(function(obj) {
      return {
        class: $(this).attr('class'),
        text: $(this).text()
      };
    }).get().reduce( (obj, arr) => {
      obj[arr.class] = arr.text;
      return obj;
    }, {});
  }).get();
  
  console.log(arrayOfObjects);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo">
    <div class="bar1">A</div>
    <div class="bar2">B</div>
    <div class="bar3">C</div> 
</div>
<div class="foo">
    <div class="bar1">D</div>
    <div class="bar2">E</div>
    <div class="bar3">F</div> 
</div>

hope this helps you :)

Upvotes: 0

Poul Bak
Poul Bak

Reputation: 10929

You can wrap your elements as jQuery objectslike this:

arrayOfObjects.push(
    { 
        bar1: $(row).find(".bar1").text(),
        bar2: $(row).find(".bar2").text(),
        bar3: $(row).find(".bar3").text()
    }
);

This makes you row a JQuery object, which has the 'find' method.

Upvotes: 1

Related Questions