This is a mimic of Ajax style upload, but in reality it is a good old form submit through an iframe.
I have created a Demo for the same and you can download it from the link given below
Demo for Ajax File Upload
I create a new instance of the File Uploader Utility as
var configInstance = {
keepAlive: false,
responseType: "json",
}
var uploader = new fileUploader(configInstance);
The config has values keepAlive which when set true will enable you to download content from the API where you submit the form with the new file content. This can be achieved by appropriate response type of the API.
Also note in any scenario the script will return the content of the response. The responseType is by default set to text or innerHtml you can set it to json or xml depending on the API.
You have following properties available to configure an instance
1. keepAlive : Useful when you want to start a download
2. responseType : default value is 'false' , returns innerHtml. Can be set to json or xml also.
3. formatTag : Allows you to specify the tag from which you want read the content in the response.Sometimes the json might be set inside a <pre> tag in the response html.
To start an upload you need to pass a second config object and the form id .In this example the form id is 'demoFile'.
var config = {
onComplete: function(data, returnMeData){
//do something here
},
onFailure: function(){
//do something here
},
returnMe: {
"message": "I am returnMeData"
}
}
uploader.startUpload('demoFile', config);
The onComplete and onFailure callback methods are self explainatory.
The returnMe configuration can be used to pass an object to the utility. The utility will return the same as a parameter to the callback for onComplete as shown above.
All comments and feedback are welcome. Pasting the utility code below also. Cheers!!! :)
The code for the utility is as follows
/* Utility Code Start*/
function fileUploader(config){
/*
* Default value is false.
* Set value as "json" to get json response.
* Set value as "xml" to get XML response
* By default returns response as HTML of the screen
*/
this.responseType = (config.responseType) ? config.responseType : false;
/*
* if the response is enclosed in a specific tag
*/
this.formatTag = (config.formatTag) ? config.formatTag : "";
/*
* by default the value is set to true to keep the iframe alive after the operation is finished
* comes in handy if you have to start a file download from the respone of the upload
*/
this.keepAlive = (config.keepAlive) ? true : false;
/*
* @description Method to create the dynamic iframe
* @scope Private to each instance
*
*/
function createFrame(c){
//generate a random value
var n = 'f' + Math.floor(Math.random() * 99999);
//javascript:false; prevents the IE alert in secure connections
var iframe = toElement('<iframe src="javascript:false;" id="' + n + '" name="' + n + '"></iframe>');
document.body.appendChild(iframe);
iframe.style.display = 'none';
if (c && typeof(c.onComplete) == 'function') {
iframe.onComplete = c.onComplete;
}
if (c && typeof(c.onFailure) == 'function') {
iframe.onFailure = c.onFailure;
}
if (c.returnMe != undefined) {
iframe.returnBack = c.returnMe;
}
iframe.delNode = n;
iframe.fired = false;
iframe.toDeleteFlag = false;
return iframe;
};
/*
* Helper Methods Start
* @scope All are private to each instance created
*/
function setTarget(f, name){
f.setAttribute('target', name);
};
function toElement(html){
var div = document.createElement('div');
div.innerHTML = html;
var el = div.childNodes[0];
div.removeChild(el);
return el;
};
function addEvent(el, type, fn){
if (window.addEventListener) {
el.addEventListener(type, fn, false);
}
else
if (window.attachEvent) {
var f = function(){
fn.call(el, window.event);
};
el.attachEvent('on' + type, f)
}
};
/*Helper Methods Ends*/
var other = this;
/*
* @scope Public
* @description
* @parameters f : id of form to be submitted for file Upload
* c : the configuration passed with the onComplete, onFailure and returnMe data
* Sample of this c property
* c = {
* onComplete : function(){},
* onFailure : function(){}, you will recieve the error object in the parameter here
* returnMe : {prop1:"data1",prop2:"data2"}
* }
*/
this.startUpload = function(fID, c){
try {
var f = document.getElementById(fID);
if (!f) {
var e = new Error();
e.description = "Form element not found";
throw e;
}
var iframe = createFrame(c);
var that = other;
addEvent(iframe, "load", function(e){
//function for capturing the load
var loaded = function(){
try {
var response;
if (doc.XMLDocument) {
response = doc.XMLDocument;
}
else
if (doc.body) {
//convert result text to JSON format
if (that.responseType == 'json') {
if (that.formatTag != "") {
response = eval("result=" + doc.body.getElementsByTagName(that.formatTag)[0].innerHTML);
}
else {
response = eval("result=" + doc.body.innerHTML);
}
}
else
if (!that.responseType) {
response = doc.body.innerHTML;
}
}
else {
// response is a xml document
response = doc;
}
if (typeof(iframe.onComplete) == 'function') {
if (iframe.returnBack != undefined || iframe.returnBack != null) {
iframe.onComplete(response, iframe.returnBack);
}
else
iframe.onComplete(response);
// Reload blank page, so that reloading main page
// does not re-submit the post.
// delete the frame
iframe.toDeleteFlag = true;
//load event fired reset the iframe
//but we will not reset the iframe url to consider
//the fact that a file can be downloaded if keepAlive is true
//Please note the file download happens only if the response type of the
//url to which the form is submitted is correct
if (!that.keepAlive) {
iframe.src = "about:blank";
}
}
}
catch (e) {
//suppress
}
};
if (iframe.src == "about:blank") {
//dont delete on first read
if (iframe.toDeleteFlag) {
// Fix busy state in FF3
setTimeout(function(){
//keepAlive is true if its a file download
if (!that.keepAlive) {
document.body.removeChild(iframe);
}
}, 0);
}
return;
}
//Fix Opera multiple event firing
if (iframe.fired) {
return;
}
var doc = null
if (iframe.contentDocument) {
doc = iframe.contentDocument;
}
else
if (iframe.contentWindow) {
doc = iframe.contentWindow.document;
}
else {
doc = window.frames[iframe.id].document;
}
//Opera fires onload twice.
// Once when the content of the html is 'false'
if (window.opera) {
if (doc.body && doc.body.innerHTML != "false") {
iframe.fired = true;
loaded();
}
}
else {
if (doc.body && doc.body.innerHTML != "false") {
iframe.fired = true;
loaded();
}
}
});
//set the target of iframe and submit
setTarget(f, iframe.id);
f.submit();
}
catch (e) {
//suppress all errors
//fire onFailure method with the error object as param
if (typeof(c.onFailure) == 'function') {
c.onFailure(e);
if (iframe) {
iframe.src = "about:blank";
}
}
}
};
};
No comments:
Post a Comment