常用的两种ajax上传文件的方式

时间:2022-11-27 16:20:08

一,ajaxfileupload

Java代码  常用的两种ajax上传文件的方式
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>  
  4. <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/fn" %>  
  5. <%@ taglib prefix="cus" uri="http://web.microcare.com/tag"%>  
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  7. <html>  
  8. <head>  
  9.     <script type="text/javascript" src="/tpl/html/common/ajaxfileupload/ajaxfileupload.js"></script>  
  10.     <c:import url="${contextpath}/tpl/html/appuploadjs.jsp" />  
  11. </head>  
  12. <body>  
  13.   
  14. <input type=file id="appFile" name="appFile" onchange="getValue();" style="-moz-opacity:0;filter:alpha(opacity=0);opacity:0;position:absolute;left:166px;" />  
  15. <input id="appFilename" style="color: green;border: 1px solid green;width:300px;" />  
  16. <input type="button" value="File" style="border: 1px solid green;width:80px;" />  
  17.   
  18.   
  19. </body>  
  20. </html>  

 

Java代码  常用的两种ajax上传文件的方式
  1. <%@ page contentType="text/html;charset=UTF-8"%>  
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>  
  3.   
  4. <script type="text/javascript">  
  5. function getValue(){  
  6.     document.getElementById('appFilename').value = document.getElementById('appFile').value;  
  7.     validateImage();  
  8.     ajaxFileUpload();  
  9. }  
  10.   
  11. function ajaxFileUpload()  
  12. {  
  13.     /* $("#loading") 
  14.     .ajaxStart(function(){ 
  15.         $(this).show(); 
  16.     }) 
  17.     .ajaxComplete(function(){ 
  18.         $(this).hide(); 
  19.     }); */  
  20.       
  21.     $.ajaxFileUpload  
  22.     (  
  23.         {  
  24.             <a href="/admin/blogs/'/json/dff.action?op=App.upload'">url:'/json/dff.action?op=App.upload'</a>,   
  25.             secureuri:false,  
  26.             fileElementId:'appFile',  
  27.             dataType: 'json',  
  28.             success: function (data, status)  
  29.             {  
  30.                 alert("1"+data);  
  31.                 alert("5"+data.data.errorCode);  
  32.                 if(typeof(data.errorCode) != undefined)  
  33.                 {  
  34.                     alert(data.data.errorCode);  
  35.                 }  
  36.             },  
  37.             error: function (data, status, e)  
  38.             {  
  39.                 alert("2"+data);  
  40.                 alert("3"+status);  
  41.                 alert("4"+e);  
  42.             }  
  43.         }  
  44.     )  
  45.     return false;  
  46. }  
  47.   
  48. //校验图片格式及大小 Add Date 2012-6-14 LIUYI  
  49. function validateImage() {  
  50.     var tmpFileValue = document.getElementById('appFilename').value;  
  51.     //校验图片格式  
  52.     if(/^.*?\.(apk|ipa)$/.test(tmpFileValue.toLowerCase())){  
  53.         return true;  
  54.     } else {  
  55.         alert("只能上传apk和ipa格式的文件!");  
  56.         return false;  
  57.     }  
  58.       
  59.     if(file.value == ""){  
  60.         alert("请选择上传的文件!");  
  61.         return false;  
  62.     }  
  63. }  
  64. </script>  

 

