Asynchronous upload - Like AJAX - 1 function

Helo! Here a simple function to asynchronous upload using iframe. Dont reload the page. Like AJAX but its not ajax.You dont need to create the iframe, the function do this. Work like Gmail upload and Google pages upload.

Tested in Firefox 2.0, Internet Explorer 6.0 e Opera 9.1. If you test in another browsers, please write a comment.

Update: New version here (portuguese)

1) Put the code above in a file called micoxUpload.js

/* standard small functions */
function $m(quem){
 return document.getElementById(quem)
}
function remove(quem){
 quem.parentNode.removeChild(quem);
}
function addEvent(obj, evType, fn){
 // elcio.com.br/crossbrowser
    if (obj.addEventListener)
        obj.addEventListener(evType, fn, true)
    if (obj.attachEvent)
        obj.attachEvent("on"+evType, fn)
}
function removeEvent( obj, type, fn ) {
  if ( obj.detachEvent ) {
    obj.detachEvent( 'on'+type, fn );
  } else {
    obj.removeEventListener( type, fn, false ); }
} 
/* THE UPLOAD FUNCTION */
function micoxUpload(form,url_action,id_element,html_show_loading,html_error_http){
/******
* micoxUpload - Submit a form to hidden iframe. Can be used to upload
* Use but dont remove my name. Creative Commons.
* Versão: 1.0 - 03/03/2007 - Tested no FF2.0 IE6.0 e OP9.1
* Author: Micox - Náiron JCG - elmicoxcodes.blogspot.com - micoxjcg@yahoo.com.br
* Parametros:
* form - the form to submit or the ID
* url_action - url to submit the form. like action parameter of forms.
* id_element - element that will receive return of upload.
* html_show_loading - Text (or image) that will be show while loading
* html_error_http - Text (or image) that will be show if HTTP error.
*******/

 //testing if 'form' is a html object or a id string
 form = typeof(form)=="string"?$m(form):form;
 
 var erro="";
 if(form==null || typeof(form)=="undefined"){ erro += "The form of 1st parameter does not exists.\n";}
 else if(form.nodeName.toLowerCase()!="form"){ erro += "The form of 1st parameter its not a form.\n";}
 if($m(id_element)==null){ erro += "The element of 3rd parameter does not exists.\n";}
 if(erro.length>0) {
  alert("Error in call micoxUpload:\n" + erro);
  return;
 }

 //creating the iframe
 var iframe = document.createElement("iframe");
 iframe.setAttribute("id","micox-temp");
 iframe.setAttribute("name","micox-temp");
 iframe.setAttribute("width","0");
 iframe.setAttribute("height","0");
 iframe.setAttribute("border","0");
 iframe.setAttribute("style","width: 0; height: 0; border: none;");
 
 //add to document
 form.parentNode.appendChild(iframe);
 window.frames['micox-temp'].name="micox-temp"; //ie sucks
 
 //add event
 var carregou = function() { 
   removeEvent( $m('micox-temp'),"load", carregou);
   var cross = "javascript: ";
   cross += "window.parent.$m('" + id_element + "').innerHTML = document.body.innerHTML; void(0); ";
   
   $m(id_element).innerHTML = html_error_http;
   $m('micox-temp').src = cross;
   //del the iframe
   setTimeout(function(){ remove($m('micox-temp'))}, 250);
  }
 addEvent( $m('micox-temp'),"load", carregou)
 
 //properties of form
 form.setAttribute("target","micox-temp");
 form.setAttribute("action",url_action);
 form.setAttribute("method","post");
 form.setAttribute("enctype","multipart/form-data");
 form.setAttribute("encoding","multipart/form-data");
 //submit
 form.submit();
 
 //while loading
 if(html_show_loading.length > 0){
  $m(id_element).innerHTML = html_show_loading;
 }
 
}

2) Include this file in your HTML

<script type="text/javascript" src="micoxUpload.js"></script>

3) Parameters of micoxUpload function:

  1. form - the form to submit or the ID of a form .
  2. url_action - url to submit the form. like 'action' parameter of forms.
  3. id_element - element that will receive return of upload.
  4. html_show_loading - Text (or image) that will be show while loading
  5. html_error_http - Text (or image) that will be show if HTTP error.

4) Ok. Now you have a lot of forms to call the Asynchronous upload function. 3 Examples:

4.1) Basic from a button (or input-type-button) in a form:

<legend>Basic use</legend>
  <form>
    <input type="file" name="name" />
    <div id="upload_1" class="recebe">&nbsp;</div>
    <button onClick="micoxUpload(this.form,'upa.php','upload_1','Loading...','Error in upload'); return false;" type="button">test</button>
  </form>
</fieldset>

4.2) When input-file lost focus (onblur):

<fieldset>
<legend>On blur use</legend>
  <form>
    <input type="file" name="name" onchange="micoxUpload(this.form,'upa.php','upload_2','Loading...','Error in upload')" />
    <div id="upload_2" class="recebe">&nbsp;</div>
  </form>
</fieldset>

4.3) Making acessible whitout JavaScript :

