001package gwt.material.design.addins.client.fileuploader;
002
003/*
004 * #%L
005 * GwtMaterial
006 * %%
007 * Copyright (C) 2015 - 2016 GwtMaterialDesign
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023
024import com.google.gwt.dom.client.Document;
025import com.google.gwt.dom.client.Element;
026import com.google.gwt.event.shared.HandlerRegistration;
027import com.google.gwt.user.client.DOM;
028import com.google.gwt.user.client.ui.Widget;
029import gwt.material.design.addins.client.MaterialAddins;
030import gwt.material.design.addins.client.dnd.events.DragEndEvent;
031import gwt.material.design.addins.client.dnd.events.DragStartEvent;
032import gwt.material.design.addins.client.fileuploader.base.HasFileUpload;
033import gwt.material.design.addins.client.fileuploader.base.UploadFile;
034import gwt.material.design.addins.client.fileuploader.base.UploadResponse;
035import gwt.material.design.addins.client.fileuploader.constants.FileMethod;
036import gwt.material.design.addins.client.fileuploader.events.*;
037import gwt.material.design.client.MaterialDesignBase;
038import gwt.material.design.client.base.MaterialWidget;
039import gwt.material.design.client.constants.Display;
040
041import java.util.Date;
042
043//@formatter:off
044
045/**
046 * Custom file uploader with Dnd support with the help of dropzone.js. It has multiple
047 * feature just like the GWT File Uploader core widget.
048 *
049 * <h3>XML Namespace Declaration</h3>
050 * <pre>
051 * {@code
052 * xmlns:ma='urn:import:gwt.material.design.addins.client'
053 * }
054 * </pre>
055 *
056 * <h3>UiBinder Usage:</h3>
057 * <pre>
058 * {@code
059 * <ma:fileuploader.MaterialFileUploader url="/file/upload"/>
060 * }
061 * </pre>
062 *
063 * @author kevzlou7979
064 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#fileuploader">File Uploader</a>
065 */
066//@formatter:on
067public class MaterialFileUploader extends MaterialWidget implements HasFileUpload<UploadFile> {
068
069    static {
070        if(MaterialAddins.isDebug()) {
071            MaterialDesignBase.injectDebugJs(MaterialFileUploaderDebugClientBundle.INSTANCE.dropzoneJsDebug());
072            MaterialDesignBase.injectCss(MaterialFileUploaderDebugClientBundle.INSTANCE.dropzoneCssDebug());
073        } else {
074            MaterialDesignBase.injectJs(MaterialFileUploaderClientBundle.INSTANCE.dropzoneJs());
075            MaterialDesignBase.injectCss(MaterialFileUploaderClientBundle.INSTANCE.dropzoneCss());
076        }
077    }
078
079    private String url; // Has to be specified on elements other than form (or when the form doesn't have an action attribute).
080    private int maxFileSize = 20; // 20MB by default for max file size
081    private boolean autoQueue = true;
082    private FileMethod method = FileMethod.POST; // Defaults to "post" and can be changed to "put" if necessary.
083    private int maxFiles = 100; // If the number of files you upload exceeds, the event maxfilesexceeded will be called. By default it's 100 files.
084    private String acceptedFiles = ""; // The default implementation of accept checks the file's mime type or extension against this list. This is a comma separated list of mime types or file extensions. Eg.: image/*,application/pdf,.psd
085    private String clickable = "";
086    private MaterialUploadPreview uploadPreview = new MaterialUploadPreview();
087    private boolean preview = true;
088    private boolean initialize = false;
089    private boolean withCredentials = false;
090
091    public MaterialFileUploader() {
092        super(Document.get().createDivElement(), "fileuploader");
093        setId("zdrop");
094        add(uploadPreview);
095    }
096
097    @Override
098    protected void onLoad() {
099        super.onLoad();
100        if(!isInitialize()) {
101            initDropzone();
102            setInitialize(true);
103        }
104    }
105
106    @Override
107    public void add(Widget child) {
108        super.add(child);
109    }
110
111    public void initDropzone() {
112        String previews = DOM.createUniqueId();
113        uploadPreview.getUploadCollection().setId(previews);
114        if(clickable.isEmpty()) {
115            String clickable = DOM.createUniqueId();
116            if (getWidget(1) instanceof MaterialUploadLabel) {
117                MaterialUploadLabel label = (MaterialUploadLabel) getWidget(1);
118                label.getIcon().setId(clickable);
119            } else {
120                getWidget(1).getElement().setId(clickable);
121            }
122            setClickable(clickable);
123        }
124        if(!isPreview()){
125            uploadPreview.setDisplay(Display.NONE);
126        }
127        initDropzone(getElement(), uploadPreview.getUploadCollection().getItem().getElement(), previews, uploadPreview.getElement(),uploadPreview.getUploadHeader().getUploadedFiles().getElement(), getUrl(), getMaxFileSize(), getMaxFiles(), getMethod().getCssName(), isAutoQueue(), getAcceptedFiles(), getClickable(), preview, isWithCredentials());
128    }
129
130    /**
131     * Intialize the dropzone component with element and form url to provide a
132     * dnd feature for the file upload
133     * @param e
134     * @param url
135     */
136    protected native void initDropzone(Element e, Element template, String previews, Element uploadPreview, Element uploadedFiles, String url, int maxFileSize, int maxFiles, String method, boolean autoQueue, String acceptedFiles, String clickable,boolean preview,boolean withCredentials) /*-{
137        var that = this;
138        $wnd.jQuery(document).ready(function() {
139            var previewNode = $wnd.jQuery(template);
140            var previewContainer = $wnd.jQuery("#" + previews).html();
141            previewNode.id = "";
142            var previewTemplate = previewNode.parent().html();
143            var globalResponse = "";
144
145            var totalFiles = 0;
146            var zdrop = new $wnd.Dropzone(e, {
147                url: url,
148                maxFilesize: maxFileSize,
149                method: method,
150                maxFiles: maxFiles,
151                previewTemplate: previewTemplate,
152                acceptedFiles: acceptedFiles,
153                autoQueue: autoQueue,
154                previewsContainer: "#" + previews,
155                clickable: "#" + clickable,
156                withCredentials: withCredentials
157            });
158
159            zdrop.on('drop', function () {
160                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireDropEvent()();
161                if(preview) {
162                    $wnd.jQuery(e).removeClass("active");
163                }
164            });
165
166            zdrop.on('dragstart', function () {
167                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireDragStartEvent()();
168            });
169
170            zdrop.on('dragend', function () {
171                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireDragEndEvent()();
172            });
173
174            zdrop.on('dragenter', function () {
175                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireDragEnterEvent()();
176                if(preview){
177                    $wnd.jQuery(e).addClass("active");
178                }
179            });
180
181            zdrop.on('dragover', function () {
182                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireDragOverEvent()();
183            });
184
185            zdrop.on('dragleave', function () {
186                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireDragLeaveEvent()();
187                if(preview) {
188                    $wnd.jQuery(e).removeClass("active");
189                }
190            });
191
192            zdrop.on("addedfile", function(file) {
193                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireAddedFileEvent(*)(file.name , file.lastModifiedDate , file.size , file.type);
194                totalFiles += 1;
195                $wnd.jQuery(uploadPreview).css('visibility', 'visible');
196                $wnd.jQuery(uploadedFiles).html('Uploaded files ' + totalFiles);
197            });
198
199            zdrop.on("removedfile", function(file) {
200                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireRemovedFileEvent(*)(file.name , file.lastModifiedDate , file.size , file.type);
201                totalFiles -= 1;
202                $wnd.jQuery(uploadedFiles).html('Uploaded files ' + totalFiles);
203            });
204
205            zdrop.on('error', function (file, response) {
206                var code = '200';
207                if(file.xhr !== undefined) {
208                    code = file.xhr.status;
209                }
210                if(response.indexOf("401") >= 0) {
211                    response = "Unautharized. Probably Your's session expired. Log in and try again.";
212                    globalResponse = response;
213                    that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireUnauthorizedEvent(*)(file.name , file.lastModifiedDate , file.size , file.type, file.xhr.status, file.xhr.statusText, response);
214                }
215                if(response.indexOf("404") >= 0) {
216                    response = "There's a problem uploading your file.";
217                    globalResponse = response;
218                }
219                if(response.indexOf("500") >= 0) {
220                    response = "There's a problem uploading your file.";
221                    globalResponse = response;
222                }
223                file.previewElement.querySelector("#error-message").innerHTML = response;
224                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireErrorEvent(*)(file.name , file.lastModifiedDate , file.size , file.type, code, response);
225            });
226
227            zdrop.on("totaluploadprogress", function (progress) {
228                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireTotalUploadProgressEvent(*)(progress);
229                var progr = document.querySelector(".progress .determinate");
230                if (progr === undefined || progr === null)
231                    return;
232                progr.style.width = progress + "%";
233            });
234
235            zdrop.on('sending', function (file) {
236                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireSendingEvent(*)(file.name , file.lastModifiedDate , file.size , file.type, file.xhr.status, file.xhr.statusText);
237            });
238
239            zdrop.on('success', function (file, response) {
240                globalResponse = response;
241                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireSuccessEvent(*)(file.name , file.lastModifiedDate , file.size , file.type, file.xhr.status, file.xhr.statusText, response);
242            });
243
244            zdrop.on('complete', function (file) {
245                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireCompleteEvent(*)(file.name , file.lastModifiedDate , file.size , file.type, file.xhr.status, file.xhr.statusText, globalResponse);
246            });
247
248            zdrop.on('canceled', function (file) {
249                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireCancelEvent(*)(file.name , file.lastModifiedDate , file.size , file.type);
250            });
251
252            zdrop.on('maxfilesreached', function (file) {
253                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireMaxFilesReachEvent(*)(file.name , file.lastModifiedDate , file.size , file.type);
254            });
255
256            zdrop.on('maxfilesexceeded', function(file) {
257                that.@gwt.material.design.addins.client.fileuploader.MaterialFileUploader::fireMaxFilesExceededEvent(*)(file.name , file.lastModifiedDate , file.size , file.type);
258                Materialize.toast('You have reached the maximum files to be uploaded.', 4000);
259            });
260        });
261    }-*/;
262
263    /**
264     * Get the form url
265     * @return
266     */
267    public String getUrl() {
268        return url;
269    }
270
271    /**
272     * Set the form url e.g /file/post
273     * @param url
274     */
275    public void setUrl(String url) {
276        this.url = url;
277    }
278
279    /**
280     * Get the maximum file size value of the uploader
281     * @return
282     */
283    public int getMaxFileSize() {
284        return maxFileSize;
285    }
286
287    /**
288     * Set the maximum file size of the uploader
289     * @param maxFileSize
290     */
291    public void setMaxFileSize(int maxFileSize) {
292        this.maxFileSize = maxFileSize;
293    }
294
295    /**
296     * Check whether it's auto queue or not
297     * @return
298     */
299    public boolean isAutoQueue() {
300        return autoQueue;
301    }
302
303    /**
304     * Set the auto queue boolean value
305     * @param autoQueue
306     */
307    public void setAutoQueue(boolean autoQueue) {
308        this.autoQueue = autoQueue;
309    }
310
311    /**
312     * Get the method param of file uploader
313     * @return
314     */
315    public FileMethod getMethod() {
316        return method;
317    }
318
319    /**
320     * Set the method param of file upload (POST or PUT)
321     * @param method
322     */
323    public void setMethod(FileMethod method) {
324        this.method = method;
325    }
326
327    /**
328     * Get the max number of files.
329     * @return
330     */
331    public int getMaxFiles() {
332        return maxFiles;
333    }
334
335    /**
336     * Check whether it's withCredentials or not
337     * @return
338     */
339    public boolean isWithCredentials() {
340        return withCredentials;
341    }
342
343    /**
344     * Set the withCredentials boolean value
345     * @param withCredentials
346     */
347    public void setWithCredentials(boolean withCredentials) {
348        this.withCredentials = withCredentials;
349    }
350
351
352    /**
353     * Set the max number of files, by default it's 100 but if you want to accept only one file just
354     * set the max file to 1
355     * @param maxFiles
356     */
357    public void setMaxFiles(int maxFiles) {
358        this.maxFiles = maxFiles;
359    }
360
361    /**
362     * Get the accepted file string
363     * @return
364     */
365    public String getAcceptedFiles() {
366        return acceptedFiles;
367    }
368
369    /**
370     * Set the default implementation of accept checks the file's mime type or extension against this list. This is a comma separated list of mime types or file extensions. Eg.: image/*,application/pdf,.psd
371     * @param acceptedFiles
372     */
373    public void setAcceptedFiles(String acceptedFiles) {
374        this.acceptedFiles = acceptedFiles;
375    }
376
377    @Override
378    public HandlerRegistration addDropHandler(final DropEvent.DropHandler handler) {
379        return addHandler(new DropEvent.DropHandler() {
380            @Override
381            public void onDrop(DropEvent event) {
382                if(isEnabled()){
383                    handler.onDrop(event);
384                }
385            }
386        }, DropEvent.TYPE);
387    }
388
389    @Override
390    public void fireDropEvent() {
391        DropEvent.fire(this);
392    }
393
394    @Override
395    public HandlerRegistration addDragStartHandler(final DragStartEvent.DragStartHandler handler) {
396        return addHandler(new DragStartEvent.DragStartHandler() {
397            @Override
398            public void onDragStart(DragStartEvent event) {
399                if(isEnabled()){
400                    handler.onDragStart(event);
401                }
402            }
403        }, DragStartEvent.TYPE);
404    }
405
406    @Override
407    public void fireDragStartEvent() {
408        DragStartEvent.fire(this);
409    }
410
411    @Override
412    public HandlerRegistration addDragEndHandler(final DragEndEvent.DragEndHandler handler) {
413        return addHandler(new DragEndEvent.DragEndHandler() {
414            @Override
415            public void onDragEnd(DragEndEvent event) {
416                if(isEnabled()){
417                    handler.onDragEnd(event);
418                }
419            }
420        }, DragEndEvent.TYPE);
421    }
422
423    @Override
424    public void fireDragEndEvent() {
425        DragEndEvent.fire(this);
426    }
427
428    @Override
429    public HandlerRegistration addDragEnterHandler(final DragEnterEvent.DragEnterHandler handler) {
430        return addHandler(new DragEnterEvent.DragEnterHandler() {
431            @Override
432            public void onDragEnter(DragEnterEvent event) {
433                if(isEnabled()){
434                    handler.onDragEnter(event);
435                }
436            }
437        }, DragEnterEvent.TYPE);
438    }
439
440    @Override
441    public void fireDragEnterEvent() {
442        DragEnterEvent.fire(this);
443    }
444
445    @Override
446    public HandlerRegistration addDragOverHandler(final DragOverEvent.DragOverHandler handler) {
447        return addHandler(new DragOverEvent.DragOverHandler() {
448            @Override
449            public void onDragOver(DragOverEvent event) {
450                if(isEnabled()){
451                    handler.onDragOver(event);
452                }
453            }
454        }, DragOverEvent.TYPE);
455    }
456
457    @Override
458    public void fireDragOverEvent() {
459        DragOverEvent.fire(this);
460    }
461
462    @Override
463    public HandlerRegistration addDragLeaveHandler(final DragLeaveEvent.DragLeaveHandler handler) {
464        return addHandler(new DragLeaveEvent.DragLeaveHandler() {
465            @Override
466            public void onDragLeave(DragLeaveEvent event) {
467                if(isEnabled()){
468                    handler.onDragLeave(event);
469                }
470            }
471        }, DragLeaveEvent.TYPE);
472    }
473
474    @Override
475    public void fireDragLeaveEvent() {
476        DragLeaveEvent.fire(this);
477    }
478
479    @Override
480    public HandlerRegistration addAddedFileHandler(final AddedFileEvent.AddedFileHandler<UploadFile> handler) {
481        return addHandler(new AddedFileEvent.AddedFileHandler<UploadFile>() {
482            @Override
483            public void onAddedFile(AddedFileEvent<UploadFile> event) {
484                if(isEnabled()){
485                    handler.onAddedFile(event);
486                }
487            }
488        }, AddedFileEvent.getType());
489    }
490
491    @Override
492    public void fireAddedFileEvent(String fileName, String lastModified, String size, String type) {
493        AddedFileEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type));
494    }
495
496    @Override
497    public HandlerRegistration addRemovedFileHandler(final RemovedFileEvent.RemovedFileHandler<UploadFile> handler) {
498        return addHandler(new RemovedFileEvent.RemovedFileHandler<UploadFile>() {
499            @Override
500            public void onRemovedFile(RemovedFileEvent<UploadFile> event) {
501                if(isEnabled()){
502                    handler.onRemovedFile(event);
503                }
504            }
505        }, RemovedFileEvent.getType());
506    }
507
508    @Override
509    public void fireRemovedFileEvent(String fileName, String lastModified, String size, String type) {
510        RemovedFileEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type));
511    }
512
513    @Override
514    public HandlerRegistration addErrorHandler(final ErrorEvent.ErrorHandler<UploadFile> handler) {
515        return addHandler(new ErrorEvent.ErrorHandler<UploadFile>() {
516            @Override
517            public void onError(ErrorEvent<UploadFile> event) {
518                if(isEnabled()){
519                    handler.onError(event);
520                }
521            }
522        }, ErrorEvent.getType());
523    }
524
525    @Override
526    public void fireErrorEvent(String fileName, String lastModified, String size, String type, String responseCode, String responseMessage, String responseBody) {
527        ErrorEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type), new UploadResponse(responseCode, responseMessage, responseBody));
528    }
529
530    @Override
531    public HandlerRegistration addUnauthorizedHandler(final UnauthorizedEvent.UnauthorizedHandler<UploadFile> handler) {
532        return addHandler(new UnauthorizedEvent.UnauthorizedHandler<UploadFile>() {
533            @Override
534            public void onUnauthorized(UnauthorizedEvent<UploadFile> event) {
535                if (isEnabled()) {
536                    handler.onUnauthorized(event);
537                }
538            }
539        }, UnauthorizedEvent.getType());
540    }
541
542    @Override
543    public void fireUnauthorizedEvent(String fileName, String lastModified, String size, String type, String responseCode, String responseMessage, String responseBody) {
544        UnauthorizedEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type), new UploadResponse(responseCode, responseMessage, responseBody));
545    }
546
547    @Override
548    public HandlerRegistration addTotalUploadProgressHandler(final TotalUploadProgressEvent.TotalUploadProgressHandler handler) {
549        return addHandler(new TotalUploadProgressEvent.TotalUploadProgressHandler() {
550            @Override
551            public void onTotalUploadProgress(TotalUploadProgressEvent event) {
552                if(isEnabled()){
553                    handler.onTotalUploadProgress(event);
554                }
555            }
556        }, TotalUploadProgressEvent.TYPE);
557    }
558
559    @Override
560    public void fireTotalUploadProgressEvent(double progress) {
561        TotalUploadProgressEvent.fire(this, progress);
562    }
563
564    @Override
565    public HandlerRegistration addSendingHandler(final SendingEvent.SendingHandler<UploadFile> handler) {
566        return addHandler(new SendingEvent.SendingHandler<UploadFile>() {
567            @Override
568            public void onSending(SendingEvent<UploadFile> event) {
569                if(isEnabled()){
570                    handler.onSending(event);
571                }
572            }
573        }, SendingEvent.getType());
574    }
575
576    @Override
577    public void fireSendingEvent(String fileName, String lastModified, String size, String type, String responseCode, String responseMessage) {
578        SendingEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type), new UploadResponse(responseCode, responseMessage));
579    }
580
581    @Override
582    public HandlerRegistration addSuccessHandler(final SuccessEvent.SuccessHandler<UploadFile> handler) {
583        return addHandler(new SuccessEvent.SuccessHandler<UploadFile>() {
584            @Override
585            public void onSuccess(SuccessEvent<UploadFile> event) {
586                if(isEnabled()){
587                    handler.onSuccess(event);
588                }
589            }
590        }, SuccessEvent.getType());
591    }
592
593    @Override
594    public void fireSuccessEvent(String fileName, String lastModified, String size, String type, String responseCode, String responseMessage, String responseBody) {
595        SuccessEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type), new UploadResponse(responseCode, responseMessage, responseBody));
596    }
597
598    @Override
599    public HandlerRegistration addCompleteHandler(final CompleteEvent.CompleteHandler<UploadFile> handler) {
600        return addHandler(new CompleteEvent.CompleteHandler<UploadFile>() {
601            @Override
602            public void onComplete(CompleteEvent<UploadFile> event) {
603                if(isEnabled()){
604                    handler.onComplete(event);
605                }
606            }
607        }, CompleteEvent.getType());
608    }
609
610    @Override
611    public void fireCompleteEvent(String fileName, String lastModified, String size, String type, String responseCode, String responseMessage, String responseBody) {
612        CompleteEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type), new UploadResponse(responseCode, responseMessage, responseBody));
613    }
614
615    @Override
616    public HandlerRegistration addCancelHandler(final CanceledEvent.CanceledHandler<UploadFile> handler) {
617        return addHandler(new CanceledEvent.CanceledHandler<UploadFile>() {
618            @Override
619            public void onCanceled(CanceledEvent<UploadFile> event) {
620                if(isEnabled()){
621                    handler.onCanceled(event);
622                }
623            }
624        }, CanceledEvent.getType());
625    }
626
627    @Override
628    public void fireCancelEvent(String fileName, String lastModified, String size, String type) {
629        CanceledEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type));
630    }
631
632    @Override
633    public HandlerRegistration addMaxFilesReachHandler(final MaxFilesReachedEvent.MaxFilesReachedHandler<UploadFile> handler) {
634        return addHandler(new MaxFilesReachedEvent.MaxFilesReachedHandler<UploadFile>() {
635            @Override
636            public void onMaxFilesReached(MaxFilesReachedEvent<UploadFile> event) {
637                if(isEnabled()){
638                    handler.onMaxFilesReached(event);
639                }
640            }
641        }, MaxFilesReachedEvent.getType());
642    }
643
644    @Override
645    public void fireMaxFilesReachEvent(String fileName, String lastModified, String size, String type) {
646        MaxFilesReachedEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type));
647    }
648
649    @Override
650    public HandlerRegistration addMaxFilesExceededHandler(final MaxFilesExceededEvent.MaxFilesExceededHandler<UploadFile> handler) {
651        return addHandler(new MaxFilesExceededEvent.MaxFilesExceededHandler<UploadFile>() {
652            @Override
653            public void onMaxFilesExceeded(MaxFilesExceededEvent<UploadFile> event) {
654                if(isEnabled()){
655                    handler.onMaxFilesExceeded(event);
656                }
657            }
658        }, MaxFilesExceededEvent.getType());
659    }
660
661    public String getClickable() {
662        return clickable;
663    }
664
665    public void setClickable(String clickable) {
666        this.clickable = clickable;
667    }
668
669    @Override
670    public void fireMaxFilesExceededEvent(String fileName, String lastModified, String size, String type) {
671        MaxFilesReachedEvent.fire(this, new UploadFile(fileName, new Date(lastModified), Double.parseDouble(size), type));
672    }
673
674    public boolean isPreview() {
675        return preview;
676    }
677
678    public void setPreview(boolean preview) {
679        this.preview = preview;
680    }
681
682    /**
683     * Check wether the component has been initialized
684     * @return
685     */
686    public boolean isInitialize() {
687        return initialize;
688    }
689
690    /**
691     * Set the initialization of the component
692     * @param initialize
693     */
694    public void setInitialize(boolean initialize) {
695        this.initialize = initialize;
696    }
697}