Java代码  常用的两种ajax上传文件的方式
  1. jQuery.extend({  
  2.       
  3.   
  4.     createUploadIframe: function(id, uri)  
  5.     {  
  6.             //create frame  
  7.             var frameId = 'jUploadFrame' + id;  
  8.             var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';  
  9.             if(window.ActiveXObject)  
  10.             {  
  11.                 if(typeof uri== 'boolean'){  
  12.                     iframeHtml += ' src="' + 'javascript:false' + '"';  
  13.   
  14.                 }  
  15.                 else if(typeof uri== 'string'){  
  16.                     iframeHtml += ' src="' + uri + '"';  
  17.   
  18.                 }     
  19.             }  
  20.             iframeHtml += ' />';  
  21.             jQuery(iframeHtml).appendTo(document.body);  
  22.   
  23.             return jQuery('#' + frameId).get(0);              
  24.     },  
  25.     createUploadForm: function(id, fileElementId, data)  
  26.     {  
  27.         //create form     
  28.         var formId = 'jUploadForm' + id;  
  29.         var fileId = 'jUploadFile' + id;  
  30.         var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');      
  31.         if(data)  
  32.         {  
  33.             for(var i in data)  
  34.             {  
  35.                 jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);  
  36.             }             
  37.         }         
  38.         var oldElement = jQuery('#' + fileElementId);  
  39.         var newElement = jQuery(oldElement).clone();  
  40.         jQuery(oldElement).attr('id', fileId);  
  41.         jQuery(oldElement).before(newElement);  
  42.         jQuery(oldElement).appendTo(form);  
  43.   
  44.   
  45.           
  46.         //set attributes  
  47.         jQuery(form).css('position''absolute');  
  48.         jQuery(form).css('top''-1200px');  
  49.         jQuery(form).css('left''-1200px');  
  50.         jQuery(form).appendTo('body');        
  51.         return form;  
  52.     },  
  53.   
  54.     ajaxFileUpload: function(s) {  
  55.         // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout          
  56.         s = jQuery.extend({}, jQuery.ajaxSettings, s);  
  57.         var id = new Date().getTime()          
  58.         var form = jQuery.createUploadForm(id, s.fileElementId, (typeof(s.data)=='undefined'?false:s.data));  
  59.         var io = jQuery.createUploadIframe(id, s.secureuri);  
  60.         var frameId = 'jUploadFrame' + id;  
  61.         var formId = 'jUploadForm' + id;          
  62.         // Watch for a new set of requests  
  63.         if ( s.global && ! jQuery.active++ )  
  64.         {  
  65.             jQuery.event.trigger( "ajaxStart" );  
  66.         }              
  67.         var requestDone = false;  
  68.         // Create the request object  
  69.         var xml = {}     
  70.         if ( s.global )  
  71.             jQuery.event.trigger("ajaxSend", [xml, s]);  
  72.         // Wait for a response to come back  
  73.         var uploadCallback = function(isTimeout)  
  74.         {             
  75.             var io = document.getElementById(frameId);  
  76.             try   
  77.             {                 
  78.                 if(io.contentWindow)  
  79.                 {  
  80.                      xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;  
  81.                      xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;  
  82.                        
  83.                 }else if(io.contentDocument)  
  84.                 {  
  85.                      xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;  
  86.                     xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;  
  87.                 }                         
  88.             }catch(e)  
  89.             {  
  90.                 jQuery.handleError(s, xml, null, e);  
  91.             }  
  92.             if ( xml || isTimeout == "timeout")   
  93.             {                 
  94.                 requestDone = true;  
  95.                 var status;  
  96.                 try {  
  97.                     status = isTimeout != "timeout" ? "success" : "error";  
  98.                     // Make sure that the request was successful or notmodified  
  99.                     if ( status != "error" )  
  100.                     {  
  101.                         // process the data (runs the xml through httpData regardless of callback)  
  102.                         var data = jQuery.uploadHttpData( xml, s.dataType );      
  103.                         // If a local callback was specified, fire it and pass it the data  
  104.                         if ( s.success )  
  105.                             s.success( data, status );  
  106.       
  107.                         // Fire the global callback  
  108.                         if( s.global )  
  109.                             jQuery.event.trigger( "ajaxSuccess", [xml, s] );  
  110.                     } else  
  111.                         jQuery.handleError(s, xml, status);  
  112.                 } catch(e)   
  113.                 {  
  114.                     status = "error";  
  115.                     jQuery.handleError(s, xml, status, e);  
  116.                 }  
  117.   
  118.                 // The request was completed  
  119.                 if( s.global )  
  120.                     jQuery.event.trigger( "ajaxComplete", [xml, s] );  
  121.   
  122.                 // Handle the global AJAX counter  
  123.                 if ( s.global && ! --jQuery.active )  
  124.                     jQuery.event.trigger( "ajaxStop" );  
  125.   
  126.                 // Process result  
  127.                 if ( s.complete )  
  128.                     s.complete(xml, status);  
  129.   
  130.                 jQuery(io).unbind()  
  131.   
  132.                 setTimeout(function()  
  133.                                     {   try   
  134.                                         {  
  135.                                             jQuery(io).remove();  
  136.                                             jQuery(form).remove();    
  137.                                               
  138.                                         } catch(e)   
  139.                                         {  
  140.                                             jQuery.handleError(s, xml, null, e);  
  141.                                         }                                     
  142.   
  143.                                     }, 100)  
  144.   
  145.                 xml = null  
  146.   
  147.             }  
  148.         }  
  149.         // Timeout checker  
  150.         if ( s.timeout > 0 )   
  151.         {  
  152.             setTimeout(function(){  
  153.                 // Check to see if the request is still happening  
  154.                 if( !requestDone ) uploadCallback( "timeout" );  
  155.             }, s.timeout);  
  156.         }  
  157.         try   
  158.         {  
  159.   
  160.             var form = jQuery('#' + formId);  
  161.             jQuery(form).attr('action', s.url);  
  162.             jQuery(form).attr('method''POST');  
  163.             jQuery(form).attr('target', frameId);  
  164.             if(form.encoding)  
  165.             {  
  166.                 jQuery(form).attr('encoding''multipart/form-data');                 
  167.             }  
  168.             else  
  169.             {     
  170.                 jQuery(form).attr('enctype''multipart/form-data');              
  171.             }             
  172.             jQuery(form).submit();  
  173.   
  174.         } catch(e)   
  175.         {             
  176.             jQuery.handleError(s, xml, null, e);  
  177.         }  
  178.           
  179.         jQuery('#' + frameId).load(uploadCallback   );  
  180.         return {abort: function () {}};   
  181.   
  182.     },  
  183.   
  184.     uploadHttpData: function( r, type ) {  
  185.         var data = !type;  
  186.         data = type == "xml" || data ? r.responseXML : r.responseText;  
  187.         // If the type is "script", eval it in global context  
  188.         if ( type == "script" )  
  189.             jQuery.globalEval( data );  
  190.         // Get the JavaScript object, if JSON is used.  
  191.         if ( type == "json" )  
  192.             eval( "data = " + data );  
  193.         // evaluate scripts within html  
  194.         if ( type == "html" )  
  195.             jQuery("<div>").html(data).evalScripts();  
  196.   
  197.         return data;  
  198.     },  
  199.       
  200.     handleError: function( s, xhr, status, e )      {  
  201.         // If a local callback was specified, fire it  
  202.         if ( s.error ) {  
  203.             s.error.call( s.context || s, xhr, status, e );  
  204.         }  
  205.   
  206.         // Fire the global callback  
  207.         if ( s.global ) {  
  208.             (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );  
  209.         }  
  210.     }  
  211. })  

 

