Bootstrap file input组件在项目中的使用方式

Bootstrap file input组件是对HTML5标准的file input组件封装的一个js插件(以下对于file input组件简称插件)。该插件是以Bootstrap系列文件为基础的,可以和Bootstrap组件无缝对接。同时提供了非常丰富的文件上传、下载和预览等相关功能。
本文所涉及的各种样例均以file-input插件4.5.2版本为基础。

1、上传方式的简介

file input组件提供两种模式、三种类型的上传文件的方式。第一种模式是同步模式上传,即file input组件中的文件,在其所属的form表单内,随input组件中的其他元素一起提交到后端。这与传统的文件上传比较接近。第二种模式是Ajax模式上传,即file input组件中的文件,在其所属的form表单提交完成后,页面发起另一次http请求,将file input组件中的文件另行提交到后端。如果上传的文件有多个,在这种模式下,又分为两种类型。第一种类型是异步Ajax上传,即将多个文件以每个文件单独使用一次http请求的形式上传到后端。也就是说,多个文件需要多次http请求才能将文件全部上传完成。第二种类型是同步Ajax上传,即不论有多少个文件,插件都以一次http请求完成文件的上传。

2、页面导入文件,包括CSS、js文件。

"stylesheet" type="text/css" href="js/bootstrap-fileinput-4.5.2/css/fileinput.min.css" />


由于版本变化,也可以参考file-input插件官网的说明:https://plugins.krajee.com/file-input#usage

3、定义html元素

"form-group">
"m-b-15"> "uattachment" type="file" name="uattachment" multiple class="file-loading">
"errorBlockAttachment" class="help-block">

特别说明,此处的元素有用到bootstrap的样式,请各位自行添加相关css文件。在这里,我们定义了一个id为uattachment的,type为file的input组件,后面的代码将以此为核心进行封装。

4、配置插件

在页面的js代码部分写入如下代码:

