/**
|
* @fileoverview 文件上传按钮base
|
* @author: 紫英(橘子)<daxingplay@gmail.com>, 剑平(明河)<minghe36@126.com>
|
**/
|
KISSY.add('gallery/form/1.3/uploader/button/base',function(S, Node, Base) {
|
var EMPTY = '',
|
LOG_PREFIX = '[Uploader-Button] ',
|
$ = Node.all;
|
/**
|
* @name Button
|
* @class 文件上传按钮,ajax和iframe上传方式使用
|
* @constructor
|
* @extends Base
|
* @param {String} target *,目标元素
|
* @param {Object} config 配置对象
|
* @param {String} config.name *,隐藏的表单上传域的name值
|
* @param {Boolean} config.disabled 是否禁用按钮
|
* @param {Boolean} config.multiple 是否开启多选支持
|
*/
|
function Button(target, config) {
|
var self = this;
|
config = S.merge({target:$(target)}, config);
|
//超类初始化
|
Button.superclass.constructor.call(self, config);
|
}
|
|
S.mix(Button, {
|
//支持的事件
|
event : {
|
'beforeShow': 'beforeShow',
|
'afterShow': 'afterShow',
|
'beforeHide': 'beforeHide',
|
'afterHide': 'afterHide',
|
'beforeRender' : 'beforeRender',
|
'afterRender' : 'afterRender',
|
'CHANGE' : 'change'
|
},
|
/**
|
* 获取文件名称(从表单域的值中提取)
|
* @param {String} path 文件路径
|
* @return {String}
|
*/
|
getFileName : function(path) {
|
return path.replace(/.*(\/|\\)/, "");
|
}
|
});
|
|
S.extend(Button, Base, /** @lends Button.prototype*/{
|
/**
|
* 运行
|
* @return {Button} Button的实例
|
*/
|
render : function() {
|
var self = this,
|
target = self.get('target'),
|
render = self.fire(Button.event.beforeRender);
|
if (render === false) {
|
S.log(LOG_PREFIX + 'button render was prevented.');
|
return false;
|
} else {
|
if (target == null) {
|
S.log(LOG_PREFIX + 'Cannot find target!');
|
return false;
|
}
|
self._createInput();
|
self.fire(Button.event.afterRender);
|
return self;
|
}
|
},
|
/**
|
* 显示按钮
|
* @return {Button} Button的实例
|
*/
|
show : function() {
|
var self = this, target = self.get('target');
|
target.show();
|
self.fire(Button.event.afterShow);
|
return Button;
|
},
|
/**
|
* 隐藏按钮
|
* @return {Button} Button的实例
|
*/
|
hide : function() {
|
var self = this, target = self.get('target');
|
target.hide();
|
self.fire(Button.event.afterHide);
|
return Button;
|
},
|
/**
|
* 重置按钮
|
* @return {Button} Button的实例
|
*/
|
reset : function() {
|
var self = this,
|
inputContainer = self.get('inputContainer');
|
//移除表单上传域容器
|
$(inputContainer).remove();
|
self.set('inputContainer', EMPTY);
|
self.set('fileInput', EMPTY);
|
//重新创建表单上传域
|
self._createInput();
|
return self;
|
},
|
/**
|
* 创建隐藏的表单上传域
|
* @return {HTMLElement} 文件上传域容器
|
*/
|
_createInput : function() {
|
var self = this,
|
target = self.get('target'),
|
name = self.get('name'),
|
tpl = self.get('tpl'),
|
html,
|
inputContainer,
|
fileInput;
|
if (!S.isString(name) || !S.isString(tpl)) {
|
S.log(LOG_PREFIX + 'No name or tpl specified.');
|
return false;
|
}
|
html = S.substitute(tpl, {
|
'name' : name
|
});
|
// TODO: inputContainer = DOM.create(html);
|
inputContainer = $(html);
|
//向body添加表单文件上传域
|
$(inputContainer).appendTo(target);
|
fileInput = $(inputContainer).children('input');
|
//TODO:IE6下只有通过脚本和内联样式才能控制按钮大小
|
if(S.UA.ie == 6) fileInput.css('fontSize','400px');
|
//TODO:firefox的fontSize不占宽度,必须额外设置left
|
//if(S.UA.firefox) fileInput.css('left','-1200px');
|
//上传框的值改变后触发
|
$(fileInput).on('change', self._changeHandler, self);
|
self.set('fileInput', fileInput);
|
self.set('inputContainer', inputContainer);
|
//禁用按钮
|
self._setDisabled(self.get('disabled'));
|
//控制多选
|
self._setMultiple(self.get('multiple'));
|
return inputContainer;
|
},
|
/**
|
* 文件上传域的值改变时触发
|
* @param {Object} ev 事件对象
|
*/
|
_changeHandler : function(ev) {
|
var self = this,
|
fileInput = self.get('fileInput'),
|
value = $(fileInput).val(),
|
//IE取不到files
|
oFiles = ev.target.files,files = [];
|
if (value == EMPTY) {
|
S.log(LOG_PREFIX + 'No file selected.');
|
return false;
|
}
|
if(oFiles){
|
S.each(oFiles,function(v){
|
if(S.isObject(v)){
|
files.push({'name' : v.name,'type' : v.type,'size' : v.size,data:v});
|
}
|
});
|
}else{
|
files.push({'name' : Button.getFileName(value)});
|
}
|
self.fire(Button.event.CHANGE, {
|
files: files,
|
input: fileInput.getDOMNode()
|
});
|
self.reset();
|
},
|
/**
|
* 设置上传组件的禁用
|
* @param {Boolean} disabled 是否禁用
|
* @return {Boolean}
|
*/
|
_setDisabled : function(disabled){
|
var self = this,
|
cls = self.get('cls'),disabledCls = cls.disabled,
|
$target = self.get('target'),
|
input = self.get('fileInput');
|
if(!$target.length || !S.isBoolean(disabled)) return false;
|
if(!disabled){
|
$target.removeClass(disabledCls);
|
$(input).show();
|
}else{
|
$target.addClass(disabledCls);
|
$(input).hide();
|
}
|
return disabled;
|
},
|
/**
|
* 设置上传组件的禁用
|
* @param {Boolean} multiple 是否禁用
|
* @return {Boolean}
|
*/
|
_setMultiple : function(multiple){
|
var self = this,fileInput = self.get('fileInput');
|
if(!fileInput.length) return false;
|
multiple && fileInput.attr('multiple','multiple') || fileInput.removeAttr('multiple');
|
return multiple;
|
}
|
}, {
|
ATTRS : /** @lends Button.prototype */{
|
/**
|
* 按钮目标元素
|
* @type KISSY.Node
|
* @default null
|
*/
|
target: {
|
value: null
|
},
|
/**
|
* 对应的表单上传域
|
* @type KISSY.Node
|
* @default ""
|
*/
|
fileInput: {
|
value: EMPTY
|
},
|
/**
|
* 文件上传域容器
|
* @type KISSY.Node
|
* @default ""
|
*/
|
inputContainer: {
|
value: EMPTY
|
},
|
/**
|
* 隐藏的表单上传域的模板
|
* @type String
|
*/
|
tpl : {
|
value : '<div class="file-input-wrapper" style="overflow: hidden;"><input type="file" name="{name}" hidefocus="true" class="file-input" /></div>'
|
},
|
/**
|
* 隐藏的表单上传域的name值
|
* @type String
|
* @default "fileInput"
|
*/
|
name : {
|
value : 'fileInput',
|
setter : function(v) {
|
if (this.get('fileInput')) {
|
$(this.get('fileInput')).attr('name', v);
|
}
|
return v;
|
}
|
},
|
/**
|
* 是否可用,false为可用
|
* @type Boolean
|
* @default false
|
*/
|
disabled : {
|
value : false,
|
setter : function(v) {
|
this._setDisabled(v);
|
return v;
|
}
|
},
|
/**
|
* 是否开启多选支持,多选目前有兼容性问题,建议禁用
|
* @type Boolean
|
* @default true
|
*/
|
multiple : {
|
value : true,
|
setter : function(v){
|
this._setMultiple(v);
|
return v;
|
}
|
},
|
/**
|
* 样式
|
* @type Object
|
* @default { disabled : 'uploader-button-disabled' }
|
*/
|
cls : {
|
value : {
|
disabled : 'uploader-button-disabled'
|
}
|
}
|
}
|
});
|
|
return Button;
|
|
}, {
|
requires:[
|
'node',
|
'base'
|
]
|
});
|