Bootstrap fileinput组件封装及使用详解

前端之家收集整理的这篇文章主要介绍了Bootstrap fileinput组件封装及使用详解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

介绍

通过本文,你可以学习到如何封装或者开发一个前端组件,同时学习Bootstrap-fileinput组件的使用,封装后使用更加简单方便。

BaseFile是AdminEAP框架中基于Bootstrap-fileinput的附件上传组件,它支持 支持文件、在线预览、拖拽上传功能,封装后BaseFile主要包括以下功能

@H_403_12@
  • 弹出窗口的附件上传
  • 当前界面的附件上传
  • 显示附件明细
  • 可编辑的附件明细(删除、预览、不可新增)
  • 关于Bootstrap-fileinput的API文档可参考

    本文源码已在AdminEAP框架(一个基于AdminLTE的Java开发平台)中开源,可在Github下载相关代码:

    Github:

    AdminEAP官网:

    使用说明

    1、初始化

    如果需要在当前界面使用附件上传功能(非弹窗方式)则需要在头部引入相关的css和js文件

    css文件

    js文件

    form表单上还需要配置enctype="multipart/form-data"属性

    2、弹窗方式调用

    BaseFile支持弹窗方式打开一个附件上传窗口,点击附件上传后,弹出窗口,上传附件关闭窗口后,上传的附件在type=file的控件回填。

    在表单中点击弹窗上传附件:

    BaseFile组件

    BaseFile组件

    上传完毕,关闭窗口,附件回填

    再次打开上传附件上传窗口时,会把已有的附件回填到附件上传窗口。

    配置如下:

    html代码

    上传附件(Max. 10MB)

    js代码

    3、本地界面调用

    本地界面调用附件上传,如下图所示:

    将上传附件嵌入到当前界面方式

    BaseFile组件

    上传后的附件可删除、可预览

    (目前图片文件可预览,其他文件不可预览,后期将集成txt/xml/html/pdf的预览功能)

    配置如下:

    html代码

    js代码

    4、控件参数说明

    window 默认为true,弹窗方式打开

    title window=true时配置,弹窗的标题,默认为“文件上传”

    width window=true时配置,弹窗的宽度,默认900

    winId window=true时配置,弹出的id,默认为fileWin

    fileinput Bootstrap-fileinput的配置参数,会覆盖默认配置,比如允许上传哪种类型的附件allowedFileTypes,允许上传最大附件大小maxFileSize,允许上传附件的个数maxFileCount等,具体的配置参数可以查询Bootstrap-fileinput的API文档。

    fileIdContainer 必须,上传后的附件id存储的位置,id以逗号分隔

    showContainer window=true必须配置,文件上传后回填的区域,window=false时如不配置,则取base-file的初始对象

    showType window=true配置,值为edit或者detail,edit表示回填后可对数据进行删除、预览,detail只能显示,不能删除

    callback window=true配置,关闭附件上传的窗口后执行的回调函数(比如更新当前的文件列表),fileIds,oldfileIds两个参数分别是更新后文件ids和更新前的文件ids

    BaseFile默认配置,BaseFile的更多实现,请查看BaseFile源码

    ',previewFileIconSettings: null,slugCallback: function (text) { var newtext=(!text||text=='') ? '' : String(text).replace(/[\-\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g,'_'); //去除空格 return newtext.replace(/(^\s+)|(\s+$)/g,"").replace(/\s/g,""); } } }

    5、BaseFile控件源码

    var pluginName = 'file';

    $.fn[pluginName] = function (options) {
    var self = $(this);
    if (this == null)
    return null;
    var data = this.data(pluginName);
    if (!data) {
    data = new BaseFile(this,$.extend(true,{},options));
    self.data(pluginName,data);
    }
    };

    var BaseFile = function (element,options) {
    this.element = element;
    //extend优先级 后面的会覆盖前面的
    //alert(this.element.selector);
    //将容器ID传过去便于弹窗获取到BaseFile对象,如果页面布局不在使用jquery.load方法,则该方法会失效,因为不是一个页面了
    options.container = options.container || this.element.selector.replace("#","");
    //初始化文件图标信息
    this.getFileIconSettings();
    this.options = $.extend(true,this.default,options);
    //初始化图标信息
    this.initFileIds();

    if(this.options.window) {
    this.element.click(function () {
    $(this).data('file').openWin();
    });
    }else{
    //非弹窗形式
    if(this.options.multiple)
    this.element.attr("multiple","multiple");
    }

    //如果配置了附件编辑容器showContainer(附件列表,可单个删除),则进行初始化
    if(this.hasDisplayZone()){
    this.showFiles();
    }

    }

    BaseFile.prototype.default = {
    winId: "fileWin","");
    }
    }
    }

    BaseFile.prototype.getFileInputConfig=function () {
    return this.options.fileinput;
    }
    BaseFile.prototype.getFileIconSettings = function () {
    var self = this;
    ajaxPost(basePath + "/file/icons",null,function (icons) {
    self.previewFileIconSettings = icons;
    //console.log(self.previewFileIconSettings);
    })
    }

    BaseFile.prototype.openWin = function () {
    var that = this;
    var self = $.extend(true,this.options);
    //深拷贝后删除属性,这样不会通过后台传送过去,防止被XSS过滤掉特殊字符
    //不需要通过参数config=传递到弹窗的参数可使用delete删除
    delete self.callback;
    delete self.fileIds;
    delete self.showContainer;
    delete self.fileIdContainer;
    delete self.fileinput;

    /console.log(this.options);
    console.log("=============");
    console.log(self);
    /
    modals.openWin({
    winId: that.options.winId,url: that.options.url + "?config=" + JSON.stringify(self),width: that.options.width + "px",title: that.options.title,backdrop: "static"
    });
    }

    BaseFile.prototype.callbackHandler = function (fileIds) {
    //更新fileIds并执行回调函数
    var oldfileIds = this.options.fileIds;
    this.options.fileIds = fileIds;
    this.updateFileIds();
    if (this.options.callback) {
    this.options.callback.call(this,fileIds,oldfileIds);
    }
    }

    //调用成功后执行显示附件
    BaseFile.prototype.showFiles=function(options){
    options=options||{};
    if(!this.hasDisplayZone()){
    modals.error("请配置showContainer属性,并在容器下配置type=file的input组件");
    return;
    }
    var fileIds=options.fileIds||this.options.fileIds;
    if(!fileIds&&this.options.window){
    $(this.options.showContainer).hide();
    return;
    }
    //显示
    $(this.options.showContainer).show();
    var fileComponet=$(this.options.showContainer);
    var fileResult=this.getFileResult(fileIds),preview=fileResult.initialPreview,previewConfig=fileResult.initialPreviewConfig,self=this;
    //配置三类参数 edit=附件列表(可删除) detail=附件列表(显示) 可上传
    var defaultConfig={
    initialPreview:preview,initialPreviewConfig:previewConfig
    };
    var config;
    if(this.options.window){
    if(this.options.showType=="edit"){
    //全局配置->本方法默认配置->edit属性下配置->外部参数
    config=$.extend({},self.options.fileinput,defaultConfig,{
    showRemove:false,showUpload:false,showClose:false,showBrowse:false,showCaption:false
    },options);
    }else if(this.options.showType=="detail"){
    config=$.extend({},showCaption:false,initialPreviewShowDelete:false
    },options);
    }
    }else{
    config=$.extend({},{
    showClose:false
    },options);
    }

    if(!config){
    modals.error("未找到showFiles中的相关配置");
    return;
    }
    //console.log("config=========="+JSON.stringify(config));
    fileComponet.fileinput('destroy');
    fileComponet.fileinput(config).on("filedeleted",function (event,key) {
    var newfids=self.deleteFileIds(key,self.options.fileIds);
    self.options.fileIds=newfids;
    self.updateFileIds();
    }).on("fileuploaded",function(event,data,previewId,index){
    var newfids=self.addFileIds(data.response.fileIds,self.options.fileIds);
    self.options.fileIds=newfids;
    self.updateFileIds();
    }).on("filebatchuploadsuccess",index) {
    var newfids=self.addFileIds(data.response.fileIds,self.options.fileIds);
    self.options.fileIds=newfids;
    self.updateFileIds();
    }).on("filezoomhidden",params) {
    $(document.body).removeClass('modal-open');
    $(document.body).css("padding-right","0px");
    });
    }

    /**

    • 向targetIds里删除数据fileIds
    • @param fileIds
    • @param targetIds
      */
      BaseFile.prototype.deleteFileIds=function(fileIds,targetIds){
      if(!fileIds) return targetIds;
      //没有文件删除,其中必有蹊跷
      if(!targetIds){
      modals.error("没有要删除的文件,请检查是否数据没有初始化");
      return;
      }
      var fileIdArr=fileIds.split(",");
      var fresult=targetIds.split(",");
      $.each(fileIdArr,function (index,fileId){
      //存在则删除
      if($.inArray(fileId,fresult)>-1){
      fresult.splice($.inArray(fileId,fresult),1);
      }
      })
      return fresult.join();
      }

    /**

    • 向targetIds里加数据fileIds
    • @param fileIds
    • @param targetIds
      */
      BaseFile.prototype.addFileIds=function (fileIds,targetIds) {
      if(!fileIds)return targetIds;
      var fileIdArr=fileIds.split(",");
      var fresult=[];
      if(targetIds){
      fresult=targetIds.split(",");
      }
      $.each(fileIdArr,fileId){
      //不存在,新增
      if($.inArray(fileId,fresult)==-1){
      fresult.push(fileId);
      }
      })
      return fresult.join();
      }

    BaseFile.prototype.updateFileIds=function(){
    if(this.options.fileIdContainer)
    $(this.options.fileIdContainer).val(this.options.fileIds);
    }

    BaseFile.prototype.initFileIds=function(){
    //不弹出窗口的话一定要绑定fileIdContainer
    if(!this.options.window){
    if(!this.options.fileIdContainer||!$(this.options.fileIdContainer)){
    modals.info("请设置fileIdContainer属性");
    return;
    }
    }
    if(!this.options.fileIds){
    if(this.options.fileIdContainer){
    this.options.fileIds=$(this.options.fileIdContainer).val();
    }
    }
    }

    BaseFile.prototype.getFileResult=function(fileIds){
    var ret=null;
    ajaxPost(basePath+"/file/getFiles",{fileIds:fileIds},function(result){
    ret=result;
    });
    return ret;
    };

    /**

    • 是否有显示区域
    • @returns {boolean}
      */
      BaseFile.prototype.hasDisplayZone=function(){
      if(!this.options.showContainer){
      this.options.showContainer=this.element.selector;
      }
      if(!this.options.showContainer||!$(this.options.showContainer)){
      return false;
      }
      return true;
      }

    })(jQuery,document);

    6、后端源码

    import com.cnpc.framework.base.entity.SysFile;
    import com.cnpc.framework.base.entity.User;
    import com.cnpc.framework.base.pojo.AvatarResult;
    import com.cnpc.framework.base.pojo.FileResult;
    import com.cnpc.framework.base.pojo.MarkDownResult;
    import com.cnpc.framework.base.pojo.Result;
    import com.cnpc.framework.base.service.UploaderService;
    import com.cnpc.framework.util.SecurityUtil;
    import com.cnpc.framework.utils.DateUtil;
    import com.cnpc.framework.utils.FileUtil;
    import com.cnpc.framework.utils.PropertiesUtil;
    import com.cnpc.framework.utils.StrUtil;
    import org.apache.commons.fileupload.util.Streams;
    import org.hibernate.criterion.DetachedCriteria;
    import org.hibernate.criterion.Order;
    import org.hibernate.criterion.Restrictions;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.MultipartHttpServletRequest;

    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.;
    import java.util.
    ;

    @Controller
    @RequestMapping("/file")
    public class UploaderController {

    private static Logger logger= LoggerFactory.getLogger(UploaderController.class);

    //previewFileIconSettings
    public static Map fileIconMap=new HashMap();
    @Resource
    private UploaderService uploaderService;

    static {
    fileIconMap.put("doc","");
    fileIconMap.put("docx","");
    fileIconMap.put("xls","");
    fileIconMap.put("xlsx","");
    fileIconMap.put("ppt","");
    fileIconMap.put("pptx","");
    fileIconMap.put("jpg","");
    fileIconMap.put("pdf","");
    fileIconMap.put("zip","");
    fileIconMap.put("rar","");
    fileIconMap.put("default","");
    }

    //从setting.properties文件中注入文件相对目录(相对目录为显示文件)
    //@Value("${uploaderPath}") 只有配置@Config才能注入
    private static final String uploaderPath=PropertiesUtil.getValue("uploaderPath");

    /**

    • 跳转到通用文件上传窗口
    • @return
      */
      @RequestMapping(value="/uploader",method = RequestMethod.GET)
      public String uploader(String config,HttpServletRequest request){
      request.setAttribute("config",config);
      return "base/file/file_uploader";
      }

    /**

    • 通用文件上传接口,存储到固定地址,以后存储到文件服务器地址
      */
      @RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
      @ResponseBody
      public SysFile uploadFile(@RequestParam(value = "file",required = false) MultipartFile file,HttpServletRequest request,HttpServletResponse response) {
      //TODO dosomething
      return new SysFile();
      }

    /**

    • 多文件上传,用于uploadAsync=false(同步多文件上传使用)
    • @param files
    • @param request
    • @param response
    • @return
      */
      @RequestMapping(value = "/uploadMultipleFile",method = RequestMethod.POST)
      @ResponseBody
      public FileResult uploadMultipleFile(@RequestParam(value = "file",required = false) MultipartFile[] files,HttpServletResponse response) throws IOException {
      System.out.println("the num of file:"+files.length);

    FileResult msg = new FileResult();

    ArrayList arr = new ArrayList<>();
    //缓存当前的文件
    List fileList=new ArrayList<>();
    String dirPath = request.getRealPath("/");
    for (int i = 0; i < files.length; i++) {
    MultipartFile file = files[i];

    if (!file.isEmpty()) {
    InputStream in = null;
    OutputStream out = null;
    try {
    File dir = new File(dirPath+uploaderPath);
    if (!dir.exists())
    dir.mkdirs();
    //这样也可以上传同名文件了
    String filePrefixFormat="yyyyMMddHHmmssS";
    System.out.println(DateUtil.format(new Date(),filePrefixFormat));
    String savedName=DateUtil.format(new Date(),filePrefixFormat)+"_"+file.getOriginalFilename();
    String filePath=dir.getAbsolutePath() + File.separator + savedName;
    File serverFile = new File(filePath);
    //将文件写入到服务器
    //FileUtil.copyInputStreamToFile(file.getInputStream(),serverFile);
    file.transferTo(serverFile);
    SysFile sysFile=new SysFile();
    sysFile.setFileName(file.getOriginalFilename());
    sysFile.setSavedName(savedName);
    sysFile.setCreateDateTime(new Date());
    sysFile.setUpdateDateTime(new Date());
    sysFile.setCreateUserId(SecurityUtil.getUserId());
    sysFile.setDeleted(0);
    sysFile.setFileSize(file.getSize());
    sysFile.setFilePath(uploaderPath+File.separator+savedName);
    uploaderService.save(sysFile);
    fileList.add(sysFile);
    /preview.add("<div class=\"file-preview-other\">\n" +
    "<span class=\"file-other-icon\"><i class=\"fa fa-file-o text-default\">\n" +
    "

    ");/

     logger.info("Server File Location=" + serverFile.getAbsolutePath());
    } catch (Exception e) {
     logger.error( file.getOriginalFilename()+"上传发生异常,异常原因:"+e.getMessage());
     arr.add(i);
    } finally {
     if (out != null) {
      out.close();
     }
     if (in != null) {
      in.close();
     }
    }

    } else {
    arr.add(i);
    }
    }

    if(arr.size() > 0) {
    msg.setError("文件上传失败!");
    msg.setErrorkeys(arr);
    }
    FileResult preview=getPreivewSettings(fileList,request);
    msg.setInitialPreview(preview.getInitialPreview());
    msg.setInitialPreviewConfig(preview.getInitialPreviewConfig());
    msg.setFileIds(preview.getFileIds());
    return msg;
    }

    //删除某一项文件
    @RequestMapping(value="/delete",method = RequestMethod.POST)
    @ResponseBody
    public Result delete(String id,HttpServletRequest request){
    SysFile sysFile=uploaderService.get(SysFile.class,id);
    String dirPath=request.getRealPath("/");
    FileUtil.delFile(dirPath+uploaderPath+File.separator+sysFile.getSavedName());
    uploaderService.delete(sysFile);
    return new Result();
    }

    /**

    • 获取字体图标map,base-file控件使用
      */
      @RequestMapping(value="/icons",method = RequestMethod.POST)
      @ResponseBody
      public Map getIcons(){
      return fileIconMap;
      }

    /**

    • 根据文件名获取icon
    • @param fileName 文件
    • @return
      */
      public String getFileIcon(String fileName){
      String ext= StrUtil.getExtName(fileName);
      return fileIconMap.get(ext)==null?fileIconMap.get("default").toString():fileIconMap.get(ext).toString();
      }

    /**

    • 根据附件IDS 获取文件
    • @param fileIds
    • @param request
    • @return
      */
      @RequestMapping(value="/getFiles",method = RequestMethod.POST)
      @ResponseBody
      public FileResult getFiles(String fileIds,HttpServletRequest request){
      String[] fileIdArr=fileIds.split(",");
      DetachedCriteria criteria=DetachedCriteria.forClass(SysFile.class);
      criteria.add(Restrictions.in("id",fileIdArr));
      criteria.addOrder(Order.asc("createDateTime"));
      List fileList=uploaderService.findByCriteria(criteria);
      return getPreivewSettings(fileList,request);
      }

    /**

    • 回填已有文件的缩略图
    • @param fileList 文件列表
    • @param request
    • @return initialPreiview initialPreviewConfig fileIds
      */
      public FileResult getPreivewSettings(List fileList,HttpServletRequest request){
      FileResult fileResult=new FileResult();
      List previews=new ArrayList<>();
      List<FileResult.PreviewConfig> previewConfigs=new ArrayList<>();
      //缓存当前的文件
      String dirPath = request.getRealPath("/");
      String[] fileArr=new String[fileList.size()];
      int index=0;
      for (SysFile sysFile : fileList) {
      //上传后预览 TODO 该预览样式暂时不支持theme:explorer的样式,后续可以再次扩展
      //如果其他文件可预览txt、xml、html、pdf等 可在此配置
      if(FileUtil.isImage(dirPath+uploaderPath+File.separator+sysFile.getSavedName())) {
      previews.add("<img src='." + sysFile.getFilePath().replace(File.separator,"/") + "' class='file-preview-image kv-preview-data' " +
      "style='width:auto;height:160px' alt='" + sysFile.getFileName() + " title='" + sysFile.getFileName() + "''>");
      }else{
      previews.add("
      " +
      ""+getFileIcon(sysFile.getFileName())+"
      ");
      }
      //上传后预览配置
      FileResult.PreviewConfig previewConfig=new FileResult.PreviewConfig();
      previewConfig.setWidth("120px");
      previewConfig.setCaption(sysFile.getFileName());
      previewConfig.setKey(sysFile.getId());
      // previewConfig.setUrl(request.getContextPath()+"/file/delete");
      previewConfig.setExtra(new FileResult.PreviewConfig.Extra(sysFile.getId()));
      previewConfig.setSize(sysFile.getFileSize());
      previewConfigs.add(previewConfig);
      fileArr[index++]=sysFile.getId();
      }
      fileResult.setInitialPreview(previews);
      fileResult.setInitialPreviewConfig(previewConfigs);
      fileResult.setFileIds(StrUtil.join(fileArr));
      return fileResult;
      }
      }

    总结

    本文源码已在AdminEAP框架(一个基于AdminLTE的Java开发平台)中开源,可在Github下载相关代码:

    Github:

    AdminEAP官网:nofollow" href="http://www.admineap.com">http://www.admineap.com

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

    原文链接:https://www.f2er.com/bootstrap/40829.html

    猜你在找的Bootstrap相关文章