$("#uattachment").fileinput({
    language: 'zh',
    elErrorContainer: "#errorBlockAttachment",
    uploadUrl: "wapi/fileupload",
    showPreview: true,
    showCaption: false,
    showRemove: true,
    showUpload: false,
    showCancel: false,
    showBrowse: false,
    showUploadedThumbs: false,
    browseOnZoneClick: true,
    allowedPreviewTypes: null,
    preferIconicPreview: true,
    overwriteInitial: false,
    initialPreview:preview,
    initialPreviewConfig:previewConfig,
    previewFileIconSettings: Files_ICON,
    previewFileExtSettings: Files_TestFunc,
    fileActionSettings: {
        showUpload: false,
        showZoom: false,
        showDownload: true,
        downloadIcon: '',
        downloadClass: 'btn btn-kv btn-default btn-outline-secondary',
        downloadTitle: '下载附件'
    },
    slugCallback: function(text) {
        if(text === undefined || text === null || text.length === 0) return '';
        return String(text).replace(/[\/:\*\?\\\|<>"']/g, '_');
    },
    uploadExtraData: function(previewId, index) {
        return {docId:$('#docId').val(), type:1};
    } 
});

通过上述代码,插件将对上文提到的id为uattachment的组件进行封装。

下面将对上述选项进行逐一解释:

$("#uattachment").fileinput({...)); 

这里是调用插件的fileinput方法,对id="uattachment"的jQuery对象进行fileinput组件的包装。以下所有的选项都是对包装的方式进行配置。

language: 'zh' 

这里的配置项是对语言的配置,这里的要求是语言的配置选项必须符合ISO的形式。同时,需要将对应的语言的js文件加载到页面中,且此语言文件的位置必须在导入的fileinput.js之后。
样例配置如下:

<script src="js/bootstrap-fileinput-4.5.2/js/fileinput.min.js"></script>
<script src="js/bootstrap-fileinput-4.5.2/js/locales/zh.js"></script>
elErrorContainer: "#errorBlockAttachment" 

这是对出错信息的展示组件进行定义,一般来说,为了布局的考虑,我们自行定义展示组件,在项目中,我们通常如下定义:

"errorBlockAttachment" class="help-block">

这里也可以不定义,组件会默认生成错误展示组件,具体可看官方文档,本文不再赘述。
https://plugins.krajee.com/file-input/plugin-options#elErrorContainer

uploadUrl: "wapi/fileupload"

(1)、如果开发者选择同步模式上传文件,按照官方文档的说明,此属性可以为null或者不设。由于同步模式上传文件的最终请求地址是在form中的action属性定义,所以从理论上来说是行得通的。但是有一点需要说明的是,此插件有个特点。当uploadUrl设置为空时,用户在操作时第二次打开文件选择框,选择的文件会将用户第一次选择的文件覆盖。如果用户需要一次选择多个文件上传,需要在打开的文件选择框中,按住键盘的ctrl键,然后用鼠标逐个点击需要上传的文件。选择完成后再释放ctrl键,再点击文件选择框的“打开”按钮。此时,插件会将这一次选择的多个文件加入上传文件列表。

(2)、如果开发者选择Ajax模式上传文件,此配置项设置的url即为上传文件的http请求的地址。当uploadUrl设置不为空时,用户可以多次点击文件选择框进行选择文件。多次选择的文件将不会覆盖之前选择的文件,会叠加在之前选择的文件后面,加入文件上传列表。
官网有这么一句话:
如果开发者需要通过Ajax方式使用拖拽、添加或者移除文件,选择性上传文件等功能,设置uploadUrl这个属性是非常重要的。对于Ajax方式上传文件而言,在后台端的参数名是type="file"的input元素的name属性名。如果未指定,则参数名默认为file_data,如下所示:MultipartFile[] file_data

下面介绍的几个有关显示的属性和插件的显示组件有关,可结合展示图来查看。
Bootstrap file input组件在项目中的使用方式_第1张图片

showPreview //默认为true 

此属性用来决定是否显示文件预览框。默认情况下,Preview是不能被点击的,仅作为文件预览框展示所用。如果browseOnZoneClick设置为true,则预览框还能通过点击打开文件选择框,选择文件。这里需要说明的是,Preview预览框不仅仅用来展示用户当前操作选择的文件,同时也是展示已保存的文件的一个通道。在项目的实际使用中,我们经常使用Preview预览框展示已保存的文件。在展示的文件框中,还提供有下载、删除等按钮,非常方便,建议按照此方法使用。

showCaption //默认为true 

这个Caption展现为一个文本框,里面默认显示当前附件框中有多少个文件被选中,包括已经上传的和选择上传的文件。Caption本身只能展示选中的文件,不能通过点击Caption来打开文件选择框,选择文件。用户只能通过Browse按钮来打开文件选择框,选择文件。

showRemove //默认为true 

这个Remove标志指的是在Caption旁出现的移除按钮。如果设置为false,则不会出现这个按钮。如果用户在附件选择框中新选择了文件,该按钮就会显示。点击该按钮,移除的是新选择的文件,对已经上传的文件没有影响。

showUpload //默认为true 

这个Upload标志指的是在Caption旁出现的上传按钮。如果是在同步模式下,此按钮等同于form表单的提交按钮,点击此按钮将会触发form表单的提交。在Ajax模式下,点击按钮,插件将会触发上传事件,将文件根据uploadUrl属性设定的地址进行上传。

showCancel //默认为true

这个Cancel标志指的是在Caption旁出现的取消按钮。此按钮只在Ajax模式下有用。如果插件设定为Ajax模式,则此属性默认为true,当插件设定为同步模式,则此属性默认为false。如果采用的是Ajax模式上传文件,那么在用户点击“上传”按钮上传文件后,取消按钮自动出现,一旦点击取消,则文件上传过程取消,取消按钮隐藏,恢复成点击上传前的状态。

showBrowse //默认为true 

这个属性设定的是显示选择文件的按钮。出现选择文件的按钮,点击此按钮,会弹出选择文件的选择框。通常,文件选择按钮与Caption或者Preview配合使用。

showClose// 默认为true 

这个属性设定的是在Preview预览框的右上角出现一个×号,点击此×号可以清空在Preview预览框,用户已经选择的文件。如果Caption设置为true,Caption文本框也出现,则在Caption框中的这些文件也会被清空。

showPause 

这个属性需要和enableResumableUpload属性联合使用,具体看官方文档。

showUploadedThumbs //默认为true 

官网上的介绍是在Ajax模式下,是否持续显示已经上传的文件。如果设置为false,批量选择的文件将会清空预览框中的文件。通常设置为false。

browseOnZoneClick //默认为false 

此属性设定Preview预览框是否能被点击,并弹出文件选择框。

allowedPreviewTypes 

参数值类型为array 此属性设定的是允许在预览框中出现的文件类型,官方参数值参考:[‘image’, ‘html’, ‘text’, ‘video’, ‘audio’, ‘flash’, ‘object’], 不在展示列表中的文件类型,插件将会显示一个默认的图标来表达文件类型。为了能够控制显示文件的图标,我们一般将此配置项设为null,并结合preferIconicPreview、previewFileIconSettings、previewFileExtSettings等属性联合控制文件预览的文件图标。

preferIconicPreview //默认为false 

此属性决定是否在预览框中显示文件的类型缩略图。如果设置为true,需要对previewFileIconSettings、previewFileExtSettings这两个属性进行设定。具体如何设定,下文会展示具体配置。

overwriteInitial //默认为true 

此属性确定,当预览框中有从数据库获取的已保存的文件在预览时,用户新选择的文件图标是否会覆盖这些已经处于预览状态的文件图标。通常情况下,设定为false。

previewFileIconSettings 

参数值类型为Object 预览文件的根据不同的文件类型(扩展名),展示不同的图标。具体代码见的样例。
官方样例如下:

previewFileIconSettings: {
    'doc': '',
    'xls': '',
    'ppt': '',
    'jpg': '',
    'pdf': '',
    'zip': '',
}
previewFileExtSettings 

参数值类型为object 此属性用来设定,多个不同的扩展名共用一个预览图标。
官网样例如下:

previewFileExtSettings: {
    'doc': function(ext) {
        return ext.match(/(doc|docx)$/i);
    },
    'xls': function(ext) {
        return ext.match(/(xls|xlsx)$/i);
    },
    'ppt': function(ext) {
        return ext.match(/(ppt|pptx)$/i);
    }
}
initialPreview 

参数类型 String或者Array 此属性用来展示预览的已经保存的文件。
参数格式:
一般推荐用Array的形式传参。将文件信息组成Array直接传入即可。如果用String格式来传参,在有多个文件的情况下,需要分隔符进行分割。分隔符默认是:$$。如果仅有单个文件进行预览,用String格式传参不需要分隔符。分隔符可以通过initialPreviewDelimiter属性进行配置,参数类型为String。
参数内容:
具体的参数内容样例,官网上有现成的例子。具体地址如下:https://plugins.krajee.com/file-input/plugin-options#initialPreview
但是我们一般用可以设定的比较简单,即将文件名组成一个js中的Array传入即可。

initialPreviewConfig 

参数类型Array 此属性用来给预览已保存的文件进行预览配置。参数的类型是Arrray,Array中的每一个元素可封装成一个jsonObject。每一个jsonObject对应一个需要预览的文件,jsonObject中的属性对应于配置项。常用的配置项如下:
type 参数类型 String 此属性用来确定预览文件的CSS样式值,样式值在previewSettings属性进行配置。type参数值与previewSettings属性配置的key值相对应。对于 reviewSettings属性设定,具体可看官网:https://plugins.krajee.com/file-input/plugin-options#previewSettings。

caption 参数类型 String 此属性用来展示预览文件的文件名或相关的文件标题。

size 参数类型 float 此属性用来展示预览文件的大小,以字节计算。

url 参数类型 String或者function 如果在插件中未设置deleteUrl,此属性用来设定删除文件的路径。并且是通过使用Ajax异步模式的Post提交。

这里需要说明几点:
(1)、如果插件需要使用删除预览文件的功能,则此属性必须配置,且不能为空。否则删除按钮即使能够显示,点击也无触发事件。
(2)、不管开发者根据业务需要,使用的业务同步或者业务异步删除,都需要在后台服务端配置对应此url响应的代码,并返回一个JSON结构的数据。如果是异步删除,则直接在此响应代码中进行处理,如果是同步删除,即删除文件动作与所属form表单一起提交处理,则此响应代码只返回个JSON结构的数据即可。
(3)、删除功能的请求参数可配置在与此属性同级别的extra属性中。extra属性的使用后面会具体说明。

downloadUrl 参数类型 String 此属性设定预览文件的下载地址。如果下载地址中需要参数,同样可以写在此地址后面。

key 参数类型 String 此属性的值将随url设定的删除路径请求提交到后台服务端,服务端获取此参数的参数名即是key。

extra 参数类型 Object 或者 Function ,此属性的值同样是随url设定的删除路径请求提交到后台服务端,一般用法是传递一个JSON结构值。但与key不同的是,在传递此参数到后台的过程中,插件将extra的值进行分拆,以JSON结构的key作为参数名,对应的value作为参数值,以这样的形式提交到服务端。

fileActionSettings 

参数类型 Object 或者 Function ,此属性用来设置预览框文件预览的格式。官方文档的说法是这个属性给新选择的文件指定预览的格式,但是实际上,在预览框中,已经上传到服务器端的文件的预览格式,也受此属性控制,只是有些配置无效。
常用的配置属性如下:
showUpload 参数类型 boolean 或者 function ,此属性仅对用户新选择的文件有效,对于已经上传至服务端,在预览框预览的文件无效。点击此按钮,此文件将根据插件设置的uploadUrl属性的值进行上传操作。

showZoom 参数类型 boolean 或者 function ,此属性对已经上传的文件和新选择的文件均有效。当此属性为true,则在预览的文件按钮区会出现一个放大镜图片的按钮,点击按钮,能够弹框显示此文件的详细预览。

showDownload 参数类型 boolean 或者 function ,此属性仅对已经上传的文件有效。当此属性为true,同时在此文件在initialPreviewConfig配置中设置了downloadUrl,文件的预览框的按钮区会出现一个下载按钮。点击下载按钮,自动触发下载动作,下载的地址就是downloadUrl设置的地址。

downloadIcon 参数类型String,此属性设定预览文件的下载按钮的图标。

downloadClass 参数类型String,此属性设定预览文件的下载按钮的图标的样式。

downloadTitle 参数类型String,此属性设定预览文件的下载按钮的title,即鼠标停留在按钮上显示的提示语句。

还有很多其他的Icon、Class、Title,为各种按钮配套,具体可看官方文档。

slugCallback 

参数类型 function,此属性设定一个方法,用于修正文件名中的不规范字符。此function的参数就是文件的文件名。如果开发人员不设此属性,插件将采用自带的slugDefault方法。

uploadExtraData 

参数类型 object或者function, 当用户采用Ajax模式上传文件,并设定了uploadUrl属性后,此属性设定的值将会随提交请求,一并提交到后台服务端。同extra属性设定的值,uploadExtraData一般设为JSON结构。上传时,插件将JSON结构值进行拆分,拆分成key为参数名,value为参数值,随请求一并提交到服务端。

5、实际项目样例

在实际项目中,我们通常采用Ajax模式上传,即将form表单内的其他元素提交到后端后,由后端返回附件文件所隶属对象的ID值,将此ID值通过uploadExtraData配置项与上传文件一起传递到后端。关于文件的删除,我们采用的是同步的删除的方式,即用户点击预览框中的文件的删除按钮,插件并不将文件ID传递到后端做删除操作,而是利用删除按钮的filebeforedelete事件,记录下删除文件的附件ID值,并赋值给form表单的元素。当form表单提交时,将删除附件的ID值一起提交到后端,由后端做删除操作。

HTML部分:

"form-group">
"m-b-15"> "uattachment" type="file" multiple class="file-loading">
"errorBlockAttachment" class="help-block">

js部分:

//定义预览已经保存的文件的配置项属性值
var previewConfig = "";//定义preview配置文件
var preview = "";//定义预览文件
if(data.files != undefined){//在这种情况下,是加载已经保存的文件,并在预览框中进行展示。
    previewConfig = JSON.parse(data.files).map(function(item){//data是后端返回的数据,data.files是一个JSON结构,里面记载了附件文件的相关信息。
        return {
	    type:'doc', 
            caption: item.oriName, //oriName是文件的原始名称,即上传时的文件名。
            size: item.size, //size是文件的大小,以字节计算。
            url: 'upload/delete', //文件删除路径 虽然文件删除并不用这个路径响应的代码删除,但是这里的路径必须返回一个JSON结构。            
            downloadUrl:'project/attachmentdownload?key='+item.saveName+'&fileName='+item.oriName, //文件下载路径,key和fileName是下载请求的参数。
            key: item.saveName, //saveName是文件保存在服务器硬盘上的物理文件名。
            extra:{id:100}//这个只是测试数据,测试id是否能够上传。
        };
    });
    
    preview = JSON.parse(data.files).map(function(item){
        return item.oriName;
    });
}

//定义配置项值
Files_ICON = {
    'ceb': '',
    'doc': '',
    'xls': '',
    'ppt': '',
    'jpg': '',
    'pdf': '',
    'zip': '',
    'htm': '',
    'txt': '',
    'mov': '',
    'mp3': '',
    'xml': ''
};
Files_TestFunc = {
    'ceb': function (ext) {
        return ext.match(/(ceb)$/i);
    },
    'doc': function (ext) {
        return ext.match(/(doc|docx)$/i);
    },
    'xls': function (ext) {
        return ext.match(/(xls|xlsx)$/i);
    },
    'ppt': function (ext) {
        return ext.match(/(ppt|pptx)$/i);
    },
    'jpg': function (ext) {
        return ext.match(/(jpg|jpeg|png|bmp|gif)$/i);
    },
    'pdf': function (ext) {
        return ext.match(/(pdf)$/i);
    },
    'zip': function (ext) {
        return ext.match(/(zip|rar|tar|gzip|gz|7z)$/i);
    },
    'htm': function (ext) {
        return ext.match(/(php|js|css|htm|html)$/i);
    },
    'txt': function (ext) {
        return ext.match(/(txt|ini|md)$/i);
    },
    'mov': function (ext) {
        return ext.match(/(avi|mpg|mkv|mov|mp4|3gp|webm|wmv)$/i);
    },
    'mp3': function (ext) {
        return ext.match(/(mp3|wav|ogg|m4a|wma)$/i);
    },
    'xml': function (ext) {
        return ext.match(/(xml)$/i);
    }
};

    //插件初始化
    $("#uattachment").fileinput({
        language: 'zh',
        elErrorContainer: "#errorBlockAttachment",
        uploadUrl: "upload/fileupload",
        showPreview: true,
        showCaption: false,
        showRemove: true,
        showUpload: false,
        showCancel: false,
        showBrowse: false,
        showUploadedThumbs: false,
        browseOnZoneClick: true,
        allowedPreviewTypes: null,
        preferIconicPreview: true,
        overwriteInitial: false,
        initialPreview:preview,//此值由前文js赋值
        initialPreviewConfig:previewConfig,//此值由前文js赋值
        previewFileIconSettings: Files_ICON,
        previewFileExtSettings: Files_TestFunc,
        fileActionSettings: {
            showUpload: false,
            showZoom: false,
            showDownload: true,//需要在initialPreviewConfig中设置downloadUrl,否则这里设置为true,下载按钮还是不会显示。
            downloadIcon: '',
            downloadClass: 'btn btn-kv btn-default btn-outline-secondary',
            downloadTitle: '下载附件'
        },
        slugCallback: function(text) {
            if(text === undefined || text === null || text.length === 0) return '';
            return String(text).replace(/[\/:\*\?\\\|<>"']/g, '_');
        },
        uploadExtraData: function(previewId, index) {
            return {id:$('#docId').val(), type:1};//这里id为docId的input存储的是附件文件所隶属的文档的ID值,后端根据此ID值,将附件文件与文档相关联。
        } 
    });

    // 目前采用同步方法删除附件文件,用户点击删除按钮,记录文件的保存名。这里采用的是同步方法删除预览框中的文件,即利用插件的filebeforedelete事件,记录附件      // 文件的ID值,当form提交到后端的时候,这些需要删除的附件的ID值一起随form提交,由后端程序处理删除。
    $("#uattachment").on('filebeforedelete', function (event, key, data) {
        $("#deleteNames").val($("#deleteNames").val() + "," + key);
    })

后端代码,以java为例:

@RequestMapping("upload/fileupload")
public BaseMessage fileUpload(Integer id, MultipartFile[] file_data, Integer type) {
    //参数id是前端通过uploadExtraData赋值的附件隶属的对象的ID值,附件通过此ID值与对象相关联。file_data是html元素中,对于type类型的文件上传input未指定            
    //name的情况下的默认值。 type是前端通过uploadExtraData赋值的附件相关信息值。                                                                         
    String files = "";
    if(file_data != null && file_data.length > 0){
        //具体的保存文件的操作,同时生成文件的相关信息,并赋值给变量files,返回给前端。返回的类BaseMessage是我们自己封装的一个返回响应的基本类。
    }
    return BaseMessage.Succ(files);
}

//此删除方法只是用来响应文件的删除按钮所配置url,并不做删除操作。如果开发者选择通过删除按钮删除附件文件,则可以在这里做删除附件的操作。但是还是要返回一个
//JSON结构的数据给前端。
@RequestMapping("upload/delete")
public BaseMessage deleteAttachmentDelete(String key, Integer id, String name){
    return BaseMessage.Succ();//这里BaseMessage是我们自己封装的一个返回响应的基本类,BaseMessage.Succ()返回的是一个JSON结构,类似{"code":0}这样的结构。
}

你可能感兴趣的:(Bootstrap file input组件在项目中的使用方式)