多文件上传与额外inputText [英] Multiple file upload with extra inputText

查看:181
本文介绍了多文件上传与额外inputText的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要实现以下功能:
$ b $ ol
  • 以ajax风格上传多个文件(不刷新整个页面)



  • 必须使用JSF 2.0完成


  • 在任何组合中都没有问题做3中的2。多个文件上传与JSF 2.0 = PrimeFaces,多个文件上传+描述可能与JSF 2.2,因为它有本地上传元素(我想它可以是ajaxed,但没有检查它,因为我不能使用它),但是当我得到所有三个要求我一起卡住了。
    在PrimeFaces的 p:fileUpload 上没有描述字段,它的简单模式不支持ajax。
    JSF 2.0没有本地fileUpload组件。我可以将描述字段与PrimeFaces的 p:fileUpload 绑定,但是我无法阻止用户选择多个文件,并且会导致少数文件被绑定到一个描述。 / p>

    那么,是否有可能在PrimeFaces和JSF 2.0中使用描述字段以ajax风格执行多个文件上传?

    解决方案

    PrimeFaces上传基于:

      .append('< td class =title>< label>标题:< input name =title ['+ file.name +']>< / label>< / td> ')//我们必须做的唯一修改

    额外的输入文本叫做 title [fileName] ,在这种情况下,您将通过当前文件名获取请求参数的值。

      public void handleFileUpload(FileUploadEvent event){
    FacesContext context = FacesContext.getCurrentInstance();
    Map map = context.getExternalContext()。getRequestParameterMap();
    String paramName =title [+ event.getFile()。getFileName()+];
    String fileWithTitle =(String)map.get(paramName);



    $ b

    下面是完整的 add 选项(假设你的 widgetVar fileUpload



    ($)$($)$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ (){

    PF('fileUpload')。jq.fileupload({
    add:function(e,data){
    $ this = PF('fileUpload');
    $ this.chooseButton.removeClass('ui-state-hover ui-state-focus');
    if($ this.files.length === 0){
    $ this。 enableButton($ this.uploadButton);
    $ this.enableButton($ this.cancelButton);
    }

    if($ this.cfg.fileLimit&&($ this.uploadedFileCount + $ this.files.length + 1)> $ this.cfg.fileLimit){
    $ this.clearMessages();
    $ this.showMessage({
    summary: $ this.cfg.fileLimitMessage
    });

    返回;
    }

    var file = data.files? data.files [0]:null;
    if(file){
    var validMsg = $ this.validate(file);

    if(validMsg){
    $ this.showMessage({
    summary:validMsg,
    filename:file.name,
    filesize:file.size
    });
    }
    else {
    $ this.clearMessages();
    //我们必须做的唯一修改
    var row = $('< tr>< / tr>')。append('< td class =ui-fileupload-preview >< / td>')
    .append('< td>'+ file.name +'< / td>')
    .append('< td class = >< label>标题:< input name =title ['+ file.name +']>< / label>< / td>')
    .append('< td>'+ $ this.formatSize(file.size)+'< / td>')
    .append('< td class =ui-fileupload-progress>< / td>' )
    .append('< td>< button class =ui-fileupload-cancel ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only> < / span>< span class =ui-button-text> ui-button< span class =ui-button-icon-left / span>< / button>< / td>')
    .appendTo($ this.filesTbody); ($ this.isCanvasSupported()&& window.File&& window.FileReader&&& $ this.IMAGE_TYPES.test(file.name))


    ) {
    var imageCanvas = $('< canvas>< / canvas')
    .appendTo(row.children('td.ui-fileupload-preview')),
    context = imageCanvas.get(0).getContext('2d'),
    winURL = window.URL || window.webkitURL,$ b $ url url = winURL.createObjectURL(file),
    img = new Image();

    img.onload = function(){
    var imgWidth = null,imgHeight = null,scale = 1;

    if($ this.cfg.previewWidth> this.width){
    imgWidth = this.width;
    }
    else {
    imgWidth = $ this.cfg.previewWidth;
    scale = $ this.cfg.previewWidth / this.width;
    }

    var imgHeight = parseInt(this.height * scale);

    imageCanvas.attr({width:imgWidth,height:imgHeight});
    context.drawImage(img,0,0,imgWidth,imgHeight);
    }

    img.src = url;
    }

    // progress
    row.children('td.ui-fileupload-progress')。append('< div class =ui-progressbar ui-widget ui-widget-content ui-corner-allrole =progressbararia-valuemin =0aria-valuemax =100aria-valuenow =0>< div class =ui-progressbar-value ui-widget-header ui-corner-leftstyle =display:none; width:0%;>< / div>< / div>);

    file.row = row;

    file.row.data('filedata',data);
    $ this.files.push(file);

    if($ this.cfg.auto){
    $ this.upload();
    }
    }
    }
    }});



    $ b $ p $ js code>文件并包含在< / h:body>



    这是 在线演示



    注意:如果用户使用 选择了多个具有相同名称和扩展名的文件 ,你会得到第一个标题两次,对于一些这将是好的,因为用户不应该上传相同的文件。



    这是测试PrimeFaces 5.0和Chrome。


    I need to implement the following:

    1. multiple file upload in ajax style (without refreshing whole page)
    2. description field per file
    3. it must be done with JSF 2.0

    There isn't problem to do 2 of 3 requirement in any combination. Multiple fileUpload with JSF 2.0 = PrimeFaces, multiple file upload + description is possible with JSF 2.2 because it has native upload element (I guess it can be ajaxed but didn't check it because I can't use it), but when I get all three requirements together I get stuck. On PrimeFaces's p:fileUpload there isn't description field and its simple mode doesn't support ajax. JSF 2.0 doesn't have native fileUpload component. I can bind description field with PrimeFaces's p:fileUpload but I can't prevent from a user to choose multiple files and it cause that few files will be tied to one description.

    So, is it possible to do multiple file upload in ajax style with description field in PrimeFaces and JSF 2.0?

    解决方案

    PrimeFaces upload is based on blueimp/jQuery-File-Upload.

    When .serializeArray() gets called, all the data inside that form would be serialized.

    In that case you could override the PrimeFaces implementation of the add option to append one extra input text for each file.

    So the result would look like this:

    Now that would be one extra line of code, exactly here:

    .append('<td class="title"><label>Title: <input name="title['+ file.name +']"></label></td>') //the only modification we have to do
    

    The extra input text is called title[fileName], in that case you would get the value of the request parameter by the current file name.

    public void handleFileUpload(FileUploadEvent event) {
        FacesContext context = FacesContext.getCurrentInstance();
        Map map = context.getExternalContext().getRequestParameterMap();
        String paramName = "title["+event.getFile().getFileName()+"]";
        String fileWithTitle = (String) map.get(paramName);            
    }
    

    Here's the full implementation of the add option (assuming your widgetVar is fileUpload)

    $(document).ready(function() {
       setTimeout(fileUpload, 1000);
    })
    
    function fileUpload() {
    
    PF('fileUpload').jq.fileupload({
        add: function(e, data) {
            $this = PF('fileUpload');
            $this.chooseButton.removeClass('ui-state-hover ui-state-focus');
            if ($this.files.length === 0) {
                $this.enableButton($this.uploadButton);
                $this.enableButton($this.cancelButton);
            }
    
            if ($this.cfg.fileLimit && ($this.uploadedFileCount + $this.files.length + 1) > $this.cfg.fileLimit) {
                $this.clearMessages();
                $this.showMessage({
                    summary: $this.cfg.fileLimitMessage
                });
    
                return;
            }
    
            var file = data.files ? data.files[0] : null;
            if (file) {
                var validMsg = $this.validate(file);
    
                if (validMsg) {
                    $this.showMessage({
                        summary: validMsg,
                        filename: file.name,
                        filesize: file.size
                    });
                }
                else {
                    $this.clearMessages();                                                                               
                    //the only modification we have to do
                    var row = $('<tr></tr>').append('<td class="ui-fileupload-preview"></td>')
                            .append('<td>' + file.name + '</td>')
                            .append('<td class="title"><label>Title: <input name="title['+ file.name +']"></label></td>') 
                            .append('<td>' + $this.formatSize(file.size) + '</td>')
                            .append('<td class="ui-fileupload-progress"></td>')
                            .append('<td><button class="ui-fileupload-cancel ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only"><span class="ui-button-icon-left ui-icon ui-icon ui-icon-close"></span><span class="ui-button-text">ui-button</span></button></td>')
                            .appendTo($this.filesTbody);
    
    
                    if ($this.isCanvasSupported() && window.File && window.FileReader && $this.IMAGE_TYPES.test(file.name)) {
                        var imageCanvas = $('<canvas></canvas')
                                .appendTo(row.children('td.ui-fileupload-preview')),
                                context = imageCanvas.get(0).getContext('2d'),
                                winURL = window.URL || window.webkitURL,
                                url = winURL.createObjectURL(file),
                                img = new Image();
    
                        img.onload = function() {
                            var imgWidth = null, imgHeight = null, scale = 1;
    
                            if ($this.cfg.previewWidth > this.width) {
                                imgWidth = this.width;
                            }
                            else {
                                imgWidth = $this.cfg.previewWidth;
                                scale = $this.cfg.previewWidth / this.width;
                            }
    
                            var imgHeight = parseInt(this.height * scale);
    
                            imageCanvas.attr({width: imgWidth, height: imgHeight});
                            context.drawImage(img, 0, 0, imgWidth, imgHeight);
                        }
    
                        img.src = url;
                    }
    
                    //progress
                    row.children('td.ui-fileupload-progress').append('<div class="ui-progressbar ui-widget ui-widget-content ui-corner-all" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="ui-progressbar-value ui-widget-header ui-corner-left" style="display: none; width: 0%;"></div></div>');
    
                    file.row = row;
    
                    file.row.data('filedata', data);
                    $this.files.push(file);
    
                    if ($this.cfg.auto) {
                        $this.upload();
                    }
                }
            }
        }});
    }
    

    Just included the above code in some js file and included it before the end of </h:body>

    Here's an online Demo.

    Note: the only drag you might have in this approach, if the user has selected multiple files with the same exact name and extension you would get the first title twice!, for some this would be okay, since the user isn't supposed to upload identical files.

    This is test on PrimeFaces 5.0 and Chrome.

    这篇关于多文件上传与额外inputText的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