This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch wicket-8.x
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/wicket-8.x by this push:
     new 47ab2fe  [WICKET-6876] add an AJAX behavior to transfer client side 
files information to server side (when a file/files is/are selected for upload 
at client side).
47ab2fe is described below

commit 47ab2fe7f8ffa66d4cb3340fb7d5ed72df473d2e
Author: reiern70 <[email protected]>
AuthorDate: Thu Apr 8 08:09:02 2021 +0300

    [WICKET-6876] add an AJAX behavior to transfer client side files 
information to server side (when a file/files is/are selected for upload at 
client side).
    
    (cherry picked from commit b3d911ee33cea32a99fed285fc46bb6a11be5ea9)
---
 .../markup/html/form/upload/FileDescription.java   |  76 ++++
 .../html/form/upload/FilesSelectedBehavior.java    | 130 +++++++
 .../html/form/upload/FilesSelectedBehavior.js      |  78 ++++
 ...eUploadPage$MultipleFileUploadsSamplePanel.html |  37 ++
 ...FileUploadPage$SingleFileUploadSamplePanel.html |  25 ++
 .../examples/ajax/builtin/FileUploadPage.html      |  20 +-
 .../examples/ajax/builtin/FileUploadPage.java      | 393 ++++++++++++++++-----
 7 files changed, 664 insertions(+), 95 deletions(-)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FileDescription.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FileDescription.java
