1

Brief question first: How can I show an upload error message in the same style of all the other input fields?

Details: Vaadin 14.1.5 offers an upload-element: https://vaadin.com/components/vaadin-upload/java-examples

I created an upload field with this code:

 MemoryBuffer buffer = new MemoryBuffer(); Upload upload = new Upload(buffer); 

A failure message for too large file size is enforce by this line:

 upload.setMaxFileSize(1); 

Translation is done with UploadI18N (see https://vaadin.com/api/platform/14.1.5/com/vaadin/flow/component/upload/UploadI18N.html ):

 upload.setI18n(buildMyUploadI18N(Locale.GERMAN)); 

And with all the listeners I can receive and show error messages at server-side, e.g. for rejection:

 upload.addFileRejectedListener(new ComponentEventListener<FileRejectedEvent>() { @Override public void onComponentEvent(FileRejectedEvent event) { Notification.show(event.getErrorMessage()); } }); 

This code works fine and the system shows a notification message to the user when the file to upload is too large.

But: this validation-message-behavior differs from what the user is used to: Red text next to the input field (see screenshot).

validation with binder

How can I show an upload error message in the same style of all the other input fields?

1
  • Hint for the standard error messages "Forbidden" and "File is too large": If you have an nginx between browser and server and that nginx has a smaller max-file-size-limit set as your Upload component, then the nginx max answer an upload request with HTTP status code 413 and then the Upload component shows "Forbidden", though the file is too large (for nginx, not compared with the Upload component limit). See here: vaadin.com/forum/thread/18470457/… Commented Nov 3, 2020 at 20:28

2 Answers 2

2

Another option is to use a Paragraph, as in the example page you have linked. The source code for it could be found here: addRejectedListener

So once rejected listener is called, add a paragraph with a red text and possibly set background of upload to pink(or any other color/style you would like it to have). Below is a simplified version of the approach (You should put styles to a separate css file and set/remove a class to upload)

 import com.vaadin.flow.component.Component; import com.vaadin.flow.component.HasComponents; import com.vaadin.flow.component.HtmlComponent; import com.vaadin.flow.component.Tag; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.Label; import com.vaadin.flow.component.html.Paragraph; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.upload.Upload; import com.vaadin.flow.component.upload.receivers.MemoryBuffer; import com.vaadin.flow.router.Route; @Route("multiuploadView") public class MultiFileUploadView extends VerticalLayout { Div output = new Div(); Upload upload; public MultiFileUploadView(){ MemoryBuffer buffer = new MemoryBuffer(); upload = new Upload(buffer); upload.setMaxFiles(1); upload.setDropLabel(new Label("Upload a 300 bytes file in .csv format")); upload.setAcceptedFileTypes("text/csv"); upload.setMaxFileSize(300); upload.addFileRejectedListener(event -> { Paragraph component = new Paragraph(); showOutput(event.getErrorMessage(), component, output); }); add(upload,output); } private void showOutput(String text, Component content, HasComponents outputContainer) { outputContainer.removeAll(); HtmlComponent p = new HtmlComponent(Tag.P); p.getElement().setText(text); p.getElement().getStyle().set("color","red"); upload.getElement().getStyle().set("background","pink"); outputContainer.add(p); outputContainer.add(content); } } 

And this looks like this: enter image description here

But, otherwise, I would say that your workaround is pretty much what one can do :)

Sign up to request clarification or add additional context in comments.

3 Comments

That's another good workaround. Thanks. :-) Maybe styling could be done with part="error-message" (like with other Vaadin components for the sake of consistency).
My styling now is as follows (like other error messages in 14.1.5 with Lumo) and it looks the same as any other error message: [part="error-message"] { margin-left: calc(var(--lumo-border-radius-m) / 4); font-size: var(--lumo-font-size-xs); line-height: var(--lumo-line-height-xs); color: var(--lumo-error-text-color); will-change: max-height; transition: 0.4s max-height; max-height: 5em; }
How do I undo the error message if the file gets accepted?
0

My current workaround is as follows:

The system creates a disabled Textfield in addition to the Upload-element

 TextField filenameField = new TextField(); filenameField.setEnabled(false); 

Every error listener at the Upload-element then sets the error message at the TextField:

 upload.addFileRejectedListener(new ComponentEventListener<FileRejectedEvent>() { @Override public void onComponentEvent(FileRejectedEvent event) { filenameField.setInvalid(true); filenameField.setErrorMessage(event.getErrorMessage()); } }); 

and

 upload.addFailedListener(new ComponentEventListener<FailedEvent>() { @Override public void onComponentEvent(FailedEvent event) { filenameField.setInvalid(true); filenameField.setErrorMessage(event.getReason().getMessage()); } }); 

and reset invalid-status and set new filename at success:

 upload.addSucceededListener(event -> { filenameField.setValue(StringUtils.trimToEmpty(event.getFileName())); filenameField.setInvalid(false); }); 

This is how it looks like - not my preferred solution (because the filename is not errorneous but the file size), but for the moment this is OK for me:

enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.