Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
756 views
in Technique[技术] by (71.8m points)

file upload - Vaadin with JQuery FileUpload

I would like to create FileUploader with Vaadin . But I need to get more features over normal Vaadin Upload.

  1. beautiful and easy to manage (but optional)
  2. fast and never failed while uploading
  3. include progress bar
  4. show preview
  5. multi file upload support
  6. upload file size and type restriction
  7. drag and drop
  8. client-side image resizable (it is main feature for me because all of my uploaded files were images)

There has an addon MultiFileUpload. Yes , it is perfect for most of my requirements but not for client-size image resizing. So I decided to use JQuery FileUpload because it is support for Client side Image Resizing.

I used vaadin Window for upload image. But I got a problem while creating my window , very hard to create each HTML elements respectively (may be I have less exp). So I used CustomLayout with HTML for easy to create and edit design of my image uploader window.

Below is my custom layout HTML file. (two scripts were templates for image preview)

<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload">
    <td width="100px" align="center">
        <span class="preview"></span>
    </td>
    <td width="400px" align="center">
        <p class="name">{%=file.name%}</p>
        {% if (!o.files.error) { %}
            <div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="bar" style="width:0%;"></div></div>
        {% } %}
        {% if (file.error) { %}
            <div><span class="label label-important">Error</span> {%=file.error%}</div>
        {% } %}
    </td>
    <td width="100px" align="center">
        {% if (!i) { %}
            <button style="display: none;" class="start" type="button">
                <span>Start</span>
            </button>
            <div class="v-button v-widget cancel" type = "button">
                <span class="v-button-wrap" style="color: red;">
                    <span class="v-button-caption">Cancel</span>
                </span>
            </div>
        {% } %}
        <br>
        {%=o.formatFileSize(file.size)%}
    </td>
</tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-download">
    <td width="100px" align="center">
        <span class="preview">
            {% if (file.path) { %}
                <img src="../{%=file.path%}" width="100px">
            {% } %}
        </span>
    </td>
    <td width="400px" align="center">
        <p class="name">
            {%=file.name%}
        </p>
        {% if (file.error) { %}
            <div><span class="label label-important">Error</span> {%=file.error%}</div>
        {% } %}
    </td>
    <td width="100px" align="center">
        <span class="size">{%=o.formatFileSize(file.size)%}</span>
    </td>
</tr>
{% } %}
</script>
<table cellpadding="5" style="width: 100%;">
<colgroup>
<col>
</colgroup>
<tbody>
    <tr>
        <td width="90px">
            <div style="text-align: right; width: 120px;">UploadPhoto :</div>
        </td>
        <td>
            <div id="pnlProgress" aria-valuenow="0" aria-valuemax="100" aria-valuemin="0" style="display: none;" class="progress progressall progress-success progress-striped active">
                <div style="width: 0%;" class="allbar" id="pnlProgressBar">&nbsp;</div>
            </div>
        </td>
    </tr>
    <tr>
        <td colspan="3">
            <div id="imageForm" style="width: 600px;">
                <form id="fileupload">
                    <div style="margin-bottom: 10px; border: 1px solid #DDD; width: 600px; height: 300px; overflow: scroll">
                        <table cellspacing="0" cellpadding="5">
                            <tbody class="files"></tbody>
                        </table>
                    </div>
                    <div style="margin-bottom: 10px;" class="fileupload-buttonbar">
                        <div class="v-button v-widget btnPlus">
                            <span class="v-button-caption">Add Files</span> 
                            <input type="file" multiple="" name="files[]">
                        </div>
                        <div class="v-button v-widget start" type = "submit">
                            <span class="v-button-wrap">
                                <span class="v-button-caption">StartUpload</span>
                            </span>
                        </div>
                        <div class="v-button v-widget cancel" type = "reset">
                            <span class="v-button-wrap">
                                <span class="v-button-caption">Cancel All</span>
                            </span>
                        </div>
                    </div>
                    <div style="border: 1px solid #999; width: 600px; height: 100px;" id="dropZone">
                        <div class="carPhotoDropMsg">
                            Draft &amp; Drop Photos<br>(jpg, jpeg, png, gif only)
                        </div>
                    </div>
                </form>
            </div>
        </td>
    </tr>
</tbody>

Below is for ImageUpload window

public final class ImageUploadDialog extends CustomComponent {
private Window window;

public void show() {
    UI.getCurrent().addWindow(window);
 // 123 is seq for save in database or other use
    Page.getCurrent().getJavaScript().execute("initImageuploader(123)");
}

public ImageUploadDialog() {
    CustomLayout layout = new CustomLayout("imageUploadLayout");
    window = new Window("Uploading Photos");
    window.center();
    window.setWidth("615px");
    window.setModal(true);
    window.setResizable(false);
    window.setClosable(true);
    window.setContent(layout);
}
}

And below is my upload.js file for initialize my image uploader

