Link to home
Start Free TrialLog in
Avatar of speedygonzalez
speedygonzalez

asked on

call cgi from javascript - Do not leave web page

hello,

I have a web page in which I will have a number of links for whch I will call CGI scripts when each link is clicked.

What I need to do is (a) call the cgi script when the button or link is clicked but do not leave the webpage when this occurs (i.e. stay on the same page but do not show a refresh to the web user. (b) check if the user is still pressing on the mousebotton (i.e. has not released the button pressed) & recall the cgi script again if required after a period of time if the mouse button is still clicked)

Sounds complicated I know.

The following was my first attempt (just using one web client button for testing)

<SCRIPT>
function callCgi() {
   location = '../../Scripts/testC.cgi'
}
</SCRIPT>
<FORM>
<INPUT TYPE="button" onClick="callCgi();" VALUE="Run">
</FORM>

When I click on the button the testC.cgi script does execute as required, however the page then moves to testC.cgi and does not stay on the same client page.

I'm not sure if what I'm asking is in fact possible but thought I'd check anyhow.

Any help would be very much appreciated!
Avatar of arritjenof
arritjenof

i'm not sure what your skill-level is when it comes to javascript, and what part of the script(s) you already have, but to start-off with, you should use 'mousedown' and 'mouseup' instead of 'onclick'.

additionally, you need to 'stop the event' to prevent that the browser will register the actual click and refresh the page or open the link.

just returning false in your callCgi() or in the onouseup/-down - attributes script could be all you need to do, but you might also need to stop event propagation/bubbling.

i can recommend the following links for more information on that.
http://www.quirksmode.org/js/events_mouse.html
http://www.quirksmode.org/js/events_order.html

If what you want is getting complicated, to should consider using a library such as jQuery, Mootools, Dojo, Prototype etc.. because they will make your life so much easier. My personal favorit is jQuery.
By putting
location = ...
you are telling the browser to go to a new page, which is why it is "refreshing" and not leaving the web page.

What you are looking for is Ajax. That is javascript which will run a script on the server, and get the output of the script. JQuery has a nice Ajax module. I've not used it, since I wrote an Ajax function before I ever heard of JQuery. The code I use is in the attached file, getData.js. The function createXMLHttp in that file, I got from someone else, and there is sample function to call it. I name all my cgi scripts that are called by Ajax ajax_somename.cgi and I wrote getData so I don't need to send the "ajax_" and ".cgi" parts of the script name, which is why the first four lines of function getData. Remove those if you prefer to send the whole name of the script.

But arritnenof is right that using JQuery will probably make your javascript coding easier all around. I do use it now for numerous things, though I've never learned it well.

In the code below, the first function would be called by your event (onmousedown) to get the output. I assume you want to stop calling the script when the user either lets the mouse button up, or moves the mouse off your link. You will need to use setTimeOut to have your function rerun the script every X milliseconds. And set a global variable which is toggled on mousedown and mouseup. Your script getCGI will then set the innerHTML of an element to the output of your script. Note that when you call getCGI you must send an empty string as the first parameter, since getData calls it as well, with the output of the script as the first parameter. Also, you must set the value of mousedn before calling getCGI.

 Also, you could hard code the name of script in getCGI, and not send it when it is called. But, if you send the script name to getCGI, you could use getCGI for multiple buttons on the same page to run different scripts..

For illustration's  sake, I'm assuming the script needs an id number and a firstname. Your script will need to
print "Content-type: text/html\n\n";
then print the data you want displayed on the page.

In (b) above, about recalling the cgi script, you only need to do that if the output of the script is going to change each time it is called. If the output will be the same every time it is run, leave out the lines about the timer, line 5-14, and everything about mousedn - you don't need to keep recalling the script.

Note: I have not tested the code below. It is possible I made a typo, but I believe it should work. On the other hand, the attached file I use regularly.
<script type="text/javascript">
<!--
	var mousedn = false;
	function callCgi(response,scriptname,parameters,id) {

		// check if mouse is still down and over the button
		if (!mousedn) {
			if(Timer) {
				clearTimeout(Timer);
			}
			return;
		} else {
			// recall cgi script every 1000 milliseconds (1 second)
			Timer = setTimeout("callCgi('',scriptname,parameters,id)",1000);
		}

		if (response != '') {
			if (response = ' ') {
				response = 'There was no output from the script.';
			}
			// do something here:
			document.getElementById(id).innerHTML = response;
		} else {
			getData(scriptname,'callCgi',parameters);
		}
	}
//-->
</script>

================