new file mode 100644
index 0000000..5e44cb7
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FileDescription.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.upload;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Objects;
+import com.github.openjson.JSONObject;
+
+/**
+ * Description of file properties as in browser client side.
+ */
+public class FileDescription implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final String fileName;
+    private final long fileSize;
+    private final Date lastModified;
+    private final String mimeType;
+
+   public FileDescription(JSONObject jsonObject) {
+        this(jsonObject.getString("fileName"), jsonObject.getLong("fileSize"),
+                jsonObject.getLong("lastModified"), 
jsonObject.getString("mimeType"));
+    }
+
+    public FileDescription(String fileName, long fileSize, long lastModified, 
String mimeType) {
+        this.fileName = fileName;
+        this.fileSize = fileSize;
+        this.lastModified = new Date(lastModified);
+        this.mimeType = mimeType;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public long getFileSize() {
+        return fileSize;
+    }
+
+    public Date getLastModified() {
+        return lastModified;
+    }
+
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        FileDescription that = (FileDescription) o;
+        return fileName.equals(that.fileName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(fileName);
+    }
+}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FilesSelectedBehavior.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FilesSelectedBehavior.java
new file mode 100644
index 0000000..5328abd
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FilesSelectedBehavior.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.upload;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.wicket.Component;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.attributes.IAjaxCallListener;
+import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.request.IRequestParameters;
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.string.StringValue;
+import org.danekja.java.util.function.serializable.SerializableBiConsumer;
+import com.github.openjson.JSONArray;
+import com.github.openjson.JSONObject;
+
+/**
+ * {@link org.apache.wicket.ajax.form.OnChangeAjaxBehavior} that streams back 
to server properties
+ * of the selected file(s) (at client side), before uploading it (them).
+ *
+ * @author Ernesto Reinaldo Barreiro ([email protected]).
+ */
+public abstract class FilesSelectedBehavior extends OnChangeAjaxBehavior {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final ResourceReference JS = new 
JavaScriptResourceReference(FilesSelectedBehavior.class, 
"FilesSelectedBehavior.js");
+
+    @Override
+    protected void onBind() {
+        super.onBind();
+        Component component = getComponent();
+        if (!(component instanceof FileUploadField)) {
+            throw new WicketRuntimeException("Behavior " + getClass().getName()
+                    + " can only be added to an instance of a 
FileUploadField");
+        }
+    }
+
+    @Override
+    protected void onUpdate(AjaxRequestTarget target) {
+        Request request = RequestCycle.get().getRequest();
+        List<FileDescription> fileDescriptions = new ArrayList<>();
+        IRequestParameters parameters = request.getRequestParameters();
+        // data is streamed as JSON.
+        StringValue fileInfos = parameters.getParameterValue("fileInfos");
+        JSONArray jsonArray = new JSONArray(fileInfos.toString());
+        for (int i = 0; i < jsonArray.length(); i++)
+        {
+            fileDescriptions.add(new 
FileDescription((JSONObject)jsonArray.get(i)));
+        }
+        onSelected(target, fileDescriptions);
+    }
+
+
+    /**
+     * Called when a file, at client side is selected.
+     *
+     * @param target           The {@link 
org.apache.wicket.ajax.AjaxRequestTarget}
+     * @param fileDescriptions A list of FileDescription
+     */
+    protected abstract void onSelected(AjaxRequestTarget target, 
List<FileDescription> fileDescriptions);
+
+    @Override
+    protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
+    {
+        super.updateAjaxAttributes(attributes);
+        attributes.getAjaxCallListeners().add(new IAjaxCallListener()
+        {
+            @Override
+            public CharSequence getPrecondition(Component component)
+            {
+                return "return Wicket.FilesSelected.precondition(this);";
+            }
+        });
+        attributes.getDynamicExtraParameters().add("return 
Wicket.FilesSelected.collectFilesDetails('" + getComponent().getMarkupId() + 
"');");
+    }
+
+    @Override
+    public void renderHead(Component component, IHeaderResponse response)
+    {
+        super.renderHead(component, response);
+        response.render(JavaScriptHeaderItem.forReference(JS));
+    }
+
+    /**
+     * Creates an {@link FilesSelectedBehavior} based on lambda expressions
+     *
+     * @param select {@link SerializableBiConsumer}
+     *
+     * @return the {@link FilesSelectedBehavior} behavior
+     */
+    public static FilesSelectedBehavior onSelected(
+            SerializableBiConsumer<AjaxRequestTarget, List<FileDescription>> 
select)
+    {
+        Args.notNull(select, "select");
+
+        return new FilesSelectedBehavior()
+        {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected void onSelected(AjaxRequestTarget target, 
List<FileDescription> fileDescriptions) {
+                select.accept(target, fileDescriptions);
+            }
+        };
+    }
+}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FilesSelectedBehavior.js
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FilesSelectedBehavior.js
new file mode 100644
index 0000000..df89e8b
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/FilesSelectedBehavior.js
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+;(function (undefined) {
+
+    'use strict';
+
+    if (typeof(Wicket.FilesSelected) === 'object') {
+        return;
+    }
+
+    /**
+     * Contains JS code for FilesSelectedBehavior.
+     */
+    Wicket.FilesSelected = {
+
+        // the id of temporary object holding files.
+        varId: function (componentId) {
+            return componentId + "_files";
+        },
+
+        /**
+         * Precondition to trigger (or not) server round-trip.
+         *
+         * @param inputField the file input field
+         * @returns {boolean} true if some files (file) were (was) selected,
+         */
+        precondition : function (inputField) {
+            if (inputField.files && inputField.files.length > 0) {
+                var id = this.varId(inputField.id);
+                Wicket.FilesSelected[id] = inputField.files;
+                return true;
+            }
+            return false;
+        },
+
+        /**
+         * Collects selected files details
+         *
+         * @param componentId The id of file upload input field.
+         *
+         * @returns array with file infos.
+         */
+        collectFilesDetails: function(componentId) {
+            var id = this.varId(componentId);
+            var sources = Wicket.FilesSelected[id];
+            var files = [];
+            for (var i = 0; i < sources.length; i++) {
+                var file = sources[i];
+                var info = {
+                    'fileName': file.name,
+                    'fileSize': file.size,
+                    'lastModified': file.lastModified,
+                    'mimeType': file.type
+                }
+                files.push(info);
+            }
+            // clean temporary holder object
+            delete(Wicket.FilesSelected[id]);
+            // return information about selected files.
+            return {'fileInfos': JSON.stringify(files)};
+        }
+    };
+})();
\ No newline at end of file
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage$MultipleFileUploadsSamplePanel.html
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage$MultipleFileUploadsSamplePanel.html
new file mode 100644
index 0000000..201fda4
--- /dev/null
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage$MultipleFileUploadsSamplePanel.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+<head>
+    <wicket:head>
+        <script type="text/css">
+            table.files {
+                width: 1000px;
+                display: table;
+            }
+            table.files tbody {
+                width: 100%;
+            }
+            table.files td {
+                width: 25%;
+            }
+        </script>
+    </wicket:head>
+</head>
+<body>
+<wicket:panel>
+    <h2>Uploading a multiple files</h2>
+
+    <div wicket:id="feedback"></div>
+
+    <form wicket:id="form">
+        Text field: <input wicket:id="text" type="text"/><br/>
+        File field (can select multiple files): <input wicket:id="file" 
type="file" multiple="multiple"/> (<span wicket:id="max"></span> max)<br/><br/>
+        <br/>
+        <table wicket:id="selectedFileInfo" class="files">
+        </table>
+        <br/>
+        <div wicket:id="progress"></div>
+        <input wicket:id="submit" type="submit" value="Regular Submit"/> 
<input wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/>
+    </form>
+</wicket:panel>
+</body>
+</html>
\ No newline at end of file
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage$SingleFileUploadSamplePanel.html
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage$SingleFileUploadSamplePanel.html
new file mode 100644
index 0000000..1addf8c
--- /dev/null
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage$SingleFileUploadSamplePanel.html
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+<body>
+<wicket:panel>
+
+    <h2>Uploading a single file</h2>
+
+    <div wicket:id="feedback"></div>
+
+    <form wicket:id="form">
+        Text field: <input wicket:id="text" type="text"/><br/>
+        File field: <input wicket:id="file" type="file"/> (<span 
wicket:id="max"></span> max)<br/><br/>
+        <br/>
+        <div wicket:id="selectedFileInfo"></div>
+        <br/>
+        <div wicket:id="progress"></div>
+        <input wicket:id="submit" type="submit" value="Regular Submit"/> 
<input wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/>
+    </form>
+
+    <div wicket:id="drop" class="drop-zone">
+        Drop file here.
+    </div>
+</wicket:panel>
+</body>
+</html>
\ No newline at end of file
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
index 18d2bfb..46f3612 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
@@ -18,21 +18,13 @@
 <body>
 <wicket:extend xmlns:wicket="http://wicket.apache.org";>
 
-Demonstrates Wicket's ability to transparently handle multipart forms via 
AJAX.<br/><br/>The only difference between this example and other non-AJAX 
upload examples is the option to trigger the form submit via an AjaxButton, 
everything else is handled transparently by Wicket.<br/><br/>
+    Demonstrates Wicket's ability to transparently handle multipart forms via 
AJAX.<br/><br/>The only difference
+    between this example and other non-AJAX upload examples is the option to 
trigger the form submit via an AjaxButton,
+    everything else is handled transparently by Wicket.<br/><br/>
 
-
-<div wicket:id="feedback"></div>
-
-<form wicket:id="form">
-       Text field: <input wicket:id="text" type="text"/><br/>
-       File field: <input wicket:id="file" type="file"/> (<span 
wicket:id="max"></span> max)<br/><br/>
-       <div wicket:id="progress"></div>
-       <input type="submit" value="Regular Submit"/> <input 
wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/>
-</form>
-
-<div wicket:id="drop" class="drop-zone">
-       Drop file here.
-</div>
+    <div wicket:id="singleFileUpload"></div>
+    <br/>
+    <div wicket:id="multipleFileUpload"></div>
 
 </wicket:extend>
 </body>
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
index c7f25fb..a84b45b 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
@@ -16,21 +16,33 @@
  */
 package org.apache.wicket.examples.ajax.builtin;
 
+import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
+import org.apache.commons.collections4.iterators.EmptyIterator;
 import org.apache.commons.fileupload.FileUploadException;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.extensions.ajax.AjaxFileDropBehavior;
 import 
org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
+import 
org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import 
org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import 
org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Button;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.form.upload.FileDescription;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.markup.html.form.upload.FileUploadField;
+import org.apache.wicket.markup.html.form.upload.FilesSelectedBehavior;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.util.lang.Bytes;
 import org.apache.wicket.validation.validator.StringValidator;
@@ -44,115 +56,334 @@ public class FileUploadPage extends BasePage
 {
        private static final long serialVersionUID = 1L;
 
-       private final FileUploadField file;
-       private final TextField<String> text;
+       private static class SingleFileUploadSamplePanel extends Panel {
 
-       /**
-        * Constructor
-        */
-       public FileUploadPage()
-       {
+               private final FileUploadField file;
+               private final TextField<String> text;
+               private final Label selectedFileInfo;
+               private final AjaxButton ajaxSubmit;
+               private final Button submit;
+               private String fileInfo;
 
-               // create a feedback panel
-               final Component feedback = new 
FeedbackPanel("feedback").setOutputMarkupId(true);
-               add(feedback);
+               public SingleFileUploadSamplePanel(String id) {
+                       super(id);
 
-               // create the form
-               final Form<?> form = new Form<Void>("form")
-               {
-                       private static final long serialVersionUID = 1L;
+                       // create a feedback panel
+                       final Component feedback = new 
FeedbackPanel("feedback").setOutputMarkupId(true);
+                       add(feedback);
 
-                       @Override
-                       protected void onSubmit()
+                       // create the form
+                       final Form<?> form = new Form<Void>("form")
                        {
-                               // display uploaded info
-                               info("Text: " + text.getModelObject());
-                               FileUpload upload = file.getFileUpload();
-                               if (upload == null)
+                               private static final long serialVersionUID = 1L;
+
+                               @Override
+                               protected void onSubmit()
                                {
-                                       info("No file uploaded");
+                                       // display uploaded info
+                                       info("Text: " + text.getModelObject());
+                                       FileUpload upload = 
file.getFileUpload();
+                                       if (upload == null)
+                                       {
+                                               info("No file uploaded");
+                                       }
+                                       else
+                                       {
+                                               info("File-Name: " + 
upload.getClientFileName() + " File-Size: " +
+                                                               
Bytes.bytes(upload.getSize()).toString());
+                                       }
                                }
-                               else
+                       };
+                       form.setMaxSize(Bytes.megabytes(1));
+                       add(form);
+
+                       // create a textfield to demo non-file content
+                       form.add(text = new TextField<>("text", Model.of()));
+                       text.add(StringValidator.minimumLength(2));
+
+                       // create the file upload field
+                       form.add(file = new FileUploadField("file"));
+
+                       add(selectedFileInfo = new Label("selectedFileInfo", 
(IModel<String>) () -> fileInfo) {
+                               @Override
+                               protected void onAfterRender() {
+                                       super.onAfterRender();
+                                       fileInfo = null;
+                               }
+                       });
+                       selectedFileInfo.setOutputMarkupId(true);
+                       form.add(selectedFileInfo);
+
+                       form.add(new Label("max", form::getMaxSize));
+
+                       form.add(new UploadProgressBar("progress", form, file));
+
+                       // create a submit button
+                       form.add(submit = new Button("submit"));
+                       submit.setOutputMarkupId(true);
+
+                       // create the ajax button used to submit the form
+                       form.add(ajaxSubmit = new AjaxButton("ajaxSubmit")
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               /**
+                                * Need to trigger submit to initiate 
progressbar.
+                                */
+                               @Override
+                               protected boolean 
shouldTriggerJavaScriptSubmitEvent()
                                {
-                                       info("File-Name: " + 
upload.getClientFileName() + " File-Size: " +
-                                               
Bytes.bytes(upload.getSize()).toString());
+                                       return true;
                                }
-                       }
-               };
-               form.setMaxSize(Bytes.megabytes(1));
-               add(form);
 
-               // create a textfield to demo non-file content
-               form.add(text = new TextField<>("text", Model.of()));
-               text.add(StringValidator.minimumLength(2));
+                               @Override
+                               protected void onSubmit(AjaxRequestTarget 
target)
+                               {
+                                       info("This request was processed using 
AJAX");
+
+                                       // ajax-update the feedback panel
+                                       target.add(feedback);
+                               }
+
+                               @Override
+                               protected void onError(AjaxRequestTarget target)
+                               {
+                                       // update feedback to display errors
+                                       target.add(feedback);
+                               }
+
+                       });
+                       ajaxSubmit.setOutputMarkupId(true);
 
-               // create the file upload field
-               form.add(file = new FileUploadField("file"));
+                       file.add(FilesSelectedBehavior.onSelected(
+                                       (AjaxRequestTarget target, 
List<FileDescription> fileDescriptions)->
+                                       {
+                                               FileDescription fileDescription 
= fileDescriptions.get(0);
+                                               Bytes bytes = 
Bytes.bytes(fileDescription.getFileSize());
+                                               fileInfo = "File " + 
fileDescription.getFileName() +
+                                                               " (with size " 
+ bytes + ") was selected at client side. "
+                                                               + "File was 
last modified at: " + fileDescription.getLastModified()
+                                                               + " and is of 
type " + fileDescription.getMimeType() +
+                                                               ". It has not 
been uploaded yet. ";
+                                               if 
(bytes.greaterThan(form.getMaxSize()))
+                                               {
+                                                       fileInfo += " File 
exceeds max allowed size.";
+                                                       // disable buttons as 
file is not valid
+                                                       
submit.setEnabled(false);
+                                                       
ajaxSubmit.setEnabled(false);
+                                               }
+                                               else
+                                               {
+                                                       fileInfo += " You can 
click on buttons bellow in order to upload it.";
+                                                       // enable buttons as 
file is valid
+                                                       submit.setEnabled(true);
+                                                       
ajaxSubmit.setEnabled(true);
+                                               }
+                                               target.add(selectedFileInfo, 
submit, ajaxSubmit);
+                                       }));
+                       WebMarkupContainer drop = new 
WebMarkupContainer("drop");
+                       drop.add(new AjaxFileDropBehavior() {
+                               protected void onFileUpload(AjaxRequestTarget 
target, List<FileUpload> files) {
 
-               form.add(new Label("max", form::getMaxSize));
+                                       // display uploaded info
+                                       if (files == null || files.isEmpty())
+                                       {
+                                               info("No file uploaded");
+                                       }
+                                       else
+                                       {
+                                               for (FileUpload file : files) {
+                                                       info("File-Name: " + 
file.getClientFileName() + " File-Size: " +
+                                                                       
Bytes.bytes(file.getSize()).toString());
+                                               }
+                                       }
 
-               form.add(new UploadProgressBar("progress", form, file));
+                                       target.add(feedback);
+                               }
+
+                               @Override
+                               protected void onError(AjaxRequestTarget 
target, FileUploadException fux)
+                               {
+                                       info(fux.getMessage());
+
+                                       target.add(feedback);
+                               }
+                       });
+                       add(drop);
+               }
+       }
 
-               // create the ajax button used to submit the form
-               form.add(new AjaxButton("ajaxSubmit")
-               {
-                       private static final long serialVersionUID = 1L;
+       private static class MultipleFileUploadsSamplePanel extends Panel {
+
+               private static class DataProvider extends 
SortableDataProvider<FileDescription, String> {
+
+                       private List<FileDescription> fileDescriptions;
+
+                       public void setFileDescriptions(List<FileDescription> 
fileDescriptions) {
+                               this.fileDescriptions = new 
ArrayList<>(fileDescriptions);
+                       }
 
-                       /**
-                        * Need to trigger submit to initiate progressbar. 
-                        */
                        @Override
-                       protected boolean shouldTriggerJavaScriptSubmitEvent()
-                       {
-                               return true;
+                       public Iterator<? extends FileDescription> 
iterator(long first, long count) {
+                               if (this.fileDescriptions == null) {
+                                       return EmptyIterator.emptyIterator();
+                               }
+                               return fileDescriptions.listIterator();
                        }
-                       
+
                        @Override
-                       protected void onSubmit(AjaxRequestTarget target)
-                       {
-                               info("This request was processed using AJAX");
+                       public long size() {
+                               if (this.fileDescriptions == null) {
+                                       return 0L;
+                               }
+                               return this.fileDescriptions.size();
+                       }
 
-                               // ajax-update the feedback panel
-                               target.add(feedback);
+                       @Override
+                       public IModel<FileDescription> model(FileDescription 
object) {
+                               return Model.of(object);
                        }
 
                        @Override
-                       protected void onError(AjaxRequestTarget target)
-                       {
-                               // update feedback to display errors
-                               target.add(feedback);
+                       public void detach() {
+                               super.detach();
+                               this.fileDescriptions = null;
                        }
+               }
+
+               private final FileUploadField file;
+               private final TextField<String> text;
+               private DataProvider dataProvider;
+               private AjaxFallbackDefaultDataTable<FileDescription, String> 
selectedFileInfo;
+               private final AjaxButton ajaxSubmit;
+               private final Button submit;
 
-               });
-               
-               WebMarkupContainer drop = new WebMarkupContainer("drop");
-               drop.add(new AjaxFileDropBehavior() {
-                       protected void onFileUpload(AjaxRequestTarget target, 
List<FileUpload> files) {
-                           
-                               // display uploaded info
-                               if (files == null || files.isEmpty())
+               public MultipleFileUploadsSamplePanel(String id) {
+                       super(id);
+
+                       // create a feedback panel
+                       final Component feedback = new 
FeedbackPanel("feedback").setOutputMarkupId(true);
+                       add(feedback);
+
+                       // create the form
+                       final Form<?> form = new Form<Void>("form")
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               @Override
+                               protected void onSubmit()
                                {
-                                       info("No file uploaded");
+                                       // display uploaded info
+                                       info("Text: " + text.getModelObject());
+                                       FileUpload upload = 
file.getFileUpload();
+                                       if (upload == null)
+                                       {
+                                               info("No file uploaded");
+                                       }
+                                       else
+                                       {
+                                               info("File-Name: " + 
upload.getClientFileName() + " File-Size: " +
+                                                               
Bytes.bytes(upload.getSize()).toString());
+                                       }
                                }
-                               else
+                       };
+                       form.setMaxSize(Bytes.megabytes(1));
+                       add(form);
+
+                       List<IColumn<FileDescription, String>> columns = new 
ArrayList<>();
+                       columns.add(new PropertyColumn<>(Model.of("File Name"), 
"fileName"));
+                       columns.add(new PropertyColumn<>(Model.of("Size"), 
"fileSize"));
+                       columns.add(new PropertyColumn<>(Model.of("Last 
Modified"), "lastModified"));
+                       columns.add(new PropertyColumn<>(Model.of("MIME Type"), 
"mimeType"));
+                       selectedFileInfo = new 
AjaxFallbackDefaultDataTable<>("selectedFileInfo", columns, dataProvider = new 
DataProvider(), 100) {
+                               @Override
+                               protected void onConfigure() {
+                                       super.onConfigure();
+                                       setVisible(dataProvider.size() > 0);
+                               }
+                       };
+                       form.add(selectedFileInfo);
+                       selectedFileInfo.setOutputMarkupPlaceholderTag(true);
+
+                       // create a textfield to demo non-file content
+                       form.add(text = new TextField<>("text", Model.of()));
+                       text.add(StringValidator.minimumLength(2));
+
+                       // create the file upload field
+                       form.add(file = new FileUploadField("file"));
+
+                       form.add(new Label("max", form::getMaxSize));
+
+                       form.add(new UploadProgressBar("progress", form, file));
+
+                       // create a submit button
+                       form.add(submit = new Button("submit"));
+                       submit.setOutputMarkupId(true);
+
+                       // create the ajax button used to submit the form
+                       form.add(ajaxSubmit = new AjaxButton("ajaxSubmit")
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               /**
+                                * Need to trigger submit to initiate 
progressbar.
+                                */
+                               @Override
+                               protected boolean 
shouldTriggerJavaScriptSubmitEvent()
                                {
-                                   for (FileUpload file : files) {
-                                       info("File-Name: " + 
file.getClientFileName() + " File-Size: " +
-                                               
Bytes.bytes(file.getSize()).toString());
-                                   }
+                                       return true;
                                }
-                               
-                               target.add(feedback);
-                       }
-                       
-                       @Override
-                       protected void onError(AjaxRequestTarget target, 
FileUploadException fux)
+
+                               @Override
+                               protected void onSubmit(AjaxRequestTarget 
target)
+                               {
+                                       info("This request was processed using 
AJAX");
+
+                                       // ajax-update the feedback panel
+                                       target.add(feedback);
+                               }
+
+                               @Override
+                               protected void onError(AjaxRequestTarget target)
+                               {
+                                       // update feedback to display errors
+                                       target.add(feedback);
+                               }
+
+                       });
+                       ajaxSubmit.setOutputMarkupId(true);
+                       file.add(FilesSelectedBehavior.onSelected(
+                                       (AjaxRequestTarget target, 
List<FileDescription> fileDescriptions) ->
                        {
-                               info(fux.getMessage());
-                               
-                               target.add(feedback);                           
-                       }
-               });
-               add(drop);
+                               
dataProvider.setFileDescriptions(fileDescriptions);
+                               Bytes bytes = 
Bytes.bytes(fileDescriptions.stream().mapToLong(FileDescription::getFileSize).sum());
+                               if (bytes.greaterThan(form.getMaxSize()))
+                               {
+                                       form.error("Total file size exceeds max 
allowed size.");
+                                       // disable buttons as file is not valid
+                                       submit.setEnabled(false);
+                                       ajaxSubmit.setEnabled(false);
+                               }
+                               else
+                               {
+                                       form.info("You can click on buttons 
bellow in order to upload selected files.");
+                                       // enable buttons as file is valid
+                                       submit.setEnabled(true);
+                                       ajaxSubmit.setEnabled(true);
+                               }
+                               target.add(selectedFileInfo, submit, 
ajaxSubmit, feedback);
+                       }));
+               }
+       }
+       /**
+        * Constructor
+        */
+       public FileUploadPage()
+       {
+               // sample of a single uploaded file.
+               add(new SingleFileUploadSamplePanel("singleFileUpload"));
+               add(new MultipleFileUploadsSamplePanel("multipleFileUpload"));
+
+
        }
 }

Reply via email to