I still have mastered the syntax to jQyery. With the following code

    //kick off the process
    $.ajax({         
url: 'send_email.php',
success: function(data) {}
});

send_emal.php is started as soon at the home page gets focus. I would like to start the page on the click of #start_button. How can I implement that?

Once that page is started, the following jQuery script is run:

    //start polling
    (function poll(){
       setTimeout(function(){
          $.ajax({ 
             url: "get_progress.php", 
             success: function(data){
                 //Update the progress
                 if (data.length > 0) {
                   $("#send_results").html(data);
                 } else {
                   $("#send_results").html("");
                 }
                 //Setup the next poll recursively
                 poll();
             }, 
             dataType: "text"
         });
      }, 3000);
    })();    

I would like a way to stop it. For instance, this happens when the loop is finished:

  // Return to calling page
  header("location: ./index.php?finished=1");

Is that possible to do?

Sorry for being such a newbie, but I have to start somewhere.

Todd

    Move your code inside a .click() call:

    $(document).ready(function()
    {
        $('#start_button').click(function(event)
        {
            //kick off the process
            $.ajax({         
    url: 'send_email.php',
    success: function(data) {}
    }); }); });

    Not sure what you mean by home page gets focus, though.

      That you so much for the help...it works perfectly: http://www.toddcary.com/test/ajax3/index.php

      I needed to make a couple of changes that included putting in the hide() and show(), otherwise the last count (10) would show before pressing Start. Another change is that the start script and the polling script had to be put within the same function. I guess these are things one learns with time and experience.

      I would like to have the script end with a "Finished", but I am not sure where to add that. Suggestions welcomed.

      <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
        <head>
          <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8" />
          <title>Learn Ajax</title>
          <script src="http://code.jquery.com/jquery-latest.min.js"></script>
          <script type="text/javascript">
          $(document).ready(function()
          {
          // Hide the results
          $( "#send_results" ).hide();
          //kick off the process
          $('#startButton').click(function(event) {
            $.ajax({         
      url: 'send_email.php',
      success: function(data) {}
      }); //start polling (function poll(){ setTimeout(function(){ $.ajax({ url: "get_progress.php", success: function(data){ // Show the results $( "#send_results" ).show(); //Update the progress if (data.length > 0) { $("#send_results").html(data); } else { $("#send_results").html(""); } //Setup the next poll recursively poll(); }, dataType: "text" }); }, 3000); })(); // Polling
      }); //Start button pressed }); </script> </head> <body> <h1> Learn about polling with AJAX</h1> <form id="countform" method="post"> <div> <p>Press Start to send emails</p> <p>Simulation: 10 emails will be sent: 1/sec</p> <input id="startButton" type="button" value="Start" /> </div> </form> <!-- Progress will be put here --> <div id="send_results"></div> </body> </html>

      Todd

        This works, however I do not understand why the loop, when finished, causes the loop to stop. Any clarification would be appreciated.

        http://www.toddcary.com/test/ajax3/index.php

            <script type="text/javascript">
            $(document).ready(function()
            {
            // Hide the results
            $( "#send_results" ).hide();
            //kick off the process
            $('#startButton').click(function(event) {
              $.ajax({         
        url: 'send_email.php',
        success: function(data) {}
        }); //start polling (function poll(){ setTimeout(function(){
        $.ajax({ url: "get_progress.php", success: function(data){ // Show the results $( "#send_results" ).show(); //Update the progress if (data.length > 0) { $("#send_results").html(data); } else { $("#send_results").html(""); } poll(); }, dataType: "text" }); $(document).ajaxStop(function(){ // This updates with "Finished" $("#send_results").html("Finished"); }); }, 3000); })(); // Polling
        }); //Start button pressed }); </script>

          Perhaps you get confused because the loop never actually does stop. And it's not a loop, it's recursion. It's recursion with no end condition: poll will always call itself.

          Load the page using Chrome. Rclick anywhere in the page, click ”inspect element”, then click ”network” in the new window. Click the button that initiates the entire process. As you can see, it never stops sending ajax requests. (other browsers have similar tools - use whatever tools you find suitable. but do use them)

          You should also change some other things. First off, you start by performing an ajax request, and then you proceed to register an event handler for ajaxStop (which will be called whenever an ajax request finishes if there are no other ajax requests in progress. If the first ajax requests finishes quickly enough, you will not have registered the ajaxStop handler in time, and it will not fire (the first time). Thus, the order in which these things are done ought to be changed.

          But more importantly, you register a new identical anonymous function for each new ajax request which means that
          - after the first ajax request is done, one anonymous function is called on ajaxStop
          - after the second ajax request is done, two anonymous functions are called on ajaxStop

          - after the 100th ajax request is done, 100 anonymous functions are called on ajaxStop

          I don't believe that these identical functions actually have to be separate functions, but I'd guess that they will be separate functions in current javascript implementations.


          I recommend changing the logic by refactoring the outermost doEverythingFunction (the document ready handler) so that

          - it registers one event handler for the button click called something like sendEmail, but nothing else
          
          - you define sendEmail outside of the document ready handler
          - sendEmail only performs the first ajax request (to send email)
          - you break out everything dealing with polling for progress into a function called something like poll
          - define poll outside the document ready function
          
          - then go back to the first ajax request (in sendEmail), and on success...
            - call function poll
          
          - poll now only performs an ajax request
          - which on success...
            - checks if job is not done...
              - and then calls itself (using setTimeout - You only need the timeout when recalling poll)
            - if job is done… well, then the job is done. no need for poll to call itself again.
          

          Please note that the call to setTimeout now will only specify an already defined function to call, rather than defining a new identical function every time. If you only call setTimeout once, then you may just as well define an anonymous function in place. But otherwise you are better off defining the function once and calling it many times. This is similar to how

          function foo() { /* function body */ }
          foo();
          foo();
          

          is preferable to

          (function () { /* function body */ }());
          (function () { /* function body */ }());
          

            johanafm -

            Thank you for taking the time for your detailed answer to my trying to grasp jQuery, especially AJAX. Unfortunately, I am a newbie at these more complex uses of jQuery, but I am trying. You suggested that

            • you define sendEmail outside of the document ready handler

            Does this fulfill that?

                $(document).ready(function()
                {
                // Hide the results
                $( "#send_results" ).hide();
                //kick off the process
                $('#startButton').click(function(event) {
                  $.ajax({         
            url: 'send_email.php',
            success: function() {poll()}
            }); }); });

            Then you suggest that I do this:

            • you break out everything dealing with polling for progress into a function called something like poll
            • define poll outside the document ready function
                //start polling
                function poll(){
                   setTimeout(function(){        
            $.ajax({ url: "get_progress.php", success: function(data){ // Show the results $( "#send_results" ).show(); //Update the progress if (data.length > 0) { $("#send_results").html(data); } else { $("#send_results").html(""); } }, dataType: "text" }); }, 3000); }; // Polling

            In the poll() function, "get_progress.php" is accessed. However, I do not know how to make it loop back to poll again.

            Or do I still have some bad logic errors?

            With appreciation,

            Todd

              Write a Reply...