第二种为ajaxupload

Java代码  常用的两种ajax上传文件的方式
  1. 上传文档:  
  2. <script src="/js/common/AjaxUpload.js" type="text/javascript"></script>  
  3. <div class="uploadFile">  
  4.     <span id="doc"><input type="text" disabled="disabled" /></span>  
  5.     <input type="hidden" id="hidFileName"  />  
  6.     <input type="button" id="btnUploadFile" value="上传" />  
  7.     <input type="button" id="btnDeleteFile" value="删除"  />  
  8. </div>  
  9.   
  10. 上传图片:  
  11. <div class="uploadImg">  
  12.     <img id="imgShow" src="/images/nophoto.gif" />  
  13.     <input type="hidden" id="hidImgName" />  
  14.     <input type="button" id="btnUploadImg" value="上传" />  
  15.     <input type="button" id="btnDeleteImg" value="删除" />  
  16. </div>  

 

Java代码  常用的两种ajax上传文件的方式
  1. window.onload = function() {  
  2.     init();  //初始化  
  3. }  
  4.   
  5. //初始化  
  6. function init() {  
  7.     //初始化文档上传  
  8.     var btnFile = document.getElementById("btnUploadFile");  
  9.     var doc = document.getElementById("doc");  
  10.     var hidFileName = document.getElementById("hidFileName");  
  11.     document.getElementById("btnDeleteFile").onclick = function() { DelFile(doc, hidFileName); };  
  12.     g_AjxUploadFile(btnFile, doc, hidFileName);  
  13.       
  14.     //初始化图片上传  
  15.     var btnImg = document.getElementById("btnUploadImg");  
  16.     var img = document.getElementById("imgShow");  
  17.     var hidImgName = document.getElementById("hidImgName");  
  18.     document.getElementById("btnDeleteImg").onclick = function() { DelImg(img, hidImgName); };  
  19.     g_AjxUploadImg(btnImg, img, hidImgName);  
  20. }  
  21.   
  22.   
  23. var g_AjxTempDir = "/file/temp/";  
  24. //文档上传  
  25. function g_AjxUploadFile(btn, doc, hidPut, action) {  
  26.     var button = btn, interval;  
  27.     new AjaxUpload(button, {  
  28.     action: ((action == null || action == undefined) ? '/Common/UploadHandler.ashx?fileType=file' : action),  
  29.         data: {},  
  30.         name: 'myfile',  
  31.         onSubmit: function(file, ext) {  
  32.             if (!(ext && /^(rar|zip|pdf|pdfx|txt|csv|xls|xlsx|doc|docx|RAR|ZIP|PDF|PDFX|TXT|CSV|XLS|XLSX|DOC|DOCX)$/.test(ext))) {  
  33.                 alert("您上传的文档格式不对,请重新选择!");  
  34.                 return false;  
  35.             }  
  36.         },  
  37.         onComplete: function(file, response) {  
  38.             flagValue = response;  
  39.             if (flagValue == "1") {  
  40.                 alert("您上传的文档格式不对,请重新选择!");  
  41.             }  
  42.             else if (flagValue == "2") {  
  43.                 alert("您上传的文档大于2M,请重新选择!");  
  44.             }  
  45.             else if (flagValue == "3") {  
  46.                 alert("文档上传失败!");  
  47.             }  
  48.             else {  
  49.                 hidPut.value = response;  
  50.                 doc.innerHTML="<a href='" + g_AjxTempDir + response + "' target='_blank'>" + response + "</a>";  
  51.             }  
  52.         }  
  53.     });  
  54. }  
  55. //图片上传  
  56. function g_AjxUploadImg(btn, img, hidPut) {  
  57.     var button = btn, interval;  
  58.     new AjaxUpload(button, {  
  59.         action: '/Common/UploadHandler.ashx?fileType=img',  
  60.         data: {},  
  61.         name: 'myfile',  
  62.         onSubmit: function(file, ext) {  
  63.             if (!(ext && /^(jpg|JPG|png|PNG|gif|GIF)$/.test(ext))) {  
  64.                 alert("您上传的图片格式不对,请重新选择!");  
  65.                 return false;  
  66.             }  
  67.         },  
  68.         onComplete: function(file, response) {  
  69.             flagValue = response;  
  70.             if (flagValue == "1") {  
  71.                 alert("您上传的图片格式不对,请重新选择!");  
  72.             }  
  73.             else if (flagValue == "2") {  
  74.                 alert("您上传的图片大于200K,请重新选择!");  
  75.             }  
  76.             else if (flagValue == "3") {  
  77.                 alert("图片上传失败!");  
  78.             }  
  79.             else {  
  80.                 hidPut.value = response;  
  81.                 img.src = g_AjxTempDir + response;  
  82.             }  
  83.         }  
  84.     });  
  85. }  
  86.   
  87. //删除文档  
  88. function DelFile(doc, hidPut) {  
  89.     hidPut.value = "";  
  90.     doc.innerHTML = "<input type=\"text\" disabled=\"disabled\" />";  
  91. }  
  92.   
  93. //删除图片  
  94. function DelImg(img, hidPut) {  
  95.     hidPut.value = "";  
  96.     img.src = "/images/nophoto.gif";  
  97. }  

 

