cryptinitedemon Posted June 1, 2008 Share Posted June 1, 2008 Okay, I've been able to get the php upload working just fine. I have a form whose action goes to somepage.php and it uploads and spits out the new page and everything. What I'm looking to do is instead of displaying the somepage.php, I want to use AJAX and call a function in javasript on the page that will use some php file to upload and then send back a message about whether or not it was successful. The form action would be left blank. that message would be put in the page, without leaving the page because I'll have other ajax messages on the page. Soooo, what gets me is that everyone says that enctype="multipart/form-data" field is important to the file uploads. If I leave the action field blank, and then let the submit call my javascript function, would that even be possible to do, or am I required use use a form acion for this? I know what I'm saying might seem weird with how I'm wording it, but hopefully you guys will get what I'm saying. I just have a page that will be getting lots of these little status messages about different changes and I don't want it to have to go to another page. Link to comment https://forums.phpfreaks.com/topic/108185-php-and-uploading-files/ Share on other sites More sharing options...
radar Posted June 1, 2008 Share Posted June 1, 2008 Do what I do and do it all in a single php file using a switch.. If ya need an example let me know i'd be glad to spit one out for ya... Link to comment https://forums.phpfreaks.com/topic/108185-php-and-uploading-files/#findComment-554540 Share on other sites More sharing options...
cryptinitedemon Posted June 1, 2008 Author Share Posted June 1, 2008 That won't help me any. The point is that I want to take the output of my php uploading script and put it in the page I already have open. So when they click the submit button, a little red text comes up below it saying "your file was uploaded." However, to do this I have to use XMLHTTP request, which has that "send" function in it that allows you to define your post data. And that's the part that confuses me because I have no idea how to define the variables in this function's parameters for a file upload. I know how to do it for regular text fields and radio buttons because all the info in those fields are just simple text strings, but php uses that global _FILES variable to suck out the info it needs to upload the file to a server. In other words, I'm looking how to format a file upload request using XMLHTTPRequest's commands instead of using the form action="somefile.php", which does everything automatically for me. Link to comment https://forums.phpfreaks.com/topic/108185-php-and-uploading-files/#findComment-554585 Share on other sites More sharing options...
radar Posted June 1, 2008 Share Posted June 1, 2008 Well I suppose you could just do something like this... <fieldset> <legend>Photo Upload Demo</legend> <div id="divFrame"> <iframe id="ifrPhoto" onload="initPhotoUpload()" scrolling="no" frameborder="0" hidefocus="true" style="text-align:center;vertical-align:middle;border-style:none;margin:0px;width:100%;height:55px" src="PhotoUpload.aspx"></iframe> </div> <div id="divUploadMessage" style="padding-top:4px;display:none"></div> <div id="divUploadProgress" style="padding-top:4px;display:none"> <span style="font-size:smaller">Uploading photo...</span> <div> <table border="0" cellpadding="0" cellspacing="2" style="width:100%"> <tbody> <tr> <td id="tdProgress1"> </td> <td id="tdProgress2"> </td> <td id="tdProgress3"> </td> <td id="tdProgress4"> </td> <td id="tdProgress5"> </td> <td id="tdProgress6"> </td> <td id="tdProgress7"> </td> <td id="tdProgress8"> </td> <td id="tdProgress9"> </td> <td id="tdProgress10"> </td> </tr> </tbody> </table> </div> </div> </fieldset> As you see that we are using few divs to show and hide the upload form and the progress bar. The important thing is we are binding the initPhotoUpload in the frame load event. Now let us check the iframe source page markup. <form id="photoUpload" enctype="multipart/form-data" runat="server"> <div> <input id="filPhoto" type="file" runat="server"/> </div> <div id="divUpload" style="padding-top:4px"> <input id="btnUpload" type="button" value="Upload Photo" /> </div> </form> The iframe source page contains only a file upload control and a button to post the form. Now lets get back to the main page initPhotoUpload function and lets check how it is implemented: function initPhotoUpload() { _divFrame = document.getElementById('divFrame'); _divUploadMessage = document.getElementById('divUploadMessage'); _divUploadProgress = document.getElementById('divUploadProgress'); _ifrPhoto = document.getElementById('ifrPhoto'); var btnUpload = _ifrPhoto.contentWindow.document.getElementById('btnUpload'); btnUpload.onclick = function(event) { var filPhoto = _ifrPhoto.contentWindow.document.getElementById('filPhoto'); //Baisic validation for Photo _divUploadMessage.style.display = 'none'; if (filPhoto.value.length == 0) { _divUploadMessage.innerHTML = '<span style=\"color:#ff0000\">Please specify the file.</span>'; _divUploadMessage.style.display = ''; filPhoto.focus(); return; } var regExp = /^(([a-zA-Z]|(\\{2}\w+)\$?)(\\(\w[\w].*))(.jpg|.JPG|.gif|.GIF|.png|.PNG|.bmp|.BMP)$/; if (!regExp.test(filPhoto.value)) //Somehow the expression does not work in Opera { _divUploadMessage.innerHTML = '<span style=\"color:#ff0000\">Invalid file type. Only supports jpg, gif, png and bmp.</span>'; _divUploadMessage.style.display = ''; filPhoto.focus(); return; } beginPhotoUploadProgress(); _ifrPhoto.contentWindow.document.getElementById('photoUpload').submit(); _divFrame.style.display = 'none'; } } Once the iframe is loaded we are setting few module level variables (All module level variables are prefixed with _ (underscore) character in this example) to DOM elements, we are also getting the reference of the Upload button which is in the iframe and creating its click handler. In the click handler first we are doing few basic validation such as the file upload control is not empty or the file that is specified has a valid image file extension. Once the validation qualifies then we are calling the beginPhotoUploadProgress function (discussed next) and submitting the iframe form. The beginPhotoUploadProgress function is the first of three functions which are used to show the dummy progress bar. Let us see how these functions are written: function beginPhotoUploadProgress() { _divUploadProgress.style.display = ''; clearPhotoUploadProgress(); _photoUploadProgressTimer = setTimeout(updatePhotoUploadProgress, PROGRESS_INTERVAL); } function clearPhotoUploadProgress() { for (var i = 1; i <= _maxLoop; i++) { document.getElementById('tdProgress' + i).style.backgroundColor = 'transparent'; } document.getElementById('tdProgress1').style.backgroundColor = PROGRESS_COLOR; _loopCounter = 1; } function updatePhotoUploadProgress() { _loopCounter += 1; if (_loopCounter <= _maxLoop) { document.getElementById('tdProgress' + _loopCounter).style.backgroundColor = PROGRESS_COLOR; } else { clearPhotoUploadProgress(); } if (_photoUploadProgressTimer) { clearTimeout(_photoUploadProgressTimer); } _photoUploadProgressTimer = setTimeout(updatePhotoUploadProgress, PROGRESS_INTERVAL); } As we can see we are basically using the timer (window.setTimeout) to show the dummy progress in these functions. Now lets see what happens in the server side when the iframe page posts. private const string SCRIPT_TEMPLATE = "<" + "script " + "type=\"text/javascript\">window.parent.photoUploadComplete('{0}', {1});" + "<" + "/script" + ">"; private void Page_Load(object sender, EventArgs e) { if (IsPostBack) { //Sleeping for 10 seconds, fake delay, You should not it try at home. System.Threading.Thread.Sleep(10 * 1000); UploadPhoto(); } } private void UploadPhoto() { string script = string.Empty; if ((filPhoto.PostedFile != null) && (filPhoto.PostedFile.ContentLength > 0)) { if (!IsValidImageFile(filPhoto)) { script = string.Format(SCRIPT_TEMPLATE, "The uploaded file is not a valid image file.", "true"); } } else { script = string.Format(SCRIPT_TEMPLATE, "Please specify a valid file.", "true"); } if (string.IsNullOrEmpty(script)) { //Uploaded file is valid, now we can do whatever we like to do, copying it file system, //saving it in db etc. //Your Logic goes here script = string.Format(SCRIPT_TEMPLATE, "Photo uploaded.", "false"); } //Now inject the script which will fire when the page is refreshed. ClientScript.RegisterStartupScript(this.GetType(), "uploadNotify", script); } private static bool IsValidImageFile(HtmlInputFile file) { try { using (Bitmap bmp = new Bitmap(file.PostedFile.InputStream)) { return true; } } catch (ArgumentException) { //throws exception if not valid image } return false; } In the server side we are first doing some basic validation such as the file upload control has file and the file is a valid image file. Once the validation is done we are injecting some javascript which will be executed when the page is loaded in the browser. The javascript calls the main page photoUploadComplete function which shows the success/failure or the validation message of the upload. Lets see the javascript function photoUploadComplete of the main page. function photoUploadComplete(message, isError) { clearPhotoUploadProgress(); if (_photoUploadProgressTimer) { clearTimeout(_photoUploadProgressTimer); } _divUploadProgress.style.display = 'none'; _divUploadMessage.style.display = 'none'; _divFrame.style.display = ''; if (message.length) { var color = (isError) ? '#ff0000' : '#008000'; _divUploadMessage.innerHTML = '<span style=\"color:' + color + '\;font-weight:bold">' + message + '</span>'; _divUploadMessage.style.display = ''; if (isError) { _ifrPhoto.contentWindow.document.getElementById('filPhoto').focus(); } } } The function simply hides the progress bar and shows the upload control then it shows the message in colored text which is sent from the server. Maybe something like that might fit your needs more? Link to comment https://forums.phpfreaks.com/topic/108185-php-and-uploading-files/#findComment-554617 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.