AJAX n00b. Bear with me.

I have an AJAX object requesting the date modified header of a file, and performing another function based on the result when the request returns ready state 4. This works.

Now I'd like to do the same thing to a series of files. This is where it breaks. I've tried creating separate request objects for each file checked (as suggested in some tutorials), but I haven't gotten it to work.

I don't even really know whether I can just create these objects and send these requests in close order via a loop, or if I need to have the next wait for the prior request to complete.

I've used the code below to compare one file's modification date between one interval and the next, and to reload content on a change. This seems to work, but I have to make it watch more than one file.

<html>
<head>
<script language="javascript" type="text/javascript">
var modified_bool = '';
var the_modified = '';
var the_modified_buffer = '';
function ajaxFunction() {
	if (the_modified != the_modified_buffer) {
		modified_bool = true;
	}
	else {
		modified_bool = false;
	}
	var ajaxRequest;
	try {
		ajaxRequest = new XMLHttpRequest();
	}
	catch(e) {
		try {
			ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch(e) {
			try {
				ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(e) {
				alert("Problem");
				return false;
			}
		}
	}
	ajaxRequest.onreadystatechange = function() {
		if (ajaxRequest.readyState == 4) {
			the_modified_buffer = the_modified;
			the_modified = ajaxRequest.getResponseHeader("Last-Modified");
			var ajaxDisplay = document.getElementById('ajaxDiv');
			ajaxDisplay.innerHTML = ajaxRequest.getResponseHeader("Last-Modified") + '<br />the_modified ' + the_modified + '<br />' + 'the_modified_buffer ' + the_modified_buffer + '<br />modified_bool ' + modified_bool;
			var flash_display = document.getElementById('flash_div');
			if (modified_bool == true) {
				flash_display.innerHTML = '<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0\" width=\"804px\" height=\"768px\"><param name=\"movie\" value=\"test.swf"><param name=\"quality\" value=\"high\"><embed src=\"test.swf" quality=\"high\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" width=\"804px\" height=\"768px\"></embed></object>';
			}
		}
	}
	ajaxRequest.open("HEAD", "watched.txt", true);
	ajaxRequest.send(null);
}
</script>
</head>
<body>
<div id='ajaxDiv'>Loading...</div>
<script type="text/javascript">
window.setInterval("javascript:ajaxFunction()", 250);
</script>
<div id='flash_div'>Loading...
</div>
</body>
</html>

HST,

Like all things javascript, there are many ways to do this. Here's one (below).

I'm pretty sure it's is not fully working but certainly offers a framework for monitoring multiple files.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style type="text/css">
.fNameDiv {
	margin: 10px 0 0 0;
	padding: 2px;
	border: 0 solid #999;
	border-width: 1px 0;
	background-color: #e0e0e0;
}
.resultDiv {
	padding: 3px;
}
.flashDiv {
	padding: 3px;
}
.control {
	margin: 5px 5px 0 0;
}
</style>
<script type="text/javascript">
var AJAX = function(){//Namespace pattern
	return {//Public members
		Request : function(){
			var ajaxRequest; 
			try { ajaxRequest = new XMLHttpRequest(); }
			catch(e) {
				try { ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP"); }
				catch(e) {
					try { ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP"); }
					catch(e) {
						alert("Problem");
						return false;
					}
				}
			}
			return ajaxRequest;
		}
	};
}();

var FILE_CHECKS = function(){//Namespace pattern
	//FILE_CHECKS Private members
	var fileObjArray = [];
	var File = function(fName, container, interval){//Contructor
		var that = this;
		this.fName = fName;
		this.interval = (!interval) ? 0 : interval;
		this.the_modified = '';
		this.the_modified_buffer = '';
		this.modified_bool = false;
		this.running = false;
		//Create nodes and insert into DOM
		this.headingContainer = document.createElement('div');
		this.resultContainer = document.createElement('div');
		this.flashContainer = document.createElement('div');
		var b1 = document.createElement('button');
		var b2 = document.createElement('button');
		this.headingContainer.innerHTML = this.fName;
		this.resultContainer.innerHTML = 'Loading...';
		this.flashContainer.innerHTML = 'Loading...';
		this.headingContainer.className = 'fNameDiv';
		this.resultContainer.className = 'resultDiv';
		this.flashContainer.className = 'flashDiv';
		b1.innerHTML = 'START';
		b2.innerHTML = 'STOP';
		b1.className = 'control';
		b2.className = 'control';
		b1.onclick = function(){ that.start(); };
		b2.onclick = function(){ that.stop(); };
		container.appendChild(this.headingContainer);
		container.appendChild(b1);
		container.appendChild(b2);
		container.appendChild(this.resultContainer);
		container.appendChild(this.flashContainer);
		//Methods
		this.start = function(){
			if(this.running){ alert('Already running'); return; }
			that.running = true;
			that.headingContainer.style.backgroundColor = '#9C9';
			that.checkLastModified();
		};
		this.stop = function(){
			that.running = false;
			that.headingContainer.style.backgroundColor = '#C99';
		};
		this.checkLastModified = function(){
			var ajaxRequest = new AJAX.Request();
			ajaxRequest.onreadystatechange = function() {
				if (ajaxRequest.readyState == 4) {
					if( !that.running ) { return; }
					that.modified_bool = (that.the_modified != that.the_modified_buffer) ? true : false;
					that.the_modified_buffer = that.the_modified;
					that.the_modified = ajaxRequest.getResponseHeader("Last-Modified");
					that.resultContainer.innerHTML = [ ('the_modified '+that.the_modified), ('the_modified_buffer '+that.the_modified_buffer), ('modified_bool '+that.modified_bool) ].join('<br>');
					if (that.modified_bool) {
						that.flashContainer.innerHTML = '<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0\" width=\"804px\" height=\"768px\"><param name=\"movie\" value=\"test.swf\"><param name=\"quality\" value=\"high\"><embed src=\"test.swf\" quality=\"high\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" width=\"804px\" height=\"768px\"><\/embed><\/object>';
					}
					if( that.interval !== null ) {
						setTimeout( function(){ that.checkLastModified(); }, that.interval);
					}
				}
			};
			ajaxRequest.open('HEAD', this.fName, true);
			ajaxRequest.send(null);
		};
	};
	return {//FILE_CHECKS Public members
		init : function(fNames, cont, interval){
			if(!fNames || !(fNames instanceof Array) || fNames.length === 0) { alert('Error: File name'); return; }
			var container = (cont) ? document.getElementById(cont) : null;
			if(!container) { alert('Error: Container not sepecified/found'); return; }
			for(var i=0; i<fNames.length; i++){
				fileObjArray[i] = new File(fNames[i], container, interval);
			}
		},
		startAll : function(){
			for(var i=0; i<fileObjArray.length; i++){
				fileObjArray[i].start();
			}
		},
		stopAll : function(){
			for(var i=0; i<fileObjArray.length; i++){
				fileObjArray[i].stop();
			}
		}
	};
}();

window.onload = function(){
	var myFiles = [ 'watched_1.txt', 'watched_2.txt', 'watched_3.txt', 'watched_4.txt', 'watched_5.txt', 'watched_6.txt' ];
	FILE_CHECKS.init(myFiles, 'fileCheckContainer', 5000);
	FILE_CHECKS.startAll();
};
</script>
</head>
<body>

<div id="fileCheckContainer"></div>

</body>
</html>

NOTES:

The code will look pretty strange because it's wrapped up in two namespace patterns (AJAX and FILE_CHECKS), and within FILE_CHECKS, there's a constructor (File).

Constructors are not particularly unusual (they correspond to classes in most other OO languages) but namespaces are less common (and even less understood). Namespaces are singleton patterns that help avoid name clashes in the global namespace. Like constructors, they can have private and public members.

You will see that the urls of the files you want to monitor are specified in an array in an anonymous window.onload function.

The HTML comprises just one div container. Everything else is created and inserted into the DOM dynamically. This way you can monitor as few or as many files as you want without having to change the HTML.

I have included START/STOP buttons which allow each File object to be individually started and stopped. As written, all File objects are started after initialisation.

You will recognise some of your original code, and these bits are the ones you will most likely need to work on to get exactly what you want.

Airshow

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.