【bootstrap-fileinput】
这是个据传最好用的bootstrap相关联的文件上传控件,支持拖曳上传,多线程上传,上传文件预览等等功能。
首先还是说一下要引入的一些文件:
<link href="{% static 'bootstrap-fileinput/css/fileinput.min.css' %}" rel="stylesheet" /> <script src="{% static 'bootstrap-fileinput/js/fileinput.min.js' %}"></script> <script src="{% static 'bootstrap-fileinput/js/locales/zh.js' %}"></script>
同样也需要jquery和bootstrap的支持。
■ 基本使用
HTML:
<!-- 就是一个简单的文件表单字段 --> <label class="control-label" for="testfile">上传文件</label> <input type="file" id="testfile" name="test" multiple />
JS:
$('#testfile').fileinput({
language: 'zh', uploadUrl: location.pathname + 'upload/', showCaption: true, showUpload: true, showRemove: true, showClose: true, layoutTemplates:{ actionDelete: '' }, browseClass: 'btn btn-primary' });
通过这样的初始化得到的上传组件大概是这样子的:
我们姑且把显示一个个文件的虚线区域称为文件区,每个文件标识称为文件缩略图
然后来解释一下各个参数的含义:
language指出国际化显示的语言环境,需要locales下面响应的js文件的支持;uploadUrl指出了点击上传之后会将上传文件的这个post请求发向哪个url。(uploadUrl这个参数其实还牵扯到了fileinput支持的两种不同的上传方式——form上传和ajax上传,在配置了uploadUrl时默认就是选择了ajax上传方式。fileinput对于ajax方式的上传支持更好,而拖曳上传等功能也只有在ajax上传方式中才奏效。关于具体的两种上传方式的区别后面再说,现在先默认所有操作都是基于ajax方式上传来做的。)
showCaption 默认true,设置为false时将不显示下面那个类似于input[type=text]那样的显示框(然而这个显示框并不能直接编辑,它只是显示了文件名等信息)
showUpload 默认true,设置为false是不显示右下角那个上传按钮
showRemove 默认为true,设置为false时不显示右下角移除按钮
showClose 默认为true,设置为false时不显示右上角的小叉(这个叉的作用就是移除当前所有文件区中的文件)
以上这些都是一些非文件区内的显示调整
layoutTemplates和文件缩略图的样式相关,暂且先不谈
browseClass指出了右下角选择按钮的样式。一般尽量不要用btn-sm和btn-lg,会和左边的输入框不协调。
● 更多初始化参数
showPreview 默认true,设置为false时默认不显示整个文件区,自然就无法拖曳文件进行上传了。
showCancel 默认true,只在ajax上传模式中可用,在上传过程中右下角有一个取消按钮,可以取消上传
showUploadedThumbs 默认为true,这个属性是基于这样一个使用方法的:选择若干个文件后点击右下角上传按钮批量上传,待全部完成后再选择一批文件,此时之前上传成功的文件是否要保存。就是这个属性控制的。注意,点击文件缩略图下面的上传按钮不会导致之前的成功上传的文件消失,即使这里设置了true
showBrowse fileinput支持部分文件格式(如各种图片格式,txt,pdf等)的预览,点击缩略图的右上角按钮即可,这个就是控制是否显示这个按钮的。
autoReplace,maxFileCount 这两个属性配合一起使用,即可以设置一个文件区存放的最多文件的数量,当要处理的文件个数超过这个数量时自动只选取最后的那几个进行展示和处理。
captionClass/previewClass/mainClass/frameClass 这四个class参数可以为各自部分增加一些class属性、mainClass针对元素.file-caption-main,frameClass针对每个缩略图的框架。
initialPreview 通过这个参数,我们可以为文件区设置一些默认的缩略图。通常可以用于一些附带的默认要上传的文件。参数的值写html代码即可,不过为了和其他部分统一,我们要用file-preview-image,file-preview-text等fileinput预设的class。代码实例可以参考官方文档【http://plugins.krajee.com/file-input/plugin-options#initialPreview】。事实上,initialPreview这一块内容是很丰富的,也有很多很多相关的参数可以使用。这个主要是用于当需要直接从后端读取一些文件数据展示给前端,并且允许前端进行新增或删除操作时使用。这种场景其实已经超越了普通的文件上传表单的意义了。就不详细叙述。等到要用的时候再研究吧
● layoutTemplates
这个参数内容也比较多,所以单独拿出来说一下。这个参数的值应该是一个object,而object中的各个键值对指出了一个整个fileinput组件的各种样式。上面的基本应用示例中的actionDelete其实就是指缩略图上的删除按钮。如像我一样设置成了''(空值),则文件缩略图上就不会显示删除按钮了。从观念上来说,我们可以把各个键值对的值看成是一个模板性质的东西,改变相应的模板自然就可以渲染出相应的内容了。
既然有模板,那么肯定就有模板变量和有一定语法的模板语言。fileinput里面有一种叫做tag的机制,即在模板中会出现类似{variable}的变量,可以被具体内容替换。而模板之间是可以嵌套的。比如layoutTemplates.footer中有{actions}这个变量:
footer: '<div class="file-thumbnail-footer">\n' + ' <div class="file-caption-name" style="width:{width}">{caption}</div>\n' + ' {progress} {actions}\n' + '</div>',
,其内容是actions模板,而这个模板中又含有{upload},{download}等变量:
actions: '<div class="file-actions">\n' + ' <div class="file-footer-buttons">\n' + ' {upload} {download} {delete} {zoom} {other}' + ' </div>\n' + ' {drag}\n' + ' <div class="file-upload-indicator" title="{indicatorTitle}">{indicator}</div>\n' + ' <div class="clearfix"></div>\n' + '</div>',
有了模板机制,可以让我们*地选择再哪个层面的组件上进行模板的修改,然后模板系统会自动将这种改变传递给所有长辈模板,非常方便。因为我们不设置layoutTemplates参数也能渲染出一个界面来,说明这些模板中的所有变量(递归到最底层)都是有默认值的,这些默认值可以在这里看到:【http://plugins.krajee.com/file-input/plugin-options#layoutTemplates】。同时在修改模板时也要注意,除非有十足的把握,否则应该尽量不动这个模板中原本就有的那些变量。如果在改后的模板中少写了某个变量,就意味着这个变量指代的内容将不会被体现出来。
上面示例中给出的actionDelete相对还是比较低层级的模板,下面我们从高到低梳理一下各个层级的模板,部分模板没有变量,表明其是一个相对独立的模板:
main1 带有caption的渲染模板
main2 不带caption的渲染模板
preview 文件区的渲染模板
fileIcon caption中在文件名前面那个图标,默认glypyhicon-file
caption caption的渲染模板
modal modal的渲染模板(这个模态对话框在预览文件内容时出现)
progress 进度条的渲染模板,包括总进度条和每一个缩略图中进度条
size 含有{sizeText}变量,文件缩略图中文件大小部分信息的渲染模板
footer 含有{actions}变量等。
actions 含有{upload}、{download}、{delete}等变量,这三个变量分别代表了actionUpload,actionDownload和actionDelete三个模板的内容。
以actionDelete为例:
actionDelete里面还有removeClass,removeIcon,removeTitle等变量。这三个变量比较特殊,是在fileActionSettings里面进行设置的。
内容还有很多很多。。。我不想写了。总之就是看文档看文档
还有一个previewTemplates,是文件预览界面跳出来的模态框的样式设置, 不多说了。。
● 好的,继续来看其他的初始化参数
previewSettings 这个参数可以为不同类型的文件设置预览时不同的CSS,同这个系列的也还有很多
allowedFileTypes 一个数组,指出哪些类型的文件才是被接受上传的,尽量不要同时设置allowedFileTypes和allowedFileExtensions两个参数
allowedFileExtensions 一个数组,指出带有哪些后缀名的文件才是被接受上传的,设置msgInvalidFileExtension可以个性化出现此错误时的错误信息
previewFileIcon 当文件无法被预览时出现在缩略图中的图标,默认是<i class="glyphicon glyphicon-file"></i>
previewFileIconSettings 可以将不同的后缀的文件有不同的缩略图图标
uploadExtraData 刚才说过,如果使用ajax上传的话,可以设置这个属性来上传一些其他的数据。这个是一个object。
minFileSize/maxFileSize 指出上传支持的最小/最大的文件大小,同时可以设置msgFileTooSmall和msgFileTooLarge个性化报错信息
minFileCount/maxFileCount 指出上传最少/多几个文件,若设置成0则表示没有限制。默认是0
msgPlaceholder 默认是Select {files} ,代表了caption中的placeholder。如果是中文环境最好改一下,因为Select这个是没办法自己消除的。
msgFileRequired 当要求文件但是没上传时的报错信息
关于msg的还有很多参数比如太多太少,太大太小,没找到文件,文件不可读等等,不一一列举。
dropZoneEnabled 是否有拖曳文件上传区,和showPreview的区别在于,上传之后用户还是能看到文件缩略图,只是单纯不能拖曳上传了。
● fileActionSettings
最上面的那些show都是在缩略图外面的,现在来说说缩略图里面的一些东西要怎么控制显示隐藏:
showUpload,showDownload,showRemove,showZoom等就不说了
showDrag 显示拖动按钮(只适用于initialPreview的部分)
uploadIcon/uploadTitle/uploadClass 上传按钮相关的属性
download/remove/drag/zoom也有上面这三个
篇幅有些过长了。。关于fileinput的方法、事件以及两种上传方法的比较另开一片写
■ fileinput相关方法
通过$('#testfile').调用下列方法:
fileinput('disable/enable') 禁用/启用文件上传
fileinput('reset/clear') 清空待上传/所有文件(待上传就是说不包括已经上传的和initialPreview部分的缩略图)
fileinput('destroy') 将文件上传部分变回默认样式的上传表单字段
fileinput('refresh',{somenewconfig:value}) 这个方法可以动态增加或改变初始化参数,比如fileinput('refresh',{showCaption:false})这样子
fileinput('upload') 通过方法触发上传,这只适用于ajax上传方法。这个按钮相当于上传前caption右边那个上传按钮的事件
fileinput('lock/unlock') 这个比较有意思,会锁定/解锁fileinput组件(锁定指将各种删除/上传/预览/浏览等按钮disable掉,并且放出一个取消按钮,点击取消可手动解锁)
fileinput('getFileStack') 首先要了解什么是file stack。这个是待上传文件的一个栈,可以通过fileinput('addToStack/updateStack/clearStack')等方法进行改变。只是这些方法操作的对象是文件对象,不知道怎么在javascript中表示。。但是getFileStack这个方法是可以的,它就是返回了一个列表,其中是待上传的文件的栈。类似的getFilesCount可以返回当前待上传的文件的个数
fileinput('getFrames') 返回所有缩略图的jquery对象的列表。比较有意思的是,针对不同的状态(比如上传成功和失败),缩略图会有file-preview-success和file-preview-error这种class,我们可以基于这个class的存在情况来进行一些判断的
■ fileinput相关事件
通过$('#testfile').on('事件名',functionxx)来绑定事件和相关的响应函数,事件包括:
change 当文件选择中新增了文件(注意只有新增可以)触发
fileselect 当用户打开选择文件的对话框触发,无论其最终是否真的选中若干个文件还是点击了取消,这个事件都会被触发。
filebatchselected 当用户选择了多于一个文件时触发的事件,绑定的函数上除了event还可以有files参数,传入的值是被选择的文件对象的列表
fileclear/filecleared 当用户点击叉号或者移除按钮清空文件区时fileclear被触发,当所有缩略图被顺利删除之后filecleared被触发
fileloaded 当一个文件被顺利加载到文件区,准备被上传时触发。响应函数有4个附加参数,依次是file(文件对象),previewId(缩略图的id),index(该文件在这批上传文件中的index),reader(文件读取流实例)
filepreremove 当点击缩略图上的删除按钮,一个文件缩略图被删除时触发,两个附加参数是id和index
fileuploaded 在ajax上传的时候,每个缩略图代表的文件被成功上传之后触发的事件,有三个附加参数,data,previewId和index。data略复杂一些,是一个object,包含了字段:
form 表单数据
files 文件对象的列表
filenames 文件名的列表
filescount 上传的文件个数
extra uploadExtraData中上传上去的数据
response ajax返回
reader 文件读取流对象
类似的还有一个filebatchuploadsuccess,是在批量上传文件成功后触发的事件。以上是正常或者成功时触发的事件,下面介绍一些失败的事件
fileuploaderror 当客户端验证文件出错或上传出错时触发,附加参数data,是个object。含有字段:
id 出错文件缩略图的id
index
file 出错文件的文件对象
reader
files 文件对象数组
■ 两种不同的上传方式
内容确实比较多。。其实这块内容应该放在上面讲,已经很后面了。正如之前所说,存在两种不同的上传文件方式,即form上传和ajax上传。
对于ajax上传方式来说,是否上传成功是需要后台返回特定格式的数据来判定的。比如至少后台返回的数据应该是一个JSON串并且带有error字段,当error字段为空时默认上传成功。