Jump to content

XmlHttpRequest: sending file


Recommended Posts

Hello, im trying to create a nice file uploader using XmlHttpRequest so that we can get a nice progress bar and stuff without reloading the page. When I try to upload using my code the progress bar does show and count % up untill completed but no file is being uploded. I will show you my code and tell you what I think is wrong, but I will strip it down a bit. This is my js part:

function uploadFile()			{				var xhrObj = new XMLHttpRequest();								var filesToBeUploaded = document.getElementById("fileControl");				var file = "filename="+filesToBeUploaded.files[0];								xhrObj.upload.addEventListener("progress", progressFunction, false);				xhrObj.upload.addEventListener("load", transferCompleteFunction, false);								xhrObj.open("POST", "upload.php", true);								xhrObj.setRequestHeader("Content-type", file.type);								xhrObj.send(file);			}

My form is not important, its a button with onclick="uploadFile()". But my upload.php might not be correct. This is where I wonder if I can use this:move_uploaded_file($_FILES['Filedata']['tmp_name'], "files/".$name."/".$filename) my upload.php:

<?phpsession_start(); //Set some variables$name = $_SESSION['name'];$filename = $_POST['filename'];$key = uniqid(); // Move uploaded fileset_time_limit(0);	if(move_uploaded_file($_FILES['Filedata']['tmp_name'], "files/".$name."/".$filename)){			// Update database}?>

Edited by Ustag
Link to post
Share on other sites

I'm not sure how files are sent through XMLHttpRequest. Currently, all you're sending is the string "filename=something". There's no "Filedata" variable in your script, so there won't be anything in the $_FILES['Filedata'] array. Can you show me the reference you used to make your current script?

Link to post
Share on other sites

This looks like a good example to make sure the file gets uploaded:https://developer.mozilla.org/en/Using_files_from_web_applications#Example:_Uploading_a_user-selected_file

Link to post
Share on other sites

I use the example at the bottom of that page you gave me but I want to edit this to fit my needs. This is my code now to give me one progress bar for each file dragged on to the dropzone, my problem is how I can also give each progrss bar its own % calculator.

<script type="text/javascript">		function sendFile(file)		{			var uri = "upload.php";			var xhr = new XMLHttpRequest();			var fd = new FormData();		  			xhr.upload.addEventListener("progress", progressFunction, false);		  			xhr.open("POST", uri, true);			xhr.onreadystatechange = function()			{				if (xhr.readyState == 4 && xhr.status == 200)				{					// Handle response.					//alert(xhr.responseText);					var percentageDiv = document.getElementById("report");		   percentageDiv.innerHTML = 'Transfer complete';				}			}			fd.append('myFile', file);			// Initiate a multipart/form-data upload			xhr.send(fd);		} 		window.onload = function()		{			var dropzone = document.getElementById("dropzone");			dropzone.ondragover = dropzone.ondragenter = function(event)			{				event.stopPropagation();				event.preventDefault();			}				dropzone.ondrop = function(event)			{				event.stopPropagation();				event.preventDefault(); 				var filesArray = event.dataTransfer.files;				for (var i=0; i<filesArray.length; i++)				{				 var progressDiv = document.getElementById('progressDiv');				 var pbar = document.createElement('progress');				 var br = document.createElement('br');				 var report = document.createElement('div');								 pbar.setAttribute('id', 'progressBar' + i);				 pbar.setAttribute('value', '0');				 pbar.setAttribute('max', '100');				 report.setAttribute('id', 'report' + i)								 progressDiv.appendChild(pbar);				 progressDiv.appendChild(br);				 progressDiv.appendChild(report);				 progressDiv.appendChild(br);								 sendFile(filesArray[i]);			 }		 }		}	  		function progressFunction(evt)		{			var progressBar = document.getElementById('progressBar' + i);			var percentageDiv = document.getElementById('report' + i);			if (evt.lengthComputable)			{	progressBar.max = evt.total;				progressBar.value = evt.loaded;				percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + "%";			}		}</script>

The function progressFunction(evt) can not be placed in the for loop, then it will not work. Does anybody know how I could solve this? Thank you.

Edited by Ustag
Link to post
Share on other sites

The progressFunction function will need to loop through the list of progress bars and divs and update each one. One way to do that may be to get all progress elements, get the ID, and parse the ID to get the number to use to target the matching div.

Link to post
Share on other sites

Shouldnt this work?

		function progressFunction(evt)		{		 //give each bar a % calculator		 var bars = document.getElementsByTagName('progress');					for (var i=0; i<bars.length; i++)			{			 var progressBar = document.getElementById('progressBar' + i);			 var percentageDiv = document.getElementById('report' + i);			 if (evt.lengthComputable)			 {				 progressBar.max = evt.total;				 progressBar.value = evt.loaded;				 percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + "%";			 }			}		}

Edited by Ustag
Link to post
Share on other sites

That would work if the only progress elements on the page are the ones you want to change, and their IDs start at 0. It looks like all progress bars will be set to the same values though whenever that event fires, they all use the same event object.

Link to post
Share on other sites

If you drop 2 files at the same time it's going to trigger the drop event for each one, so each one will start the code in the drop handler. They will both call the sendFile function when they reach the end of the drop handler. They aren't synchronous, they aren't going to wait for each other. They're both going to execute the drop handler and whatever else as fast as they can.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...