<fieldset>
<legend>Unobstrusive</legend>
    <form action="upa.php" target="_blank">
    <input type="file" name="name" onchange="micoxUpload(this.form,'upa.php','upload_3','Loading...','Error in upload')" />
    <div id="upload_3" class="recebe">&nbsp;</div>
    <button type="submit">Go</button>
  </form>
</fieldset>

Ok. Bugs, errors, comment here.
In next post, a more flexible version of this function for who understend JavaScript.

Portuguese version: Upload Assíncrono (iframe como AJAX) - 1 função simples

108 comments:

  1. I have two remarks:

    You should change all "id_elemento_retorno" to "id_element" to make script work.

    When you use the "onblur" version in Firefox, the action starts immediately you click on the Browse button. After choosing a file, the action runs again, and uploads the file well. (I havent tested this on other browsers.)

    Great job, anyway.

    ReplyDelete
  2. Uh, thanks gyulus.

    I've forget this.

    Its true what you said about "onblur", but just only a example of use.

    Very thanks.
    :)

    ReplyDelete
  3. Thanks, you have resolved all my problems!!

    ReplyDelete
  4. I cant find out the file named upa.php Please give me full source code

    ReplyDelete
  5. helo Sivarama.

    The upa.php could be any script server-side for receive uploads.
    Its like normal upload that you already know.

    A example of upload script you can find here.

    Another doubts, email-me. :)

    ReplyDelete
  6. Thanks for the script.

    Instead of "onblur", use "onchange" -- then the upload takes place as soon as the file is selected.

    ReplyDelete
  7. After replacing all uses of the "standard small functions" with their prototype.js counterparts, this upload script also works in nightly builds of safari.

    ReplyDelete
  8. Oi micox,
    muito obrigado.
    É exactamente o que estava procurando há muito tempo, e parece que está funcionando perfeitamente.
    Ainda nao tinha oportunidade para testes com Mac/Safari, mas vou voltar e contar assim que possar.
    (O meu Português está horrívelmente enferrugado)

    ReplyDelete
  9. @abhi
    Intresting :)

    @Frits
    Ok, meu inglês também não é o melhor do mundo. hehehe
    Obrigado.

    ReplyDelete
  10. Hi micox,

    now I found a severe accessibility problem:
    In IE one cannot activate the "Browse" button using the keybord. Tabbing to the upload form and then pressing "Enter" when the focus is on the "Browse" button does not open the file window. It simply does nothing.
    In Fx and Op it works as supposed.
    I know: IE sucks. But this bug unfortunately renders the script useless for accessible sites :-)
    Any idea about this?

    ReplyDelete
  11. Hi Fritz,
    In IE, use SPACE BUTTON to open the dialog box and choose your file :-)

    Thanks.

    ReplyDelete
  12. Hi micox,

    SPACE! cool, you made my day. How could one imagine?

    Now I've got one more question:
    In Mac/Safari your script seems to open a new window (upa.php) showing the results, instead of writing to the <div id="upload...

    Any idea about this?

    Greetings from sunny Southern Germany
    Fritz

    ReplyDelete
  13. Could someone please explain in detail, what Abhi Beckert said on April 7, 2007 6:38 PM

    After replacing all uses of the "standard small functions" with their prototype.js counterparts, this upload script also works in nightly builds of safari.

    Wouldn't it be nice, to have this implemented in micox' Script, and have it working in Safari too?

    Thanx in advance
    Fritz

    ReplyDelete
  14. hello fritz.

    I will try adapt my script using some lib like jquery to working in Safary.

    When i finish, i'll post here.
    Thanks.

    ReplyDelete
  15. Great work!

    this is exactly what i've been looking for and i'm excited to see your project.

    I did have a problem getting it up and running though. I'm using java and posting to a jsp file but I cant get the uploads to work. Specifically im using uploadbean to do it.

    http://www.javazoom.net/jzservlets/uploadbean/documentation/installation.html

    It work's fine standalone, but not when I post to it.
    any ideas on what could of gone wrong?

    thanks!

    ReplyDelete
  16. I fixed my problem from above!

    I changed the name of my input file name to "uploadfile" and that was my problem.

    thanks!!

    ReplyDelete
  17. Ok Patrick.
    Sorry. I'm late and can't help you.

    Good that you fixed your problem.

    ReplyDelete
  18. Thanks,

    how can use it in form witn submit to ?

    ReplyDelete
  19. Hello Anonymous, please, read the examples in item 4. :-)
    Thanks

    ReplyDelete
  20. @micox, very nice script
    @fritz, is it possible that you post the mentioned prototype counterparts of the 'standard small fuctions'? my first excursus into js and, i know, i'm lazy, too --

    * thanks

    ReplyDelete
  21. ^
    \
    \___ appendix

    i forgot:
    - works fine in firefox/2.0.0.3; with the following change:

    else if (str.toLowerCase(form.nodeName) != "form") { erro += "The form of 1st parameter its not a form.\n"; }

    - opens a new window in safari/2.0.4 - which is not really useful for me (see also fritz' comment)

    * cheers

    ReplyDelete
  22. Very helpful script!

    Don't use javascript much and was wondering if there was an easy way to load 10 lines of HTML in place of html_show_loading as I'd like to show a pretty formated message while the users wait on the upload.

    $m(id_element).innerHTML = html_show_loading;

    This can be hard coded in the script and doesn't need to be passed in by the function.

    Also wondering if you heard from anyone about addressing some of the issues raised with Safari.

    Great help. Thanks for sharing.

    // Joff

    ReplyDelete
  23. Thanks Joff

    I'll work in a new version of this function, based in all help that i've receive in the comments.

    The problem with safari is that i dont have any browser safari for the test, but i'll search a way to resolve this.

    Thanks.

    ReplyDelete
  24. That's great news! Would love to help test your next version.

    It would be very cool to have a PC emulator of Safari. Did a quick search and did not find.

    Do you have any thoughts on how to hard code a few lines of HTML text into innerHTML in place of the html_show_loading var?

    Appreciated,
    joff

    ReplyDelete
  25. @joff:

    as easy as this:


    $m(id_element).innerHTML = "<p><img src=\"waiting.gif\" alt=\"\" border=\"0\" width=\"95\" height=\"11\" />uploading ...</p>";

    have a look at the result at:
    http://webdesign.weisshart.de/chat/chat.php

    Safari Emulator? better than that: A real Safari remotely controlled at:
    http://www.browserpool.de/kc/wob/portal.jsp?lang=en
    The free test account does a perfect job

    greetings
    Fritz

    ReplyDelete
  26. F-

    Thanks for the pointer. Wasn't escaping things properly :(

    WRT to a remote controlled Safari...that's cool!

    Take care,
    Joff

    ReplyDelete
  27. Got micoxUpload working in my webapp. Butt I'm still curious about Abhi Beckert's comment on April 7, 2007 about how he got micoxUpload working in Safari...

    Since Safari has become available for Windows (http://www.apple.com/safari/download/, still in beta) we PC guys have no excuses left for not making our webapps compatible with this Mac browser.

    So Abhi, could you please point us in the right direction?

    ReplyDelete
  28. Hey micox, parabéns por ter seu script publicado no Smashing Magazine.
    Sucesso e continue com o excelente trabalho.
    http://www.smashingmagazine.com/2007/07/09/best-of-mayjune-2007/
    Abraços,

    canha.

    ReplyDelete
  29. Hey there,

    tks for this, i really like it.but i can't use it inside an other form whith submit fuction

    Thank you for you help

    ReplyDelete
  30. Nice script. I was wondering if someone could help me out though. I am going to be using it for uploading images and what I want to do is show the image after it is uploaded but I dont know how to return the image. Can anyone help me out?

    Thanks
    doom

    ReplyDelete
  31. Hi anonymous.
    To do that you just need send back the tag img with the new url of the uploaded image.
    More doubts, send a email :)

    ReplyDelete
  32. I've had great success with the script on my site but it doesn't work with the new Safari. Did any of the folks familiar with Safari offer suggestions on how to fix?

    Appreciated,
    Joff

    ReplyDelete
  33. I have tested this script on Firefox 2.0 and i can't see the image I have uploaded becaue Firefox has a problem with the iframes. How did you do to enable this on FF? thanks in advance,
    Alessio

    ReplyDelete
  34. Hi Ace of Spades (motorhead rules heheh), i've tested my script now and its ok. No problems with FF2.
    If you want, i can send to you the php script that store the file in the server to use with my js-script for upload.

    ReplyDelete
  35. awesome code man! Just what I needed. I am using it to add image upload to sugarcrm.

    When I upload image, I dont want it to show the browse file input field again. How do I stop it from re-creating that field?

    ReplyDelete
  36. Hi Richard.
    You must delete the input element when you call my function.
    Try Put:
    form.parentNode.removeChild(form)
    above the line:
    $m(id_element).innerHTML = html_error_http;

    ReplyDelete
  37. This is not working my friend.

    I tried different variation, like adding it to a setTimeout call and but doest work.

    Can you post a different way to remove the input field?

    ReplyDelete
  38. I noticed that on http://webdesign.weisshart.de/chat/chat.php
    when you upload a file, it does not repeat the input field form, and then I looked at the .js file http://webdesign.weisshart.de/chat/micoxUpload.js
    And its exactly the same... no need to remove anything, it just does not repeat the input file.

    I am going crazy on this, how to remove the repeated input. Please some on help on this!

    ReplyDelete
  39. Hi richard, try this:

    after:
    setTimeout(function(){ remove($m('micox-temp'))}, 250);

    put:
    form.reset();

    ReplyDelete
  40. Hi, thanks for your reply...

    That does not work either...

    You can view my working version here:

    http://printerzone.net/uploadimages/testajax.php
    http://printerzone.net/uploadimages/testajax.js

    What I need done is that when you select the image file to upload...
    #1 the initial input field disappears (done)
    #2 a thumbnail of the image is shown (done)
    #3 Do not show again the input field (MISSING)

    Thanks for your help!

    ReplyDelete
  41. Ops. sorry.

    Put this above that setTimeout:

    var inp = form.getElementsByTagName('input')
    for(var s in inp){ if(inp[s].type=='file'){
    form.removeChild(inp[s]);
    }}
    This will remove the input-file.

    ReplyDelete
  42. Nope, thats not working either. You can test out my code in the link above and you will see yourself.

    You can also look at the js file and you will see that i placed the properly.

    FireFox FireBug is giving me this error...

    Node was not found" code: "8
    [Break on this error] form.removeChild(inp[s]);

    ReplyDelete
  43. Hei, your server side script testajax.php that is returning the input-file aggain.
    You need to put a IF in your server-side script (testajax.php) to not print the form when you upload a image. :)
    The solution its simple heheheh.
    When you upload a image, just print this image and not print the form again.

    ReplyDelete
  44. Hi, yeah that was the problem.


    Another issue now...

    I need to reference the form in another way, not this.form, because I have already others forms referenced like that.

    So I tried the following...

    #1 adding an id to the form and adding micoxUpload('formId','upload.php'... (DID NOT WORK)

    #2 adding a name to the form and adding micoxUpload('formName','upload.php'... (DID NOT WORK)

    I also tried not using the qoutes '' but then it doesn't work at all.

    I just to figure out a way to identify the form that is NOT this.form

    Thanks Again!

    ReplyDelete
  45. actually I found out the issue is that this form were are using is inside another form. So that's why I cannot refer to it as this.form and also why referring to its id doesnt work either.

    I need to come up with some savvy js code the reference the id of a form inside another form

    You think you can give me a hand on this Micox? I' trying to create a field in sugarm crm that allows image upload.

    Thanks! I welcome any ideas

    ReplyDelete
  46. Just in case someone uses SugarCRM and is interested in creating a field type that allows image upload, this is the thread I started and of coarse I am using the code from Micox.

    http://www.sugarcrm.com/forums/showthread.php?t=26723

    ReplyDelete
  47. Hi Micox,

    It would be really nice of you if you could drop by and give some feedback in trying to implement your code into sugarCrm.

    I have detailed the progress and issues, so please I inivite you to take a look and see if you can contribute with your expertise.

    Thanks!

    http://www.sugarcrm.com/forums/showthread.php?t=26723

    ReplyDelete
  48. Hi Richard. I will see your forum, but in next comunications send-me a email (or tell your email).
    bye, thanks :)

    ReplyDelete
  49. Hi Micox,
    very nice script, saved me a lot of time!

    I'm not much of a JS programmer so I have a question:
    I made the server-side script in php, and if the file uploads correctly it returns 1 and if not 0. If the file uploaded ok I need to call another function, and if not just write something in id_element. Any ideas?

    ReplyDelete
  50. Yeah, anonymous. I made a new function that accepts a callback function and you will do this that you want.
    Send me a email and i will send the new code to you.

    ReplyDelete
  51. hi micox..
    perfect script very well done.. this is what exactly what im looking for..

    there were some bugs but they are all have been fixed myself.

    i'll be implementing this script to one of my big web project and i'll surely put your name there as part of script contributor..

    VERY WELL DONE..

    ReplyDelete
  52. This comment has been removed by the author.

    ReplyDelete
  53. Lovin' the script and got it working perfectly on the first try, I just have a simple request:

    Is there a way to have the script not erase the result of the upload?

    Basically I want it to append the new upload info echoed from upa.php on top of the old ones to generate a list of all uploaded files.

    Any help would be much appreciated!

    ReplyDelete
  54. Hi h00rj

    I will post in this week a new version of upload script where i will explain a example to do this that you want. ok?

    I'll send a email to you.

    Thanks.

    ReplyDelete
  55. Amazing Job, just saved me a weeks worth of work!

    Mucho Kudos to you my friend!

    ReplyDelete
  56. Thanks for this, use lots of AJAX on my sites and needed to incorporate file uploading with progress bar for client. This does the trick. Well done. So simple, but then the best solutions are...

    ReplyDelete
  57. Well this a great idea, i have used your script, the script is working good, but the addEvent & remove Event thing is not working properly for me in mac safari , i am trying to fix this, the problem is that mac safari is not detecting the "iframe load event Listener" , if u can help me out in this?

    But last & not the list great idea.

    Mail me on "sinash2003@gmail.com"

    ReplyDelete
  58. If the id_element - element that will receive return of upload - has the same parent Node as the Form, you will run into difficulties.

    Why not try something simple like this?

    function Uploader(form, urlAction, id_returnElement, html_loadMessage, html_HttpError){
    this.oForm = typeof(form) == "string" ? this.mId(form) : form;
    this.iFrameObjId = null;
    this.httpError = html_HttpError;
    this.urlAction = urlAction;
    this.htmlOnLoading = html_loadMessage;
    this.returnElementId = id_returnElement;
    this.timeoutId = null;
    this.createIFrame();
    }
    Uploader.prototype.mId = function(sId){
    return document.getElementById(sId);
    }
    Uploader.prototype.createIFrame = function(){
    var iframe = document.createElement("iframe");
    iframe.setAttribute("id","hiddenFrame");
    iframe.setAttribute("name","hiddenFrame");
    iframe.setAttribute("width", "0");
    iframe.setAttribute("height","0");
    iframe.setAttribute("border","0");
    iframe.setAttribute("style", "width: 0; height: 0; border: none;");
    var oNode = this.mId("buffer");
    oNode.appendChild(iframe);
    window.frames['hiddenFrame'].name="hiddenFrame";
    this.iFrameObjId = this.mId("hiddenFrame");
    }
    Uploader.prototype.removeNode = function(oId){
    var oNode = oId;
    if(typeof oNode == 'object' && oNode != null){
    oNode.parentNode.removeChild(oNode);
    this.iFrameObjId = null;
    }
    }
    Uploader.prototype.addEvent = function(oId, sEventtype, fn){
    if (oId.addEventListener){
    oId.addEventListener(sEventtype, fn, true);
    }
    // IE
    else if(oId.attachEvent){
    oId.attachEvent("on"+sEventtype, fn);
    }
    }
    Uploader.prototype.removeEvent = function( obj, type, fn ) {
    if(obj.detachEvent) {
    obj.detachEvent('on'+type, fn);
    } else {
    obj.removeEventListener( type, fn, false );
    }
    }
    Uploader.prototype.doUpload = function(){
    var oThis = this;
    var OnUploadCompleted = function (){
    oThis.removeEvent(oThis.mId("hiddenFrame"), "load", OnUploadCompleted);
    window.parent.clearTimeout(oThis.timeoutId);
    window.parent.document.getElementById(oThis.returnElementId).innerHTML = window.frames['hiddenFrame'].document.body.innerHTML;
    };
    this.addEvent(this.mId("hiddenFrame"), "load", OnUploadCompleted);
    this.oForm.setAttribute("target", "hiddenFrame");
    this.oForm.setAttribute("action", this.urlAction);
    this.oForm.setAttribute("method", "POST");
    this.oForm.setAttribute("enctype", "multipart/form-data");
    this.oForm.submit();
    this.mId(\"loadMessage\").innerHTML = this.htmlOnLoading;
    this.timeoutId = window.setTimeout(function(){oThis.mId('loadMessage').innerHTML = oThis.httpError;}, 20000);
    }

    Joachim

    ReplyDelete
  59. Sorry that was nonsense. You will run into difficulties, if the Id of the element, which will receive the return of the Upload is the parent Node of the form. You append the IFrame to the parent Node of the form. So the returned html will overwrite the IFrame.

    Joachim

    ReplyDelete
  60. Thanks joachim,
    I had not think about this problem.
    Thanks.

    ReplyDelete
  61. Here is a new version of my function Uploader. Basically I added the line

    this.oForm.setAttribute("encoding", "multipart/form-data");

    which is necessary for IE to submit the form properly. At the end of the function OnUploadCompleted which is called when the Iframe reloads I added the timeout to delete the Iframe. It is necessary to delete the Iframe for IE to redo the Upload, otherwise the function Uploader will not work, if called a second time. On the other hand if you delete the Iframe, Mozilla won't work properly if the function Uploader is called a second time.
    Now it works in IE and Mozilla Browsers.

    Joachim

    // Uploader
    function Uploader(form, urlAction, id_returnElement, html_loadMessage, html_HttpError){
    this.oForm = typeof(form) == "string" ? this.mId(form) : form;
    this.iFrameObjId;
    this.httpError = html_HttpError;
    this.urlAction = urlAction;
    this.htmlOnLoading = html_loadMessage;
    this.returnElementId = id_returnElement;
    this.timeoutId = null;
    this.createIFrame();
    }
    Uploader.prototype.mId = function(sId){
    return document.getElementById(sId);
    }
    Uploader.prototype.createIFrame = function(){
    var iframe = document.createElement("iframe");
    iframe.setAttribute("id", "hiddenFrame");
    iframe.setAttribute("name", "hiddenFrame");
    iframe.setAttribute("width", "0");
    iframe.setAttribute("height", "0");
    iframe.setAttribute("border", "0");
    iframe.setAttribute("style", "width: 0; height: 0; border: none;");
    var oNode = this.mId("buffer");
    oNode.appendChild(iframe);
    window.frames['hiddenFrame'].name="hiddenFrame";
    this.iFrameObjId = this.mId("hiddenFrame");
    }
    Uploader.prototype.removeNode = function(oId){
    var oNode = oId;
    if(typeof oNode == 'object' && oNode != null){
    oNode.parentNode.removeChild(oNode);
    }
    }
    Uploader.prototype.addEvent = function(oId, sEventtype, fn){
    if (oId.addEventListener){
    oId.addEventListener(sEventtype, fn, true);
    }
    // IE
    else if(oId.attachEvent){
    oId.attachEvent("on"+sEventtype, fn);
    }
    }
    Uploader.prototype.removeEvent = function( obj, type, fn ) {
    if(obj.detachEvent) {
    obj.detachEvent('on'+type, fn);
    } else {
    obj.removeEventListener( type, fn, false );
    }
    }
    Uploader.prototype.doUpload = function(){
    var oThis = this;
    var OnUploadCompleted = function (){
    oThis.removeEvent(oThis.mId("hiddenFrame"), "load", OnUploadCompleted);
    window.parent.clearTimeout(oThis.timeoutId);
    alert(window.frames['hiddenFrame'].document.body.innerHTML);
    window.parent.document.formEditor.picture_id.value = window.frames['hiddenFrame'].document.uploadForm.picture_id.value;
    window.parent.document.getElementById(oThis.returnElementId).innerHTML = window.frames['hiddenFrame'].document.body.innerHTML;
    // del the iframe if internet explorer
    if(oThis.mId('hiddenFrame').attachEvent){
    window.parent.setTimeout(function(){oThis.removeNode(oThis.mId('hiddenFrame'))}, 250);
    }
    };
    this.addEvent(this.mId("hiddenFrame"), "load", OnUploadCompleted);
    this.oForm.setAttribute("target", "hiddenFrame");
    this.oForm.setAttribute("action", this.urlAction);
    this.oForm.setAttribute("method", "POST");
    this.oForm.setAttribute("enctype", "multipart/form-data");
    // IE
    this.oForm.setAttribute("encoding", "multipart/form-data");
    this.oForm.submit();
    this.mId("loadMessage").innerHTML = this.htmlOnLoading;
    this.timeoutId = window.setTimeout(function(){oThis.mId('loadMessage').innerHTML = oThis.httpError;}, 20000);
    }

    ReplyDelete
  62. This comment has been removed by the author.

    ReplyDelete
  63. Hi there, thanks for the great script . Ive tried a few and this is the easiest to you by far

    Thx

    Question is there a way i can limit the number downloads eg 12. Ive tried replicating the input field but it gives me strange results if i have more than one in a form.

    ReplyDelete
  64. okay.... i got a question..

    so basically this js didn't upload anything, right?

    I have to make my own the 'upa.php' with php function like
    @move_uploaded_file
    @rename
    ..etc

    isn't it?
    How about adding an ajax upload progress bar? any idea how to do that?

    ReplyDelete
  65. Yes. You have to make your own upa.php.

    You can see progressbars just with flash (swf).

    ReplyDelete
  66. Hi Micox,
    I appreciate your great work and am very thankful about you publishing your great work.

    Keep on the good work!

    ReplyDelete
  67. I really appreciate the work. But i am facing one critical issue and would be happy if any of you will be able to provide the solution for me.

    I am uploading a xls file using the iframe upload method and then i am doing some database operation in the server side which is taking about 1-2 mins to complete. The wierd thing is , though the response was sent by the server program(servlet), the javascript was not getting the response and posting the same request again to the server. It shows the response only in the second time.

    Can anyone out there able to help out on this issue.

    Thanks
    urs_amt

    ReplyDelete
  68. I have a new version if you want to test before use.
    the script: http://naironjcg.googlepages.com/micoxUpload2.js
    The examples (see de source) : http://naironjcg.googlepages.com/upload5.htm (in this examples, the upload dont work because googlepages.com dont support)

    Thanks.

    ReplyDelete
  69. I tried to use your script (micoxUpload2.js) with IE and FireFox - everything was ok, but when I try to upload a file using Opera (9.27) something goes wrong.

    ReplyDelete
  70. About the problem with Opera, which I mentioned before:
    It looks strange, but if I insert a string like that:
    'alert("sometext");'
    just before the following line in the script:
    'timeload = setInterval(periodic,500);'
    the script starts working with Opera (9.27) without any problems

    Any ideas?

    ReplyDelete
  71. Micox, great script!
    Could you share with us how would I be able to have multiple uploads in a single form?

    ReplyDelete
  72. Ok, I found a way to allow multiple uploads in a single form..
    This may not be the only/best way but it works for me =)

    Add the following code after
    form.submit();


    //reset form back to original state
    form.removeAttribute("target"); form.removeAttribute("action"); form.removeAttribute("method"); form.removeAttribute("enctype"); form.removeAttribute("encoding");

    form.setAttribute("action","saveform.php"); form.setAttribute("method","post");


    ofcourse you should change the attributes to whatever is needed for your case. that's just what I used for mine.

    ReplyDelete
  73. Thankx for this code!
    It really helped a lot.

    ReplyDelete
  74. hi ,
    Thanks for uploading the script.
    I am trying to integrate ur script on my page. I used the php from http://www.w3schools.com/PHP/php_file_upload.asp . But when i try to upload a file .. it always gives me 'Invalid File' error . Is there a solution to this ?

    ReplyDelete
  75. Hi,

    Your image must respect this conditions:

    if ((($_FILES["file"]["type"] == "image/gif")
    || ($_FILES["file"]["type"] == "image/jpeg")
    || ($_FILES["file"]["type"] == "image/pjpeg"))
    && ($_FILES["file"]["size"] < 20000)

    But its not a restriction of my upload script but of the php script.

    Thanks.

    ReplyDelete
  76. I am developing a major new product and am thrilled with your microX. However, I have found that it does not work with either Safari 3.1.2 for Windows, or the Google Chrome 0.3.154.9 (these two seem to have some shared code).

    It works without problem on Firefox 3.0.3, IE 6.x, and Opera 9.51 (I don't bother much with Netscape anymore).

    Can you provide an updated version that will also work with the current versions of Safari and Chrome?

    Thank you!

    drdave

    ReplyDelete
  77. ... and, on the MAC, Safari 2.0.4 gets the correct result, but puts it into a separate window...

    drdave

    ReplyDelete
  78. Man, I have been racking my brain trying too get this to work with chrome....

    I love your work I have modified it slightly to meet my needs but I just cannot get it.

    I have nrowed it down to the function remove()

    it only contains this:
    theVar.parentNode.removeChild(theVar);

    Any ideas???

    ReplyDelete
  79. Well, it took 2 days but I finally got this to work in all modern browsers (IE6, IE7, Firefox 2+, Opera, Safari, Chrome), etc...

    Its pretty simple actually apples webKit is where the issue lies, so I just decided to detect it by adding this function:

    function isWebKit(){
    return RegExp("AppleWebKit/").test(navigator.userAgent);
    }

    Then right after the first line of the function micoxUpload() add the following:
    var detectWebKit = isWebKit();

    Then the last step is replace:
    setTimeout(function(){ remove($m('micox-temp'))}, 250);

    With:
    if(detectWebKit){
    remove($m('ajax-temp'));
    }else{
    setTimeout(function(){ remove($m('micox-temp'))}, 250);
    }

    Hope this helps someone, I cannot tell you how many hours I wasted on this!

    comments? tim {at} atwebresults {dot} com

    or see it in an app:
    http://restaurantmenuscript.com/

    ReplyDelete
  80. Hi Micox

    Thanks for the code.

    I just feel the Script is working. But I didn’t get the exact output. Please advice me...

    I just copy all your recommended scripts and code.

    But see when I use upa.php as that sentenced in the below URL

    http://www.w3schools.com/PHP/php_file_upload.asp

    But the output I found is

    Upload:
    Type:
    Size: 0 Kb
    Temp file:
    already exists.

    Feel that I am not able to store the uploaded image in the recommended folder called "Upload"....Kindly advice me.....If any one of this Commented zone.....

    Get me @ jothirajan.veerabathiran@makeeit.com

    Or

    jothirajan.veerabathiran@makeeitsolutions.com

    ReplyDelete
  81. Thanks a lot......

    The first code from the web that works in front me...

    Excellent script..Just cut-copy-paste...

    Great......i first thought that "without submitting a form" how can the script upload the image in the folder,but your script makes the JS upload in a fantastic way.

    Thanks once again...

    Best and Smart code...

    And once again thanks for your quick reply to my personal ID....Thanks once again

    ReplyDelete
  82. Thanks a lot......

    The first code from the web that works in front me...

    Excellent script..Just cut-copy-paste...

    Great......i first thought that "without submitting a form" how can the script upload the image in the folder,but your script makes the JS upload in a fantastic way.

    Thanks once again...

    Best and Smart code...

    And once again thanks for your quick reply to my personal ID....Thanks Náiron JCG

    ReplyDelete
  83. Yes man i got it, but the thing is i cant understand the Portuguese language...You know i am using ur code for the video conversion just like that of the Youtube.Thanks man...

    One thing if you have any code to show the loading image or text for the page delay.For example if i am in the index.html and jump to reg.html it takes some certain time to go to
    that page, at that time the site become zigzag and white blank...

    Thing is can you advice me...To show something in that particular period of time( page delay)...Or anyone from this forum zone....

    Thanks and Regards
    jothirajan.V

    ReplyDelete
  84. THANKS MICOX FOR YOUR AWESOMENESS!!!
    AND THANKS TIM FOR THE SAFARI FIX!!!

    ReplyDelete
  85. This comment has been removed by the author.

    ReplyDelete
  86. I get only:
    Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in /home/antreee/public_html/test/up.php on line 33

    up.php taken from http://www.w3schools.com/PHP/php_file_upload.asp. Any ideas? :s

    ReplyDelete
  87. This comment has been removed by the author.

    ReplyDelete
  88. Need help in resolving the issue of micoxUpload.js Safari support

    Thanks Tim for the Safari fix. I really found it very helpful.

    There is an issue which I am still facing in Safari.
    The issue which I am facing is that the "carregou" function is not getting executed properly. Even though successful response from server has been received, the "innerHTML" of "micox-temp" is always "html_error_http" in Safari. For Firefox 3.0.7 and IE 6.0, the code is working fine.

    Following is the code which I am trying to execute:

    function isWebKit(){
    return RegExp("AppleWebKit/").test(navigator.userAgent);
    }

    function micoxUpload(form,url_action,id_element,html_show_loading,html_error_http,micoFileId, callback){
    /******
    * micoxUpload - Submit a form to hidden iframe. Can be used to upload
    * Versão: 1.0 - 03/03/2007 - Tested no FF2.0 IE6.0 e OP9.1
    * Parametros:
    * form - the form to submit or the ID
    * url_action - url to submit the form. like action parameter of forms.
    * id_element - element that will receive return of upload.
    * html_show_loading - Text (or image) that will be show while loading
    * html_error_http - Text (or image) that will be show if HTTP error.
    *******/

    //testing if 'form' is a html object or a id string
    form = typeof(form)=="string"?$m(form):form;
    var detectWebKit = isWebKit();

    var erro="";
    if(form===null || typeof(form)==="undefined"){ erro += "The form of 1st parameter does not exists.\n";}
    else if(form.nodeName.toLowerCase()!="form"){ erro += "The form of 1st parameter its not a form.\n";}
    if($m(id_element)===null){ erro += "The element of 3rd parameter does not exists.\n";}
    if(erro.length>0) {
    return;
    }

    //creating the iframe
    var iframe = document.createElement("iframe");
    iframe.setAttribute("id","micox-temp");
    iframe.setAttribute("name","micox-temp");
    iframe.setAttribute("width","0");
    iframe.setAttribute("height","0");
    iframe.setAttribute("border","0");
    iframe.setAttribute("style","width: 0; height: 0; border: none;");

    //add to document
    form.parentNode.appendChild(iframe);
    var fileName=$m(micoFileId).value;
    window.frames['micox-temp'].name="micox-temp"; //ie sucks

    //add event
    var carregou = function() {
    removeEvent( $m('micox-temp'),"load", carregou);
    $m(id_element).innerHTML = html_error_http;
    //del the iframe
    //setTimeout(function(){ remove($m('micox-temp'))}, 250000);
    if(detectWebKit){
    remove($m('micox-temp'));
    }else{
    setTimeout(function(){ remove($m('micox-temp'))}, 250000);
    }
    };
    addEvent( $m('micox-temp'),"load", carregou);

    //properties of form
    form.setAttribute("target","micox-temp");
    form.setAttribute("action",url_action+"&fileName="+fileName);
    form.setAttribute("method","post");
    form.setAttribute("enctype","multipart/form-data");
    form.setAttribute("encoding","multipart/form-data");
    iframe.callback=callback;
    //submit
    form.submit();

    //while loading
    if(html_show_loading.length > 0){
    $m(id_element).innerHTML = html_show_loading;
    }

    }


    Can Tim/anyone please suggest some solution for it. Thanks in advance for looking into my problem.

    My email id is: amitrnihar@gmail.com

    Thanks,
    Nihar.

    ReplyDelete
  89. I keep getting an error
    Error in upload
    and I have included the javascript file micoxUpload and used form #1 from your examples. Please help get this fixed.

    ReplyDelete
  90. I have an ASP.NET page with micoxUploader. When i test it on localhost server everything is all right, but when I test it on other server, I have a bug.
    1)press on browse button fist time
    2)choose img file
    3)file uploads on server
    4)click any place on page
    5)file uploads once more
    Please, any body help me.

    ReplyDelete
  91. hello.
    what is in the upa.php ?

    can you show me a examble .

    mfg

    ReplyDelete
  92. There's a problem when you have multiple upload buttons in the same page/form.

    When you start an upload, and start another one while the first one is still uploading. When both uploads are finished, they both return the last file uploaded - even though the actual files have been uploaded.

    Any remedy to this?

    Thanks!

    ReplyDelete
  93. finally, I got it to work for me in
    Firefox 3.5
    Opera <= 10.0
    Safari/Win
    Chrome
    IE 6.0 ... 8
    Opera <= 10.0

    (had to use micoxUpload2.js

    ReplyDelete
  94. Hi,
    First of all, thanks a lot for your code. This is exactly what I was looking for. If have integrated the same into my page. Have one query though, I want to show my users that file upload was successful when the upload process has completed sucessfully.
    Is there anyway, that I can do it?

    Thanks once again

    Jameel

    ReplyDelete
  95. Olá Micox,

    Estou a ter um problema na função "carregou" na variável "cross", o erro é o seguinte: "Reference error: Window is not defined".
    Já viste alguma vez este problema?

    Bom código :)

    Obrigado,
    JP.

    ReplyDelete
  96. @Prata
    Ummm problema novo desconhecido.
    Deve ter a ver com o navegador.
    Tente remover o window. que tem aí nesta função pra ver o que acontece.
    Até mais.

    ReplyDelete
  97. Fiz uma mudança no código e ele agora também funciona no CHROME e SAFARI.

    Substitui:

    var carregou = function() {
    removeEvent( $m('micox-temp'),"load", carregou);
    var cross = "javascript: ";
    cross += "window.parent.$m('" + id_elemento_retorno + "').innerHTML = document.body.innerHTML; void(0); ";
    $m(id_elemento_retorno).innerHTML = html_erro_http;
    $m('micox-temp').src = cross;
    //deleta o iframe
    setTimeout(function(){ remove($m('micox-temp'))}, 250);
    }


    por:


    var carregou = function() {
    window.document.getElementById( id_elemento_retorno ).innerHTML = 'Arquivo enviado com sucesso';
    }


    Dessa forma ele a mensagem de retorno vai normalmente.

    ReplyDelete
  98. Tim, your tip made my day! I was in touch w/ Micox trying to solve Chrome´s incompatibility problem e your tip solved it all. Thank you very much.

    ReplyDelete
  99. Someone could compile and test all suggested and approved mods and launch a micox v2.1, cross-browser version. Anybody?

    ReplyDelete
  100. I think i ve learn something today, I tried it with safari browser and it works great, Thanks a lot for the code

    ReplyDelete
  101. function remove(quem) {
    quem.parentNode.removeChild(quem);
    }

    This is giving error on IE9 :- parentNode is null. Don't know where others are testing as its a major dent using iframes. Any workaround?

    ReplyDelete
  102. Hi,

    it is nice script , i used to upload cv.if i upload doc file more than 2 mb it is showing 'Loading' text. please help ...

    Thanks

    ReplyDelete
  103. Great Work!!!
    I am very thankful to share this post.. I hope you have more information about this post.. So, Please share me.. Thanks..
    More info:- Gmail Technical Support

    ReplyDelete