<form>
Enter your first name: <input type="text" name="firstname" value="" />
<br />
<input type="button" onmousedown="mousedn=true;callCgi('','scriptname','id=1&firstname='+this.form.firstname.value,'cgi_output');" onmouseout="mousedn=false;callCgi('','scriptname','id=1&name=tom','cgi_output');" onmouseup="mousedn=false;callCgi('','scriptname','id=1&name=tom','cgi_output');" value="Run" />
</form>

<div id="cgi_output"></div>

Open in new window

getData.js
Note, there is an error in the first sentence of my reply. It should be:

By putting
location = ...
you are telling the browser to go to a new page, which is why it is "refreshing" and is leaving the web page.
I also see that, originally, I hard coded the firstname in the call to getCGI, then changed it to pull it from the form, and didn't change the second two calls - onmouseout and onmouseup.
If you prefer the JQuery route, after perusing some the JQuery Ajax plugins, this one looks like it would fill your need - though I've only read about it on this page:
http://plugins.jquery.com/project/ajaxContent
Avatar of speedygonzalez

ASKER

Hi guys, that's a great help. Much appreciated.
I tried to test out the code you have provided above fredmc with some very small modifcations.

I get one Javascript error returning in my Intrnet Explorer browser window.
The error is:

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Avant Browser; Avant Browser; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Timestamp: Tue, 6 Jul 2010 11:01:36 UTC


Message: 'parameters' is undefined
Line: 24
Char: 4
Code: 0
URI: http://136.206.18.70/test/test3.html

Does "parameters" have to be defined somewhere first for it to be used?

Thanks again!
<script type="text/javascript">
<!--
	var mousedn = false;
	function callCgi(response,scriptname,id) {

		// check if mouse is still down and over the button
		if (!mousedn) {
			if(Timer) {
				clearTimeout(Timer);
			}
			return;
		} else {
			// recall cgi script every 1000 milliseconds (1 second)
			Timer = setTimeout("callCgi('',scriptname,id)",1000);
		}

		if (response != '') {
			if (response = ' ') {
				response = 'There was no output from the script.';
			}
			// do something here:
			document.getElementById(id).innerHTML = response;
		} else {
			getData(scriptname,'callCgi',parameters);
		}
	}
//-->
</script>

================

<form>
<br />
<input type="button" onmousedown="mousedn=true;callCgi('','../../../Scripts/testCGI.cgi','cgi_output');" onmouseout="mousedn=false;callCgi('','../../../Scripts/testCGI.cgi','cgi_output');" onmouseup="mousedn=false;callCgi('','../../../Scripts/testCGI2.cgi','cgi_output');" value="Run" />
</form>
<div id="cgi_output"></div>

Open in new window