function initImageuploader(seq) {
$('#fileupload').fileupload({
    url : 'photo/upload.html?s=' + seq,
    sequentialUploads : true,
    disableImageResize : false,
    imageMaxWidth : 1024,
    imageMaxHeight : 1024,
    previewCrop : true,
    dropZone : $("#dropZone"),
    acceptFileTypes : /(.|/)(gif|jpe?g|png)$/i,
    progress : function(e, data) {
        if (data.context) {
            var progress = data.loaded / data.total * 100;
            progress = Math.floor(progress);
            $('.progress').attr('aria-valuenow', progress);
            $('.progress').css('display', 'block');
            $('.bar').css('width', progress + '%');
        }
    },
    progressall : function(e, data) {
        var progress = data.loaded / data.total * 100;
        progress = Math.floor(progress);
        $('.progressall').attr('aria-valuenow', progress);
        $('.progressall').css('display', 'block');
        $('.allbar').css('width', progress + '%');
        if (progress > 20) {
            $('.allbar').text(progress + '% Completed');
        }
    },
    stop: function (e) {
        return;
    }
});
}

And you need additional javascripts files for image uploader and I imported them at my UI class as below

@JavaScript({ "vaadin://themes/myproject/js/load-image.min.js",
    "vaadin://themes/myproject/js/tmpl.min.js",
    "vaadin://themes/myproject/js/jquery/jquery-1.10.1.min.js",
    "vaadin://themes/myproject/js/jquery/vendor/jquery.ui.widget.js",
    "vaadin://themes/myproject/js/jquery/jquery.iframe-transport.js",
    "vaadin://themes/myproject/js/jquery/jquery.fileupload.js",
    "vaadin://themes/myproject/js/jquery/jquery.fileupload-ui.js",
    "vaadin://themes/myproject/js/jquery/jquery.fileupload-process.js",
    "vaadin://themes/myproject/js/jquery/jquery.fileupload-image.js",
    "vaadin://themes/myproject/js/jquery/jquery.fileupload-validate.js",
    "vaadin://themes/myproject/js/canvas-to-blob.min.js",
    "vaadin://themes/myproject/js/upload.js" })
@StyleSheet({ "vaadin://themes/myproject/css/jquery-ui-1.10.3.custom.min.css",
    "vaadin://themes/myproject/css/imageUpload.css" })
public class EntryPoint extends UI {
..............
}

Please Notice for JS Files Order !

Below is my Custom CSS file for image upload window (imageUpload.css)

table.upld-status {
display: none;
}
.fileupload-buttonbar .btnPlus {
float: left;
position: relative;
overflow: hidden;
color: blue;
text-align: center;
margin-right : 10px;
}
.fileupload-buttonbar .btnPlus input {
margin: 0px;
position: absolute;
top: 0px;
right: 0px;
line-height: 30px;
font-size: 23px;
direction: ltr;
opacity: 0;
}
.carPhotoDropMsg {
color: #DDD;
font-size: 20pt;
height: 82%;
padding: 9px;
text-align: center;
}
.progress {
background-color: #F7F7F7;
background-image: linear-gradient(to bottom, #F5F5F5, #F9F9F9);
background-repeat: repeat-x;
border-radius: 4px 4px 4px 4px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
height: 17px;
overflow: hidden;
}
.progress-success.progress-striped .bar, .progress-success.progress-striped .allbar, .progress
striped .bar-success {
background-color: #62C462;
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
}
.progress.active .bar, .progress.active .allbar {
animation: 2s linear 0s normal none infinite progress-bar-stripes;
}
.progress-success .bar, .progress-success .allbar, .progress .bar-success {
background-color: #5EB95E;
background-image: linear-gradient(to bottom, #62C462, #57A957);
background-repeat: repeat-x;
}
.progress-striped .bar, .progress-striped .allbar {
background-color: #149BDF;
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
background-size: 40px 40px;
}
.progress .bar, .progress .allbar {
-moz-box-sizing: border-box;
background-color: #0E90D2;
background-image: linear-gradient(to bottom, #149BDF, #0480BE);
background-repeat: repeat-x;
box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.15) inset

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I fixed it by repairing src value of preview template for after upload image as ...

<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) {; %}
<tr class="template-download">
    <td width="100px" align="center">
        <span class="preview">
            {% if (file.path) { %}
                <img src="/myproject/{%=file.path%}" width="100px">
            {% } %}
        </span>
    </td>
    <td width="400px" align="center">
        <p class="name">
            {%=file.name%}
        </p>
        {% if (file.error) { %}
            <div><span class="label label-important">Error</span> {%=file.error%}</div>
        {% } %}
    </td>
    <td width="100px" align="center">
        <span class="size">{%=o.formatFileSize(file.size)%}</span>
    </td>
</tr>
{% } %}
</script>

Now everythings were fine. If you didn't see image immidiately , please check your IDE (Eclipse or STS) setting as below

Preference > General > Workspace

and check checkboxes Refresh on access and Refresh using native hooks or polling.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...