0

So I have a loop that displays html tables from a text file onto a page, and it does so until it has used all of the available txt files that match a line from an array that i have predetermined in another part of the code.

The only problem is that while the loop is going, and all of the tables are loading, the page just sits there and looks blank. It can take a long time to load, especially on slow internet. I need to be able to load about 10 tables at a time, and then have a button at the bottom of the page that says "Click here to show more results" that causes 10 more tables to load, until all of the available tables are used.

How might I go about this? I've tried putting loops inside of loops and using a bunch of complicated if statements, but all to no avail.

Here is the loop:

  arrayFinal[arrayln2]="end";
  var displayNumber=0;
  while(arrayFinal[displayNumber].charAt(0) != "e"){
    var boxPath="camper_htmls/"+arrayFinal[displayNumber]+".txt";
    boxhttp = new XMLHttpRequest();
    boxhttp.open("GET",boxPath,false);
    boxhttp.send(null);
    var boxHTML = boxhttp.responseText;
    var setDivId=document.createAttribute("id");
    setDivId.value=("div_"+displayNumber);
    var node = document.createElement("div");
    node.setAttributeNode(setDivId);
    document.getElementById("resultContainer").appendChild(node);
    var divIdNumber = ("div_"+displayNumber);
    document.getElementById(divIdNumber).innerHTML=boxHTML;
    displayNumber++;
  }
nife552
  • 213
  • 1
  • 2
  • 8
  • You have to process your data asynchronously. Have a look at `setTimeout`: https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout or simply make an asynchronous request. – Felix Kling Mar 15 '13 at 19:10
  • 1
    Is there any reason you've set your AJAX to be synchronous? This really goes against the technology and it is probably what's causing your problem at the moment – Benjamin Gruenbaum Mar 15 '13 at 19:12
  • @BenjaminGruenbaum Because when it is set to true, it doesn't work, and I don't know how to fix it. To be honest, I don't know what the difference actually is. I'm fairly new to all of this, so I still have a lot to learn. – nife552 Mar 15 '13 at 19:38
  • That's because you probably don't understand how callbacks work yet. It's crucial to your success as a JavaScript programmer. Read up an AJAX tutorial, you're also welcome to come, ask and learn in the StackOverflow JavaScript chatroom – Benjamin Gruenbaum Mar 15 '13 at 19:40
  • @BenjaminGruenbaum does the one on w3schools teach you how callbacks work? – nife552 Mar 15 '13 at 19:47
  • 1
    Have a look at my answer [here](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call-from-a-function). It explains a bit how Ajax works. w3schools is usually a not so good source. – Felix Kling Mar 15 '13 at 21:02
  • I completely agree with Felix – Benjamin Gruenbaum Mar 16 '13 at 01:25

4 Answers4

0
The `setTimeout()`

    var i = 1;                     //  set your counter to 1

    function myLoop () {           //  create a loop function
       setTimeout(function () {    //  call a 3s setTimeout when the loop is called
          alert('hello');          //  your code here
var boxPath="camper_htmls/"+arrayFinal[displayNumber]+".txt";
boxhttp = new XMLHttpRequest();
boxhttp.open("GET",boxPath,false);
boxhttp.send(null);
var boxHTML = boxhttp.responseText;
var setDivId=document.createAttribute("id");
setDivId.value=("div_"+displayNumber);
var node = document.createElement("div");
node.setAttributeNode(setDivId);
document.getElementById("resultContainer").appendChild(node);
var divIdNumber = ("div_"+displayNumber);
document.getElementById(divIdNumber).innerHTML=boxHTML;
displayNumber++;
    enter code here
          i++;                     //  increment the counter
          if (i < 10) {            //  if the counter < 10, call the loop function
             myLoop();             //  ..  again which will trigger another 
          }                        //  ..  setTimeout()
       }, 3000)
    }

    myLoop();
Vitthal
  • 546
  • 3
  • 18
  • 1
    How is that anything like what OP wanted? – Benjamin Gruenbaum Mar 15 '13 at 19:11
  • The reason it's lagging while it's loading is because he has asynchronous set to false. – Zachrip Mar 15 '13 at 19:11
  • but here you have it used as an actual pause. How could I set it to continue when the user clicks a button? – nife552 Mar 15 '13 at 19:18
  • You would do this by storing the result of your setTimeout() call to some variable, and then passing the result that you stored to clearTimeout() when the button is clicked, before scheduling a new timeout and assigning it back to the same variable. Sounds a bit tricky but it's really very simple. Here is an example: http://jsfiddle.net/kzDdq/ – Vitthal Mar 15 '13 at 19:24
0

EDIT: I'm going to give you a nice jsfiddle showing how to properly use async requests.

Here try this(it's now asynchronous, that way it won't do what you're describing):

arrayFinal[arrayln2]="end";
var displayNumber=0;
while(arrayFinal[displayNumber].charAt(0) != "e"){
var boxPath="camper_htmls/"+arrayFinal[displayNumber]+".txt";
boxhttp = new XMLHttpRequest();
boxhttp.open("GET",boxPath,true);
boxhttp.send(null);
var boxHTML = boxhttp.responseText;
var setDivId=document.createAttribute("id");
setDivId.value=("div_"+displayNumber);
var node = document.createElement("div");
node.setAttributeNode(setDivId);
document.getElementById("resultContainer").appendChild(node);
var divIdNumber = ("div_"+displayNumber);
document.getElementById(divIdNumber).innerHTML=boxHTML;
displayNumber++;
} 
Zachrip
  • 3,242
  • 1
  • 17
  • 32
0

Why not add a counter to your while loop? i.e.

function runTenTimes(){
    var i=0;
    while((there_is_text)&&(i<10){
        do stuff;
        i++;
    }
}
ckersch
  • 7,507
  • 2
  • 37
  • 44
  • The reason it's lagging while it's loading is because he has asynchronous set to false. – Zachrip Mar 15 '13 at 19:10
  • the problem comes when I try to unpause it. I could use multiple while loops with different numbers compared to i, but then on pages where only 2-3 tables are displayed, it would mess up – nife552 Mar 15 '13 at 19:25
  • If you have a `(there_is_text)` variable that returns false once there are no more tables, your while loop will exit after either 10 tables are created or else after all the data is in tables. You don't need to set different numbers for `i`, either, just run the whole `runTenTimes` function each time you want ten more tables, and `i` will initialize to 0 and then loop up to 10. – ckersch Mar 18 '13 at 13:38
0

I would not use loops but instead use the callback of the XMLHttpRequest to request the next item when one is finished

arrayFinal[arrayln2]="end";
var displayNumber=0;
function callback(){
    if((arrayFinal[displayNumber].charAt(0) != "e"){
        var boxPath="camper_htmls/"+arrayFinal[displayNumber]+".txt";
        boxhttp = new XMLHttpRequest();
        boxhttp.open("GET",boxPath,true);
        boxhttp.onreadystatechange(function(){
            var boxHTML = boxhttp.responseText;
            var setDivId=document.createAttribute("id");
            setDivId.value=("div_"+displayNumber);
            var node = document.createElement("div");
            node.setAttributeNode(setDivId);
            document.getElementById("resultContainer").appendChild(node);
            var divIdNumber = ("div_"+displayNumber);
            document.getElementById(divIdNumber).innerHTML=boxHTML;
            callback();
        });
        displayNumber++;
        boxhttp.send(null);            
    }
}
callback();