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"));
+
+
}
}