410 lines
14 KiB
JavaScript
410 lines
14 KiB
JavaScript
/**
|
|
* Sử dụng ajax upload file cho các trình duyệt đời mới
|
|
*/
|
|
|
|
/**
|
|
* Hàm định nghĩa cho việc kế thừa
|
|
* @returns {Array|objectExtend.args}
|
|
*/
|
|
if (typeof objectLib == 'undefined') {
|
|
var objectExtend = function () {
|
|
var args = arguments;
|
|
if (args.length === 1)
|
|
args = [this, args[0]];
|
|
for (var prop in args[1])
|
|
args[0][prop] = args[1][prop];
|
|
return args[0];
|
|
};
|
|
|
|
function $OBJECT(elm) {
|
|
if (typeof (elm) == "string") {
|
|
elm = document.getElementById(elm);
|
|
}
|
|
return (elm && !elm.appendTo) ? objectExtend(elm, objectElement.prototype) : elm;
|
|
}
|
|
|
|
var objectLib = {
|
|
isMSIE: (navigator.appVersion.indexOf("MSIE") != -1),
|
|
addEvent: function (obj, type, fn) {
|
|
(obj.addEventListener) ? obj.addEventListener(type, fn, false) : obj.attachEvent("on" + type, fn);
|
|
},
|
|
toArray: function (iterable) {
|
|
var length = iterable.length, results = new Array(length);
|
|
while (length--) {
|
|
results[length] = iterable[length];
|
|
}
|
|
return results;
|
|
},
|
|
camelize: function (s) {
|
|
return s.replace(/\-(.)/g, function (m, l) {
|
|
return l.toUpperCase();
|
|
});
|
|
},
|
|
inArray: function (arr, item) {
|
|
return (objectLib.search(arr, item) != null);
|
|
},
|
|
search: function (arr, itm) {
|
|
for (var i = 0; i < arr.length; i++) {
|
|
if (arr[i] == itm)
|
|
return i;
|
|
}
|
|
return null;
|
|
},
|
|
cancelEvent: function (e) {
|
|
e = e || window.event;
|
|
if (e.preventDefault && e.stopPropagation) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
return false;
|
|
},
|
|
domLoad: [],
|
|
domLoaded: function () {
|
|
if (arguments.callee.done)
|
|
return;
|
|
arguments.callee.done = true;
|
|
for (i = 0; i < objectLib.domLoad.length; i++)
|
|
objectLib.domLoad[i]();
|
|
},
|
|
onDomLoaded: function (fireThis) {
|
|
this.domLoad.push(fireThis);
|
|
if (document.addEventListener) {
|
|
document.addEventListener("DOMContentLoaded", objectLib.domLoaded, null);
|
|
} else if (objectLib.isMSIE) {
|
|
document.write("<style>.nicEdit-main p { margin: 0; }</style><script id=__ie_onload defer " + ((location.protocol == "https:") ? "src='javascript:void(0)'" : "src=//0") + "></script>");
|
|
$OBJECT("__ie_onload").onreadystatechange = function () {
|
|
if (this.readyState == "complete") {
|
|
objectLib.domLoaded();
|
|
}
|
|
};
|
|
}
|
|
window.onload = objectLib.domLoaded;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Lớp objectClass là lớp gốc cho các lớp
|
|
* @returns {objectClass}
|
|
*/
|
|
var objectClass = function () {
|
|
};
|
|
/**
|
|
* Tự định nghĩa hàm khởi tạo.
|
|
* @returns {instance of object}
|
|
*/
|
|
objectClass.prototype.construct = function () {
|
|
};
|
|
/**
|
|
* Định nghĩa kế thừa
|
|
* b = a.extend({}); lớp b kế thừa lớp a
|
|
* @param {type} def
|
|
* @returns {objectClass.extend.classDef}
|
|
*/
|
|
objectClass.extend = function (def) {
|
|
var classDef = function () {
|
|
if (arguments[0] !== objectClass) {
|
|
return this.construct.apply(this, arguments);
|
|
}
|
|
};
|
|
var proto = new this(objectClass);
|
|
objectExtend(proto, def);
|
|
classDef.prototype = proto;
|
|
classDef.extend = this.extend;
|
|
return classDef;
|
|
};
|
|
|
|
|
|
var objectElement = objectClass.extend({
|
|
classprefix: '',
|
|
construct: function (elm, d) {
|
|
if (typeof (elm) == "string") {
|
|
elm = (d || document).createElement(elm);
|
|
}
|
|
elm = $OBJECT(elm);
|
|
return elm;
|
|
},
|
|
appendTo: function (elm) {
|
|
elm.appendChild(this);
|
|
return this;
|
|
},
|
|
appendBefore: function (elm) {
|
|
elm.parentNode.insertBefore(this, elm);
|
|
return this;
|
|
},
|
|
addEvent: function (type, fn) {
|
|
objectLib.addEvent(this, type, fn);
|
|
return this;
|
|
},
|
|
setContent: function (c) {
|
|
this.innerHTML = c;
|
|
return this;
|
|
},
|
|
pos: function () {
|
|
var curleft = curtop = 0;
|
|
var o = obj = this;
|
|
if (obj.offsetParent) {
|
|
do {
|
|
curleft += obj.offsetLeft;
|
|
curtop += obj.offsetTop;
|
|
} while (obj = obj.offsetParent);
|
|
}
|
|
var b = (!window.opera) ? parseInt(this.getStyle('border-width') || this.style.border) || 0 : 0;
|
|
return {X: curleft + b, Y: curtop + b + this.offsetHeight};
|
|
},
|
|
noSelect: function () {
|
|
objectLib.noSelect(this);
|
|
return this;
|
|
},
|
|
parentTag: function (t) {
|
|
var elm = this;
|
|
do {
|
|
if (elm && elm.nodeName && elm.nodeName.toUpperCase() == t) {
|
|
return elm;
|
|
}
|
|
elm = elm.parentNode;
|
|
} while (elm);
|
|
return false;
|
|
},
|
|
hasClass: function (cls) {
|
|
return this.className.match(new RegExp('(\\s|^)' + this.classprefix + cls + '(\\s|$)'));
|
|
},
|
|
addClass: function (cls) {
|
|
if (!this.hasClass(cls)) {
|
|
this.className += " " + this.classprefix + cls;
|
|
}
|
|
return this;
|
|
},
|
|
removeClass: function (cls) {
|
|
if (this.hasClass(cls)) {
|
|
this.className = this.className.replace(new RegExp('(\\s|^)' + this.classprefix + cls + '(\\s|$)'), ' ');
|
|
}
|
|
return this;
|
|
},
|
|
setStyle: function (st) {
|
|
var elmStyle = this.style;
|
|
for (var itm in st) {
|
|
switch (itm) {
|
|
case 'float':
|
|
elmStyle['cssFloat'] = elmStyle['styleFloat'] = st[itm];
|
|
break;
|
|
case 'opacity':
|
|
elmStyle.opacity = st[itm];
|
|
elmStyle.filter = "alpha(opacity=" + Math.round(st[itm] * 100) + ")";
|
|
break;
|
|
case 'className':
|
|
this.className = st[itm];
|
|
break;
|
|
default:
|
|
elmStyle[itm] = st[itm];
|
|
}
|
|
}
|
|
return this;
|
|
},
|
|
getStyle: function (cssRule, d) {
|
|
var doc = (!d) ? document.defaultView : d;
|
|
if (this.nodeType == 1)
|
|
return (doc && doc.getComputedStyle) ? doc.getComputedStyle(this, null).getPropertyValue(cssRule) : this.currentStyle[ objectLib.camelize(cssRule) ];
|
|
},
|
|
remove: function () {
|
|
this.parentNode.removeChild(this);
|
|
return this;
|
|
},
|
|
setAttributes: function (at) {
|
|
for (var itm in at) {
|
|
this[itm] = at[itm];
|
|
}
|
|
return this;
|
|
}
|
|
});
|
|
|
|
var objectEvent = {
|
|
addEvent: function (evType, evFunc) {
|
|
if (evFunc) {
|
|
this.eventList = this.eventList || {};
|
|
this.eventList[evType] = this.eventList[evType] || [];
|
|
this.eventList[evType].push(evFunc);
|
|
}
|
|
return this;
|
|
},
|
|
fireEvent: function () {
|
|
var args = objectLib.toArray(arguments), evType = args.shift();
|
|
if (this.eventList && this.eventList[evType]) {
|
|
for (var i = 0; i < this.eventList[evType].length; i++) {
|
|
this.eventList[evType][i].apply(this, args);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
function __(s) {
|
|
return s;
|
|
}
|
|
|
|
Function.prototype.closure = function () {
|
|
var __method = this, args = objectLib.toArray(arguments), obj = args.shift();
|
|
return function () {
|
|
if (typeof (objectLib) != 'undefined') {
|
|
return __method.apply(obj, args.concat(objectLib.toArray(arguments)));
|
|
}
|
|
};
|
|
};
|
|
|
|
Function.prototype.closureListener = function () {
|
|
var __method = this, args = objectLib.toArray(arguments), obj = args.shift();
|
|
return function (e) {
|
|
e = e || window.event;
|
|
if (e.target) {
|
|
var target = e.target;
|
|
} else {
|
|
var target = e.srcElement;
|
|
}
|
|
return __method.apply(obj, [e, target].concat(args));
|
|
};
|
|
};
|
|
|
|
|
|
var afuButtons = {
|
|
buttons: [],
|
|
findButton: function (id) {
|
|
var buttons = afuButtons.buttons;
|
|
for (var i = 0; i < buttons.length; i++) {
|
|
if (buttons[i].instanceById(id)) {
|
|
return buttons[i].instanceById(id);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
var afuButton = objectClass.extend({
|
|
formData: {},
|
|
uploadURI: window.location.origin,
|
|
fileExtension: '*',
|
|
fileSizeLimit: 0,
|
|
uploadLimit: 0,
|
|
multi: false,
|
|
classes: 'afu-button afu-button-default',
|
|
fakeInputContent: 'Chọn tệp tin',
|
|
fakeInput: undefined,
|
|
fileInput: undefined,
|
|
wrap: {
|
|
tagName: 'div',
|
|
classes: 'afu-upload-wrapper'
|
|
},
|
|
progesss: undefined,
|
|
uploading: false,
|
|
construct: function () {
|
|
var args = arguments[0];
|
|
for (var prop in args)
|
|
this[prop] = args[prop];
|
|
afuButtons.buttons.push(this);
|
|
},
|
|
addInstance: function (id) {
|
|
if (typeof window.FormData == "undefined") {
|
|
return this.onError("Không hỗ trợ trình duyệt, nên sử dụng Chrome, Firefox, Safari hoặc Internet Explorer v10+ .");
|
|
}
|
|
this.fileInput = $OBJECT(id);
|
|
if (this.fileInput == null) {
|
|
return;
|
|
}
|
|
this.fileInput.setStyle({display: 'none'});
|
|
this.fileInput.multiple = this.multi;
|
|
this.fileInput.accept = this.fileExtension;
|
|
this.inputName = this.inputName || this.fileInput.getAttribute('name') || 'FileData';
|
|
var wrapper = new objectElement(this.wrap.tagName)
|
|
.setStyle({})
|
|
.addClass(this.wrap.classes)
|
|
.appendTo(this.fileInput.parentElement);
|
|
this.fakeInput = new objectElement('a')
|
|
.setStyle({})
|
|
.addClass(this.classes)
|
|
.setContent(this.fakeInputContent)
|
|
.appendTo(wrapper);
|
|
this.progress = new objectElement('progress')
|
|
.setStyle({width: '100%', display: 'none'})
|
|
.setAttributes({'max': '100'})
|
|
.addClass('afu-progress')
|
|
.appendTo(wrapper);
|
|
this.fakeInput.onclick = function () {
|
|
this.fileInput.click();
|
|
}.closure(this);
|
|
this.fileInput.onchange = this.uploadFile.closure(this);
|
|
},
|
|
onError: function (msg) {
|
|
common.uploadBlock(false);
|
|
alert(msg || "Không upload được tệp tin");
|
|
if (window.loading) {
|
|
window.loading.instance.close();
|
|
}
|
|
return false;
|
|
},
|
|
beforeUpload: function () {
|
|
common.uploadBlock(true);
|
|
},
|
|
uploadFile: function () {
|
|
this.beforeUpload();
|
|
if (window.loading) {
|
|
window.loading.show();
|
|
}
|
|
var file = this.fileInput.files[0];
|
|
console.log(file);
|
|
if (this.fileSizeLimit > 0 && file.size > (this.fileSizeLimit * 1024 * 1024)) {
|
|
this.onError('Dung lượng tệp tin(' + (Math.ceil(file.size / 1024 / 1024)) + ' MB) vượt quá dung lượng cho phép(' + this.fileSizeLimit + ' MB)');
|
|
if (window.loading) {
|
|
window.loading.instances.close();
|
|
}
|
|
return;
|
|
}
|
|
this.setProgress(0);
|
|
var _formData = new FormData();
|
|
_formData.append(this.inputName, file);
|
|
for (var key in this.formData) {
|
|
_formData.append(key, this.formData[key]);
|
|
}
|
|
var xhr = null;
|
|
if (window.XMLHttpRequest) {
|
|
xhr = new XMLHttpRequest();
|
|
} else {
|
|
xhr = new ActiveXObject("Microsoft.XMLHTTP");
|
|
}
|
|
xhr.open("POST", this.uploadURI);
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState == 4) {
|
|
this.progress.setStyle({display: 'none'});
|
|
this.uploading = false;
|
|
if (xhr.status == 200) {
|
|
this.onUploaded(xhr.responseText);
|
|
} else if (xhr.status == 403) {
|
|
this.onError('403 Forbidden');
|
|
} else {
|
|
this.onError('error code return ' + xhr.status);
|
|
}
|
|
}
|
|
|
|
}.closure(this);
|
|
xhr.onerror = this.onError.closure(this);
|
|
xhr.upload.onprogress = function (e) {
|
|
this.setProgress(e.loaded / e.total);
|
|
}.closure(this);
|
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
xhr.send(_formData);
|
|
this.uploading = true;
|
|
},
|
|
setProgress: function (percent) {
|
|
var pc = percent * 100;
|
|
$("#upload-percent").html(pc.toFixed(2) + " %");
|
|
this.progress.setStyle({display: 'block'});
|
|
if (percent < .98) {
|
|
this.progress.value = percent;
|
|
} else {
|
|
this.progress.removeAttribute('value');
|
|
}
|
|
},
|
|
onUploaded: function (data) {
|
|
console.log(data);
|
|
if (window.loading) {
|
|
window.loading.instance.close();
|
|
}
|
|
}
|
|
});
|
|
}
|