Yes, it does. My original line was
function callCgi(response,scriptname,parameters,id) {

You changed it to
function callCgi(response,scriptname,id) {

Since you aren't passing any paramters to getData, the easiest thing for you is to change the call to it on line 24, and leave out paramaters:
getData(scriptname,'callCgi');  
Hi fredmc,

Thanks again. An error now appears as follows (with the change suggested)

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Avant Browser; Avant Browser; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Timestamp: Tue, 6 Jul 2010 15:28:34 UTC


Message: Object expected
Line: 24
Char: 4
Code: 0
URI: http://136.206.18.70/test/test4.html


Cheers for the help!
Do you have this line in the <head> portion of your web page:
<script type="text/javascript" src="/js/getData.js"></script>

where "/js/getData.js" is the path to the file you (hopefully) downloaded from my first post - getData.js

It would appear you don't, and that is why it can't find the funtion getData, which is probably the object it can't find.
Hi fredmc, thank you again,

Note I have now placed the getData.js file in the js folder as you have suggested but I still receive an error.

The error is now.

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Avant Browser; Avant Browser; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Timestamp: Wed, 7 Jul 2010 09:49:06 UTC


Message: Object expected
Line: 33
Char: 14
Code: 0
URI: http://136.206.18.70/test/test3.html


Message: Object expected
Line: 33
Char: 15
Code: 0
URI: http://136.206.18.70/test/test3.html


Message: Object expected
Line: 33
Char: 15
Code: 0
URI: http://136.206.18.70/test/test3.html

My code is as in the snippet below  (note I notice the getData function in" getData.js" requires four input values (script,func,params,frm). Should I change this or add 4 values to pass to it in my code.

Thanks again!
<html><head><script type="text/javascript" src="/js/getData.js">
<!--
	var mousedn = false;
	function callCgi(response,scriptname,id) {

		// check if mouse is still down and over the button
		if (!mousedn) {
			if(Timer) {
				clearTimeout(Timer);
			}
			return;
		} else {
			// recall cgi script every 1000 milliseconds (1 second)
			Timer = setTimeout("callCgi('',scriptname,id)",1000);
		}

		if (response != '') {
			if (response = ' ') {
				response = 'There was no output from the script.';
			}
			// do something here:
			document.getElementById(id).innerHTML = response;
		} else {
			getData(scriptname,'callCgi',parameters);
		}
	}
//-->
</script></head>
<body>

<form>
<br />
<input type="button" onmousedown="mousedn=true;callCgi('','../../../Scripts/testCGI.cgi','cgi_output');" onmouseout="mousedn=false;callCgi('','../../../Scripts/testCGI.cgi','cgi_output');" onmouseup="mousedn=false;callCgi('','../../../Scripts/testCGI2.cgi','cgi_output');" value="Run" />
</form>
<div id="cgi_output"></div>
</body>
</html>

Open in new window

It isn't necessary to send the fourth value to gdtData - in fact, since you aren't using it, you can omit "parameters" as the third value.

The error is on line 33 of test3.html, which is the input box, which indicates that is the place where it can't find an object. The only javascript there is the call to callCGI, so that's the place to start looking.

The problem is that on the line where you call in the getData.js file you need a close script tag, then another open script tag to start the inline javascript. What you did seems like it should work so, but it doesn't. Just one more lesson in how Javascript works. :-)

<html><head><script type="text/javascript" src="/js/getData.js"></script>
<script type="text/javascript"> 
<!--  
        var mousedn = false;  
        function callCgi(response,scriptname,id) {  
  
                // check if mouse is still down and over the button  
                if (!mousedn) {  
                        if(Timer) {  
                                clearTimeout(Timer);  
                        }  
                        return;  
                } else {  
                        // recall cgi script every 1000 milliseconds (1 second)  
                        Timer = setTimeout("callCgi('',scriptname,id)",1000);  
                }  
  
                if (response != '') {  
                        if (response = ' ') {  
                                response = 'There was no output from the script.';  
                        }  
                        // do something here:  
                        document.getElementById(id).innerHTML = response;  
                } else {  
                        getData(scriptname,'callCgi',parameters);  
                }  
        }  
//-->  
</script></head>  
<body>  
  
<form>  
<br />  
<input type="button" onmousedown="mousedn=true;callCgi('','../../../Scripts/testCGI.cgi','cgi_output');" onmouseout="mousedn=false;callCgi('','../../../Scripts/testCGI.cgi','cgi_output');" onmouseup="mousedn=false;callCgi('','../../../Scripts/testCGI2.cgi','cgi_output');" value="Run" />  
</form>  
<div id="cgi_output"></div>  
</body>  
</html>

Open in new window

Hi fredmc,

Note it is still looking for an expected Object at line "getData(scriptname,'callCgi',parameters); "

If I alter this to "getData(scriptname,'callCgi')" in the javascript on the html page would I then need to change the constructor in getData.js also to reflect this?
Currently it has "function getData(script,func,params,frm) {"
the "params" and "frm" variables do seem to be used though in the getData function in getData.js.

Thanks again.

As you'll have guessed, I'm a bit of a novice at this.

Cheers.
Is the page anywhere on the Internet where I can look at it in a browser? I've tried http://136.206.18.70/test/test3.html but can't get there.

If you want to be sure the missing values aren't the problem, you can put
getData(scriptname,'callCgi',','');
or perhaps just remove "parameters" - since it isn't defined in callCgi.
I've tested calling getData without sending anything for the third and fourth parameters and it does work. Don't change getData, too big a chance of breaking it.

The other, and more likely, possibility is that you have the wrong path in this line:
<script type="text/javascript" src="/js/getData.js"></script>
and the browser isn't able to load that file. What is the directory structure where you have uploaded test3.html? Can you show me a directory listing of the directory test3.html is in? The path /js/getData.js assumes that there is a directory named "js" in the same directory as the file test3.html, and getData.js is in that directory.

What happens if you put this in your browser:
http://136.206.18.70/test/js/getData.js
If it says the page can't be found, then the path is indeed the problem. If it asks if you want to open the file, or save it, then the path is not the problem.

As you might have guessed, I used to be a teacher. Taught computers and math to 7th - 10th graders for 17 years. (I turned 61 years old today.) Took my first programming class in 1967, though I dropped out of college after 1 year and didn't touch computers again until 1980.
Fred
ASKER CERTIFIED SOLUTION
Avatar of Frederick McIntyre
Frederick McIntyre
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi fredmc,
Thanks, been away the past few days but will try this out this evening or 2moro.
Will update the question afterwards.

Thanks again.