Java代码  常用的两种ajax上传文件的方式
  1. /*上传文件*/  
  2. .uploadFile{margin-bottom:10px;}  
  3. /*上传图片*/  
  4. .uploadImg{}  
  5. .uploadImg img{width:102px; height:64px; border:1px solid #CCCCCC; display: block;}  

 

Java代码  常用的两种ajax上传文件的方式
  1. /** 
  2.  * AJAX Upload ( http://valums.com/ajax-upload/ )  
  3.  * Copyright (c) Andris Valums 
  4.  * Licensed under the MIT license ( http://valums.com/mit-license/ ) 
  5.  * Thanks to Gary Haran, David Mark, Corey Burns and others for contributions  
  6.  */  
  7. (function () {  
  8.     /* global window */  
  9.     /* jslint browser: true, devel: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true */  
  10.   
  11.     /** 
  12.      * Wrapper for FireBug's console.log 
  13.      */  
  14.   
  15.     function log() {  
  16.         if (typeof(console) != 'undefined' && typeof(console.log) == 'function') {  
  17.             Array.prototype.unshift.call(arguments, '[Ajax Upload]');  
  18.             console.log(Array.prototype.join.call(arguments, ' '));  
  19.         }  
  20.     }  
  21.   
  22.     /** 
  23.      * Attaches event to a dom element. 
  24.      * @param {Element} el 
  25.      * @param type event name 
  26.      * @param fn callback This refers to the passed element 
  27.      */  
  28.   
  29.     function addEvent(el, type, fn) {  
  30.         if (el.addEventListener) {  
  31.             el.addEventListener(type, fn, false);  
  32.         } else if (el.attachEvent) {  
  33.             el.attachEvent('on' + type, function () {  
  34.                 fn.call(el);  
  35.             });  
  36.         } else {  
  37.             throw new Error('not supported or DOM not loaded');  
  38.         }  
  39.     }  
  40.   
  41.     /** 
  42.      * Attaches resize event to a window, limiting 
  43.      * number of event fired. Fires only when encounteres 
  44.      * delay of 100 after series of events. 
  45.      *  
  46.      * Some browsers fire event multiple times when resizing 
  47.      * http://www.quirksmode.org/dom/events/resize.html 
  48.      *  
  49.      * @param fn callback This refers to the passed element 
  50.      */  
  51.   
  52.     function addResizeEvent(fn) {  
  53.         var timeout;  
  54.   
  55.         addEvent(window, 'resize', function () {  
  56.             if (timeout) {  
  57.                 clearTimeout(timeout);  
  58.             }  
  59.             timeout = setTimeout(fn, 100);  
  60.         });  
  61.     }  
  62.   
  63.     // Needs more testing, will be rewriten for next version          
  64.     // getOffset function copied from jQuery lib (http://jquery.com/)  
  65.     if (document.documentElement.getBoundingClientRect) {  
  66.         // Get Offset using getBoundingClientRect  
  67.         // http://ejohn.org/blog/getboundingclientrect-is-awesome/  
  68.         var getOffset = function (el) {  
  69.             var box = el.getBoundingClientRect();  
  70.             var doc = el.ownerDocument;  
  71.             var body = doc.body;  
  72.             var docElem = doc.documentElement; // for ie   
  73.             var clientTop = docElem.clientTop || body.clientTop || 0;  
  74.             var clientLeft = docElem.clientLeft || body.clientLeft || 0;  
  75.   
  76.             // In Internet Explorer 7 getBoundingClientRect property is treated as physical,  
  77.             // while others are logical. Make all logical, like in IE8.   
  78.             var zoom = 1;  
  79.             if (body.getBoundingClientRect) {  
  80.                 var bound = body.getBoundingClientRect();  
  81.                 zoom = (bound.right - bound.left) / body.clientWidth;  
  82.             }  
  83.   
  84.             if (zoom > 1) {  
  85.                 clientTop = 0;  
  86.                 clientLeft = 0;  
  87.             }  
  88.   
  89.             var top = box.top / zoom + (window.pageYOffset || docElem && docElem.scrollTop / zoom || body.scrollTop / zoom) - clientTop,  
  90.                 left = box.left / zoom + (window.pageXOffset || docElem && docElem.scrollLeft / zoom || body.scrollLeft / zoom) - clientLeft;  
  91.   
  92.             return {  
  93.                 top: top,  
  94.                 left: left  
  95.             };  
  96.         };  
  97.     } else {  
  98.         // Get offset adding all offsets   
  99.         var getOffset = function (el) {  
  100.             var top = 0,  
  101.                 left = 0;  
  102.             do {  
  103.                 top += el.offsetTop || 0;  
  104.                 left += el.offsetLeft || 0;  
  105.                 el = el.offsetParent;  
  106.             } while (el);  
  107.   
  108.             return {  
  109.                 left: left,  
  110.                 top: top  
  111.             };  
  112.         };  
  113.     }  
  114.   
  115.     /** 
  116.      * Returns left, top, right and bottom properties describing the border-box, 
  117.      * in pixels, with the top-left relative to the body 
  118.      * @param {Element} el 
  119.      * @return {Object} Contains left, top, right,bottom 
  120.      */  
  121.   
  122.     function getBox(el) {  
  123.         var left, right, top, bottom;  
  124.         var offset = getOffset(el);  
  125.         left = offset.left;  
  126.         top = offset.top;  
  127.   
  128.         right = left + el.offsetWidth;  
  129.         bottom = top + el.offsetHeight;  
  130.   
  131.         return {  
  132.             left: left,  
  133.             right: right,  
  134.             top: top,  
  135.             bottom: bottom  
  136.         };  
  137.     }  
  138.   
  139.     /** 
  140.      * Helper that takes object literal 
  141.      * and add all properties to element.style 
  142.      * @param {Element} el 
  143.      * @param {Object} styles 
  144.      */  
  145.   
  146.     function addStyles(el, styles) {  
  147.         for (var name in styles) {  
  148.             if (styles.hasOwnProperty(name)) {  
  149.                 el.style[name] = styles[name];  
  150.             }  
  151.         }  
  152.     }  
  153.   
  154.     /** 
  155.      * Function places an absolutely positioned 
  156.      * element on top of the specified element 
  157.      * copying position and dimentions. 
  158.      * @param {Element} from 
  159.      * @param {Element} to 
  160.      */  
  161.   
  162.     function copyLayout(from, to) {  
  163.         var box = getBox(from);  
  164.   
  165.         addStyles(to, {  
  166.             position: 'absolute',  
  167.             left: box.left + 'px',  
  168.             top: box.top + 'px',  
  169.             width: from.offsetWidth + 'px',  
  170.             height: from.offsetHeight + 'px'  
  171.         });  
  172.     }  
  173.   
  174.     /** 
  175.      * Creates and returns element from html chunk 
  176.      * Uses innerHTML to create an element 
  177.      */  
  178.     var toElement = (function () {  
  179.         var div = document.createElement('div');  
  180.         return function (html) {  
  181.             div.innerHTML = html;  
  182.             var el = div.firstChild;  
  183.             return div.removeChild(el);  
  184.         };  
  185.     })();  
  186.   
  187.     /** 
  188.      * Function generates unique id 
  189.      * @return unique id  
  190.      */  
  191.     var getUID = (function () {  
  192.         var id = 0;  
  193.         return function () {  
  194.             return 'ValumsAjaxUpload' + id++;  
  195.         };  
  196.     })();  
  197.   
  198.     /** 
  199.      * Get file name from path 
  200.      * @param {String} file path to file 
  201.      * @return filename 
  202.      */  
  203.   
  204.     function fileFromPath(file) {  
  205.         return file.replace(/.*(\/|\\)/, "");  
  206.     }  
  207.   
  208.     /** 
  209.      * Get file extension lowercase 
  210.      * @param {String} file name 
  211.      * @return file extenstion 
  212.      */  
  213.   
  214.     function getExt(file) {  
  215.         return (-1 !== file.indexOf('.')) ? file.replace(/.*[.]/, '') : '';  
  216.     }  
  217.   
  218.     function hasClass(el, name) {  
  219.         var re = new RegExp('\\b' + name + '\\b');  
  220.         return re.test(el.className);  
  221.     }  
  222.   
  223.     function addClass(el, name) {  
  224.         if (!hasClass(el, name)) {  
  225.             el.className += ' ' + name;  
  226.         }  
  227.     }  
  228.   
  229.     function removeClass(el, name) {  
  230.         var re = new RegExp('\\b' + name + '\\b');  
  231.         el.className = el.className.replace(re, '');  
  232.     }  
  233.   
  234.     function removeNode(el) {  
  235.         el.parentNode.removeChild(el);  
  236.     }  
  237.   
  238.     /** 
  239.      * Easy styling and uploading 
  240.      * @constructor 
  241.      * @param button An element you want convert to  
  242.      * upload button. Tested dimentions up to 500x500px 
  243.      * @param {Object} options See defaults below. 
  244.      */  
  245.     window.AjaxUpload = function (button, options) {  
  246.         this._settings = {  
  247.             // Location of the server-side upload script  
  248.             action: 'upload.php',  
  249.             // File upload name  
  250.             name: 'userfile',  
  251.             // Additional data to send  
  252.             data: {},  
  253.             // Submit file as soon as it's selected  
  254.             autoSubmit: true,  
  255.             // The type of data that you're expecting back from the server.  
  256.             // html and xml are detected automatically.  
  257.             // Only useful when you are using json data as a response.  
  258.             // Set to "json" in that case.   
  259.             responseType: false,  
  260.             // Class applied to button when mouse is hovered  
  261.             hoverClass: 'hover',  
  262.             // Class applied to button when AU is disabled  
  263.             disabledClass: 'disabled',  
  264.             // When user selects a file, useful with autoSubmit disabled  
  265.             // You can return false to cancel upload              
  266.             onChange: function (file, extension) {},  
  267.             // Callback to fire before file is uploaded  
  268.             // You can return false to cancel upload  
  269.             onSubmit: function (file, extension) {},  
  270.             // Fired when file upload is completed  
  271.             // WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!  
  272.             onComplete: function (file, response) {}  
  273.         };  
  274.   
  275.         // Merge the users options with our defaults  
  276.         for (var i in options) {  
  277.             if (options.hasOwnProperty(i)) {  
  278.                 this._settings[i] = options[i];  
  279.             }  
  280.         }  
  281.   
  282.         // button isn't necessary a dom element  
  283.         if (button.jquery) {  
  284.             // jQuery object was passed  
  285.             button = button[0];  
  286.         } else if (typeof button == "string") {  
  287.             if (/^#.*/.test(button)) {  
  288.                 // If jQuery user passes #elementId don't break it                    
  289.                 button = button.slice(1);  
  290.             }  
  291.   
  292.             button = document.getElementById(button);  
  293.         }  
  294.   
  295.         if (!button || button.nodeType !== 1) {  
  296.             throw new Error("Please make sure that you're passing a valid element");  
  297.         }  
  298.   
  299.         if (button.nodeName.toUpperCase() == 'A') {  
  300.             // disable link                         
  301.             addEvent(button, 'click', function (e) {  
  302.                 if (e && e.preventDefault) {  
  303.                     e.preventDefault();  
  304.                 } else if (window.event) {  
  305.                     window.event.returnValue = false;  
  306.                 }  
  307.             });  
  308.         }  
  309.   
  310.         // DOM element  
  311.         this._button = button;  
  312.         // DOM element                   
  313.         this._input = null;  
  314.         // If disabled clicking on button won't do anything  
  315.         this._disabled = false;  
  316.   
  317.         // if the button was disabled before refresh if will remain  
  318.         // disabled in FireFox, let's fix it  
  319.         this.enable();  
  320.   
  321.         this._rerouteClicks();  
  322.     };  
  323.   
  324.     // assigning methods to our class  
  325.     AjaxUpload.prototype = {  
  326.         setData: function (data) {  
  327.             this._settings.data = data;  
  328.         },  
  329.         disable: function () {  
  330.             addClass(this._button, this._settings.disabledClass);  
  331.             this._disabled = true;  
  332.   
  333.             var nodeName = this._button.nodeName.toUpperCase();  
  334.             if (nodeName == 'INPUT' || nodeName == 'BUTTON') {  
  335.                 this._button.setAttribute('disabled''disabled');  
  336.             }  
  337.   
  338.             // hide input  
  339.             if (this._input) {  
  340.                 // We use visibility instead of display to fix problem with Safari 4  
  341.                 // The problem is that the value of input doesn't change if it   
  342.                 // has display none when user selects a file             
  343.                 this._input.parentNode.style.visibility = 'hidden';  
  344.             }  
  345.         },  
  346.         enable: function () {  
  347.             removeClass(this._button, this._settings.disabledClass);  
  348.             this._button.removeAttribute('disabled');  
  349.             this._disabled = false;  
  350.   
  351.         },  
  352.         /** 
  353.          * Creates invisible file input  
  354.          * that will hover above the button 
  355.          * <div><input type='file' /></div> 
  356.          */  
  357.         _createInput: function () {  
  358.             var self = this;  
  359.   
  360.             var input = document.createElement("input");  
  361.             input.setAttribute('type''file');  
  362.             input.setAttribute('name'this._settings.name);  
  363.   
  364.             addStyles(input, {  
  365.                 'position''absolute',  
  366.                 // in Opera only 'browse' button  
  367.                 // is clickable and it is located at  
  368.                 // the right side of the input  
  369.                 'right'0,  
  370.                 'margin'0,  
  371.                 'padding'0,  
  372.                 'fontSize''480px',  
  373.                 'cursor''pointer'  
  374.             });  
  375.   
  376.             var div = document.createElement("div");  
  377.             addStyles(div, {  
  378.                 'display''block',  
  379.                 'position''absolute',  
  380.                 'overflow''hidden',  
  381.                 'margin'0,  
  382.                 'padding'0,  
  383.                 'opacity'0,  
  384.                 // Make sure browse button is in the right side  
  385.                 // in Internet Explorer  
  386.                 'direction''ltr',  
  387.                 //Max zIndex supported by Opera 9.0-9.2  
  388.                 'zIndex'2147483583  
  389.             });  
  390.   
  391.             // Make sure that element opacity exists.  
  392.             // Otherwise use IE filter              
  393.             if (div.style.opacity !== "0") {  
  394.                 if (typeof(div.filters) == 'undefined') {  
  395.                     throw new Error('Opacity not supported by the browser');  
  396.                 }  
  397.                 div.style.filter = "alpha(opacity=0)";  
  398.             }  
  399.   
  400.             addEvent(input, 'change', function () {  
  401.   
  402.                 if (!input || input.value === '') {  
  403.                     return;  
  404.                 }  
  405.   
  406.                 // Get filename from input, required                  
  407.                 // as some browsers have path instead of it            
  408.                 var file = fileFromPath(input.value);  
  409.   
  410.                 if (false === self._settings.onChange.call(self, file, getExt(file))) {  
  411.                     self._clearInput();  
  412.                     return;  
  413.                 }  
  414.   
  415.                 // Submit form when value is changed  
  416.                 if (self._settings.autoSubmit) {  
  417.                     self.submit();  
  418.                 }  
  419.             });  
  420.   
  421.             addEvent(input, 'mouseover', function () {  
  422.                 addClass(self._button, self._settings.hoverClass);  
  423.             });  
  424.   
  425.             addEvent(input, 'mouseout', function () {  
  426.                 removeClass(self._button, self._settings.hoverClass);  
  427.   
  428.                 // We use visibility instead of display to fix problem with Safari 4  
  429.                 // The problem is that the value of input doesn't change if it   
  430.                 // has display none when user selects a file             
  431.                 input.parentNode.style.visibility = 'hidden';  
  432.   
  433.             });  
  434.   
  435.             div.appendChild(input);  
  436.             document.body.appendChild(div);  
  437.   
  438.             this._input = input;  
  439.         },  
  440.         _clearInput: function () {  
  441.             if (!this._input) {  
  442.                 return;  
  443.             }  
  444.   
  445.             // this._input.value = ''; Doesn't work in IE6                                 
  446.             removeNode(this._input.parentNode);  
  447.             this._input = null;  
  448.             this._createInput();  
  449.   
  450.             removeClass(this._button, this._settings.hoverClass);  
  451.         },  
  452.         /** 
  453.          * Function makes sure that when user clicks upload button, 
  454.          * the this._input is clicked instead 
  455.          */  
  456.         _rerouteClicks: function () {  
  457.             var self = this;  
  458.   
  459.             // IE will later display 'access denied' error  
  460.             // if you use using self._input.click()  
  461.             // other browsers just ignore click()  
  462.   
  463.             addEvent(self._button, 'mouseover', function () {  
  464.                 if (self._disabled) {  
  465.                     return;  
  466.                 }  
  467.   
  468.                 if (!self._input) {  
  469.                     self._createInput();  
  470.                 }  
  471.   
  472.                 var div = self._input.parentNode;  
  473.                 copyLayout(self._button, div);  
  474.                 div.style.visibility = 'visible';  
  475.   
  476.             });  
  477.   
  478.   
  479.             // commented because we now hide input on mouseleave  
  480.             /** 
  481.              * When the window is resized the elements  
  482.              * can be misaligned if button position depends 
  483.              * on window size 
  484.              */  
  485.             //addResizeEvent(function(){  
  486.             //    if (self._input){  
  487.             //        copyLayout(self._button, self._input.parentNode);  
  488.             //    }  
  489.             //});              
  490.   
  491.         },  
  492.         /** 
  493.          * Creates iframe with unique name 
  494.          * @return {Element} iframe 
  495.          */  
  496.         _createIframe: function () {  
  497.             // We can't use getTime, because it sometimes return  
  498.             // same value in safari :(  
  499.             var id = getUID();  
  500.   
  501.             // We can't use following code as the name attribute  
  502.             // won't be properly registered in IE6, and new window  
  503.             // on form submit will open  
  504.             // var iframe = document.createElement('iframe');  
  505.             // iframe.setAttribute('name', id);                          
  506.   
  507.             var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');  
  508.             // src="javascript:false; was added  
  509.             // because it possibly removes ie6 prompt   
  510.             // "This page contains both secure and nonsecure items"  
  511.             // Anyway, it doesn't do any harm.              
  512.             iframe.setAttribute('id', id);  
  513.   
  514.             iframe.style.display = 'none';  
  515.             document.body.appendChild(iframe);  
  516.   
  517.             return iframe;  
  518.         },  
  519.         /** 
  520.          * Creates form, that will be submitted to iframe 
  521.          * @param {Element} iframe Where to submit 
  522.          * @return {Element} form 
  523.          */  
  524.         _createForm: function (iframe) {  
  525.             var settings = this._settings;  
  526.   
  527.             // We can't use the following code in IE6  
  528.             // var form = document.createElement('form');  
  529.             // form.setAttribute('method', 'post');  
  530.             // form.setAttribute('enctype', 'multipart/form-data');  
  531.             // Because in this case file won't be attached to request                      
  532.             var form = toElement('<form method="post" enctype="multipart/form-data"></form>');  
  533.   
  534.             form.setAttribute('action', settings.action);  
  535.             form.setAttribute('target', iframe.name);  
  536.             form.style.display = 'none';  
  537.             document.body.appendChild(form);  
  538.   
  539.             // Create hidden input element for each data key  
  540.             for (var prop in settings.data) {  
  541.                 if (settings.data.hasOwnProperty(prop)) {  
  542.                     var el = document.createElement("input");  
  543.                     el.setAttribute('type''hidden');  
  544.                     el.setAttribute('name', prop);  
  545.                     el.setAttribute('value', settings.data[prop]);  
  546.                     form.appendChild(el);  
  547.                 }  
  548.             }  
  549.             return form;  
  550.         },  
  551.         /** 
  552.          * Gets response from iframe and fires onComplete event when ready 
  553.          * @param iframe 
  554.          * @param file Filename to use in onComplete callback  
  555.          */  
  556.         _getResponse: function (iframe, file) {  
  557.             // getting response  
  558.             var toDeleteFlag = false,  
  559.                 self = this,  
  560.                 settings = this._settings;  
  561.   
  562.             addEvent(iframe, 'load', function () {  
  563.   
  564.                 if ( // For Safari   
  565.                 iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||  
  566.                 // For FF, IE  
  567.                 iframe.src == "javascript:'<html></html>';") {  
  568.                     // First time around, do not delete.  
  569.                     // We reload to blank page, so that reloading main page  
  570.                     // does not re-submit the post.  
  571.   
  572.                     if (toDeleteFlag) {  
  573.                         // Fix busy state in FF3  
  574.                         setTimeout(function () {  
  575.                             removeNode(iframe);  
  576.                         },  
  577.                         0);  
  578.                     }  
  579.   
  580.                     return;  
  581.                 }  
  582.   
  583.                 var doc = iframe.contentDocument ? iframe.contentDocument : window.frames[iframe.id].document;  
  584.   
  585.                 // fixing Opera 9.26,10.00  
  586.                 if (doc.readyState && doc.readyState != 'complete') {  
  587.                     // Opera fires load event multiple times  
  588.                     // Even when the DOM is not ready yet  
  589.                     // this fix should not affect other browsers  
  590.                     return;  
  591.                 }  
  592.   
  593.                 // fixing Opera 9.64  
  594.                 if (doc.body && doc.body.innerHTML == "false") {  
  595.                     // In Opera 9.64 event was fired second time  
  596.                     // when body.innerHTML changed from false   
  597.                     // to server response approx. after 1 sec  
  598.                     return;  
  599.                 }  
  600.   
  601.                 var response;  
  602.   
  603.                 if (doc.XMLDocument) {  
  604.                     // response is a xml document Internet Explorer property  
  605.                     response = doc.XMLDocument;  
  606.                 } else if (doc.body) {  
  607.                     // response is html document or plain text  
  608.                     response = doc.body.innerHTML;  
  609.   
  610.                     if (settings.responseType && settings.responseType.toLowerCase() == 'json') {  
  611.                         // If the document was sent as 'application/javascript' or  
  612.                         // 'text/javascript', then the browser wraps the text in a <pre>  
  613.                         // tag and performs html encoding on the contents.  In this case,  
  614.                         // we need to pull the original text content from the text node's  
  615.                         // nodeValue property to retrieve the unmangled content.  
  616.                         // Note that IE6 only understands text/html  
  617.                         if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE') {  
  618.                             response = doc.body.firstChild.firstChild.nodeValue;  
  619.                         }  
  620.   
  621.                         if (response) {  
  622.                             response = eval("(" + response + ")");  
  623.                         } else {  
  624.                             response = {};  
  625.                         }  
  626.                     }  
  627.                 } else {  
  628.                     // response is a xml document  
  629.                     response = doc;  
  630.                 }  
  631.   
  632.                 settings.onComplete.call(self, file, response);  
  633.   
  634.                 // Reload blank page, so that reloading main page  
  635.                 // does not re-submit the post. Also, remember to  
  636.                 // delete the frame  
  637.                 toDeleteFlag = true;  
  638.   
  639.                 // Fix IE mixed content issue  
  640.                 iframe.src = "javascript:'<html></html>';";  
  641.             });  
  642.         },  
  643.         /** 
  644.          * Upload file contained in this._input 
  645.          */  
  646.         submit: function () {  
  647.             var self = this,  
  648.                 settings = this._settings;  
  649.   
  650.             if (!this._input || this._input.value === '') {  
  651.                 return;  
  652.             }  
  653.   
  654.             var file = fileFromPath(this._input.value);  
  655.   
  656.             // user returned false to cancel upload  
  657.             if (false === settings.onSubmit.call(this, file, getExt(file))) {  
  658.                 this._clearInput();  
  659.                 return;  
  660.             }  
  661.   
  662.             // sending request      
  663.             var iframe = this._createIframe();  
  664.             var form = this._createForm(iframe);  
  665.   
  666.             // assuming following structure  
  667.             // div -> input type='file'  
  668.             removeNode(this._input.parentNode);  
  669.             removeClass(self._button, self._settings.hoverClass);  
  670.   
  671.             form.appendChild(this._input);  
  672.   
  673.             form.submit();  
  674.   
  675.             // request set, clean up                  
  676.             removeNode(form);  
  677.             form = null;  
  678.             removeNode(this._input);  
  679.             this._input = null;  
  680.   
  681.             // Get response from iframe and fire onComplete event when ready  
  682.             this._getResponse(iframe, file);  
  683.   
  684.             // get ready for next request              
  685.             this._createInput();  
  686.         }  
  687.     };  
  688. })();