hiddenuser
hiddenuser

Reputation: 61

JS Loop inside the loop

Hello I have little problem with jquery. First, I have :

VW BORA 1.9TDI 1990 1995
Audi A3 2.0TFSI 2006 2008

But I want to achieve :

VW BORA 1.9TDI 1990
VW BORA 1.9TDI 1991
VW BORA 1.9TDI 1992
VW BORA 1.9TDI 1993
VW BORA 1.9TDI 1994
VW BORA 1.9TDI 1995
Audi A3 2.0TFSI 2006
Audi A3 2.0TFSI 2007
Audi A3 2.0TFSI 2008

HTML code:

<div class="make">
   <div class="name">VW BORA 1.9TDI</div><div class="start">1990</div><div class="end">1995</div>
</div>
<div class="make">
   <div class="name">Audi A3 2.0TFSI</div><div class="start">2006</div><div class="end">2008</div>
</div>

JS code:

$('div[class="make"]').each(function(index){
   var html = '';
   var start = $('.start').text();
   var end = $('.end').text();
   var name = $('.name').text();

   for (i=start; i<=end; i++) {
     html += '<div class="'+i+'">'+name+' '+i+'</div>';
   }
   $("#content").html(html)
});

If there is class .make with one content it's fine, but if class .make appears many times with different content, all the content is put together but it should be separate.

Like this:

VW BORA 1.9TDIAudi A3 2.0TFSI 19902006
VW BORA 1.9TDIAudi A3 2.0TFSI 19902007
VW BORA 1.9TDIAudi A3 2.0TFSI 19902008
VW BORA 1.9TDIAudi A3 2.0TFSI 19902009

Upvotes: 1

Views: 99

Answers (5)

Bourbia Brahim
Bourbia Brahim

Reputation: 14712

This would work for you : note that $(".class") return always an array , so in your case you should access one by one and this by using the index value.

$('div[class="make"]').each(function(index){
  
   var html = '';
   var links = '';
   var start = parseInt($(this).find(".start").text());
   var end = parseInt($(this).find(".end").text());
   var name = $(this).find(".name").text();
   
   for (i=start; i<=end; i++) {
       html += '<div class="'+i+'">'+name+' '+i+'</div>';
   }
   $("#content").append(html)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="make">
   <div class="name">VW BORA 1.9TDI</div><div class="start">1990</div><div class="end">1995</div>
</div>
<div class="make">
   <div class="name">Audi A3 2.0TFSI</div><div class="start">2006</div><div class="end">2008</div>
</div>
<br><br>
<div id="content"></div>

Upvotes: 1

Rajesh
Rajesh

Reputation: 24925

Few issues in your code:

$('div[class="make"]').each(function(index){
   var html = '';
   var start = $('.start').text();
   var end = $('.end').text();
   var name = $('.name').text();
  • You are looping on each div, but not searching based on current div. You should rather use $(this).find(".start") to get relevant fields.
  • var start = $('.start').text(); this will have value "1990" and not 1990. You should manually convert it into integer using parseInt.
  • $("#content").html(html) this will replace html in every iteration. Either use .append() or declare html variale outsite and then use .html. Note, its a bad practice to modify DOM in loop. I would suggest to move variable outside and update dom once.

Sample JSFiddle

Upvotes: 0

Azamantes
Azamantes

Reputation: 1451

(Notice that you are trying to change #content's innerHTML inside each iteration, so you get the html overriden. You might want to update the #content just once when you're finished with the loop.)

In ES6 version:

const makes = document.querySelectorAll('.make');
let string = '';

Array.from(makes).forEach(div => {
    const text = div.querySelector('.name').textContent;
    const end = +div.querySelector('.end').textContent;
    let start = +div.querySelector('.start').textContent;

    while(start <= end) {
        string += `<div class='${start}'>${text} ${start++}</div>\n`;
    }
});
document.getElementById('content').innerHTML = string;

Old Javascript version:

var makes = document.querySelectorAll('.make');
var string = '';

Array.from(makes).forEach(function(div) {
    var text = div.querySelector('.name').textContent;
    var end = +div.querySelector('.end').textContent;
    var start = +div.querySelector('.start').textContent;

    while(start <= end) {
        string += '<div class"' + start + '">' + text + ' ' + (start++) + '</div>\n';
    }
});
document.getElementById('content').innerHTML = string;

Upvotes: 0

xaggre
xaggre

Reputation: 128

First, you want to find elements inside the currently active, but you do a global lookup. To only search in the current scope do something like this:

var start = $(this).children('.start').text(); // same for .end/.name

You will also want to explicitly convert the value retrieved via text() into a number like this:

for (var i = Number(start); i <= Number(end); i++) {
    // do stuff
}

Also, defining variables you iterate over and not just use them is generally a good practice.

jQuery provides some pretty nice utilities to work with DOM elements so you don't have to use strings - like this:

var $div = $("<div>").text(name).addClass(i);
$("#content").append($div);

Upvotes: 0

eisbehr
eisbehr

Reputation: 12452

You don't determine where jQuery has to look for the other elements, so it graps all. Just let him search for start, end and name in the parent context.

And use html() instead of text() to only get the elements content.

$('div[class="make"]').each(function(index){
    var parent = $(this),
        html = links = '',
        start = $('.start', parent).html(),
        end = $('.end', parent).html(),
        name = $('.name', parent).html();

    for( var i = start; i <= end; i++ ) {
        html += '<div class="' + i + '">' + name + ' ' + i + '</div>';
    }

    $("#content").html(html)
});

That should work.

Upvotes: 0

Related Questions