http://www.perlmonks.org?node_id=900187

isi has asked for the wisdom of the Perl Monks concerning the following question:

I have a cgi that generates color maps. I can generate different years by varying 1 paramter. So I thought I could provide a link to a JavaScript function that would move through the years recurively as follows.

function simulate(parms) { var parts = parms.split('\|'); yrs = new Array; yrs = parts[2].split('~'); for( var i=0; i < yrs.length; i++ ) { document.location = 'http://' + parts[0] + '/scx/darea.cgi?str=' + + parts[1] + '_' + yrs[i]; } }
The parameters are correct and the 'for' years are right. But it generates the first year and stops. I have added a sleep function and it generates all five years, but they are not shown. Any help would be appreciated. isi

Replies are listed 'Best First'.
Re: How to simulate?
by ikegami (Patriarch) on Apr 19, 2011 at 19:43 UTC
Re: How to simulate?
by InfiniteSilence (Curate) on Apr 19, 2011 at 18:58 UTC
    Fellow Monks, this is the first true sign of our ultimate success and supremacy over online programming discussion sites -- people are visiting this site and posting questions that have nothing to do with Perl at all. The idea? If you know Perl you must have the answer to my problem as well!

    Celebrate Intellectual Diversity

Re: How to simulate?
by Anonymous Monk on Apr 19, 2011 at 18:36 UTC
    So I thought I could provide a link to a JavaScript function that would move through the years recurively as follows.

    That is not a link

    But it generates the first year and stops.

    That is what happens when you instruct the browser to visit a different webpage

      Sorry. The Perl link is below.

      <A class='zzz tn' title='Simulate' HREF='javascript:simulate(\"$thestr +\")' ONMOUSEOVER=\"window.status='Click For A Color Map Simulation';r +eturn true\" ONMOUSEOUT=\"window.status=' ';return true\"><img SRC='. +./images/ball1.gif' style='image-orientation: 90deg;' width=7 height= +7></A>
      I hear what your saying. Do you have any suggestions? I already have links for each year on the page. I'm sort of experimenting with this simulation idea.

        I hear what your saying. Do you have any suggestions? I already have links for each year on the page. I'm sort of experimenting with this simulation idea.

        Suggestions other than don't instruct the browser to leave the current page?

        • Learn about the DOM
        Fundamentally is is a javascript/DOM/AJAX question, using javascript to get data from the webserver (AJAX), and manipulating the current DOM to display this data

        http://w3schools.com/ is a good starting point if you want to learn about these things, or try something like stackoverflow for q'n'a

Re: How to simulate?
by CountZero (Bishop) on Apr 19, 2011 at 18:54 UTC
    And where is the Perl question?

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: How to simulate?
by LanX (Saint) on Apr 19, 2011 at 19:35 UTC
    You're loading a new page, which destroys your Javascript.

    Possible advices:

    a) use a non JS solution, like WWW::Mechanize or Selenium.

    b) use an automation addon for Firefox like iMacros.

    c) put your approach in a frameset, one frame holding the JS the other the page to load. (but all parts from the same domain!)

    UPDATE:

    d) it may be that you can load a HTML page into the sidebar which starts your testscript on load. (UNTESTED)

    e) if it's only about loading pages into Firefox you can also write a simple perl script using firefox -remote (IIRC linux only) or mozrepl for communication.

    f) last but not least WWW::Mechanize::Firefox

    Cheers Rolf

Re: How to simulate?
by scorpio17 (Canon) on Apr 20, 2011 at 14:11 UTC

    This is a job for AJAX. Instead of using document.location to redirect to another page, what you need to do is:

    1. Create an XMLHttpRequest object.
    2. Use that object to make a request (i.e., invoke your perl cgi script).
    3. Define a response handler that will receive the output of your script and insert it into your page, you can create an empty div element to act as a placeholder for this.
    4. After handling each response, setup the next request (this is how you would loop through all your dates)

    Here's a simple demo I had laying around that does something similar:

    <html> <head> <script type="text/javascript"> function createRequestObject() { var req; if (window.XMLHttpRequest) { // Firefox, Safari, Opera... req = new XMLHttpRequest(); } else if (window.ActiveXObject) { // Internet Explorer 5+ req = new ActiveXObject("Microsoft.XMLHTTP"); } else { // error creating the request object, // (maybe an old browser is being used?) alert('There was a problem creating the XMLHttpRequest object'); req = ''; } return req; } // Make the XMLHttpRequest object var http = createRequestObject(); sendRequest(); function sendRequest() { // Open perl script for requests var now = new Date(); http.open('GET', 'http://' + document.domain + '/cgi-bin/ajax/demo. +pl?nocache='+now.getTime(), true); http.onreadystatechange = handleResponse; http.send(null); } function handleResponse() { if(http.readyState == 4 && http.status == 200){ var response = http.responseText; // Text returned FROM perl scrip +t if(response) { // UPDATE ajaxText content document.getElementById("ajaxText").innerHTML = response; setTimeout('sendRequest()', 5000); } } } </script> </head> <body> <p>The message is...</p> <div id="ajaxText" >Hello World!</div> </body> </html>

    This is just a demo. The demo.pl cgi script simply prints out a random text string:

    #!/usr/bin/perl use strict; print "content-type: text/html\n\n"; my @messages = ( "This is message 1", "This is message 2", "This is message 3", "This is message 4", "This is message 5", ); # print a random message print @messages[rand @messages] , "\n";

    The response handler calls this script every 5 seconds using setTimeout(). Note that I append the epoch time to the cgi script query string so that the browser won't simply cache the first response and use it over and over (that's a common ajax gotcha). When you view the html page in your browser, you should see the message change randomly every 5 seconds.

    I hope that helps get you moving in the right direction. Good luck!