Vaadin 14 - 在文件上传时显示错误,就像在任何其他输入字段中一样
Vaadin 14 - Show errors at file upload like at any other input field
先简单提问:
如何以与所有其他输入字段相同的样式显示上传错误消息?
详情:
Vaadin 14.1.5 提供上传元素:https://vaadin.com/components/vaadin-upload/java-examples
我使用以下代码创建了一个上传字段:
MemoryBuffer buffer = new MemoryBuffer();
Upload upload = new Upload(buffer);
此行强制执行文件过大的失败消息:
upload.setMaxFileSize(1);
使用 UploadI18N 完成翻译(参见 https://vaadin.com/api/platform/14.1.5/com/vaadin/flow/component/upload/UploadI18N.html):
upload.setI18n(buildMyUploadI18N(Locale.GERMAN));
通过所有的侦听器,我可以在服务器端接收和显示错误消息,例如拒绝:
upload.addFileRejectedListener(new ComponentEventListener<FileRejectedEvent>() {
@Override
public void onComponentEvent(FileRejectedEvent event) {
Notification.show(event.getErrorMessage());
}
});
这段代码工作正常,当要上传的文件太大时,系统会向用户显示一条通知消息。
但是:此验证消息行为与用户习惯的不同:输入字段旁边的红色文本(见屏幕截图)。
如何以与所有其他输入字段相同的样式显示上传错误消息?
我目前的解决方法如下:
除了上传元素之外,系统还创建了一个禁用的文本字段
TextField filenameField = new TextField();
filenameField.setEnabled(false);
上传元素中的每个错误侦听器然后在 TextField 中设置错误消息:
upload.addFileRejectedListener(new ComponentEventListener<FileRejectedEvent>() {
@Override
public void onComponentEvent(FileRejectedEvent event) {
filenameField.setInvalid(true);
filenameField.setErrorMessage(event.getErrorMessage());
}
});
和
upload.addFailedListener(new ComponentEventListener<FailedEvent>() {
@Override
public void onComponentEvent(FailedEvent event) {
filenameField.setInvalid(true);
filenameField.setErrorMessage(event.getReason().getMessage());
}
});
并在成功时重置无效状态并设置新文件名:
upload.addSucceededListener(event -> {
filenameField.setValue(StringUtils.trimToEmpty(event.getFileName()));
filenameField.setInvalid(false);
});
这是它的样子 - 不是我的首选解决方案(因为文件名不是错误的,而是文件大小),但目前这对我来说没问题:
另一种选择是使用 Paragraph
,如您链接的示例页面中所示。它的源代码可以在这里找到:addRejectedListener
因此,一旦被拒绝的侦听器被调用,添加一个带有红色文本的段落,并可能将上传背景设置为粉红色(或您希望它具有的任何其他 color/style)。下面是该方法的简化版本(您应该将样式放在单独的 css 文件中,并 set/remove 一个 class 上传)
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);
}
}
这看起来像这样:
但是,除此之外,我会说你的解决方法几乎是一个人可以做的:)
先简单提问: 如何以与所有其他输入字段相同的样式显示上传错误消息?
详情: Vaadin 14.1.5 提供上传元素:https://vaadin.com/components/vaadin-upload/java-examples
我使用以下代码创建了一个上传字段:
MemoryBuffer buffer = new MemoryBuffer();
Upload upload = new Upload(buffer);
此行强制执行文件过大的失败消息:
upload.setMaxFileSize(1);
使用 UploadI18N 完成翻译(参见 https://vaadin.com/api/platform/14.1.5/com/vaadin/flow/component/upload/UploadI18N.html):
upload.setI18n(buildMyUploadI18N(Locale.GERMAN));
通过所有的侦听器,我可以在服务器端接收和显示错误消息,例如拒绝:
upload.addFileRejectedListener(new ComponentEventListener<FileRejectedEvent>() {
@Override
public void onComponentEvent(FileRejectedEvent event) {
Notification.show(event.getErrorMessage());
}
});
这段代码工作正常,当要上传的文件太大时,系统会向用户显示一条通知消息。
但是:此验证消息行为与用户习惯的不同:输入字段旁边的红色文本(见屏幕截图)。
如何以与所有其他输入字段相同的样式显示上传错误消息?
我目前的解决方法如下:
除了上传元素之外,系统还创建了一个禁用的文本字段
TextField filenameField = new TextField();
filenameField.setEnabled(false);
上传元素中的每个错误侦听器然后在 TextField 中设置错误消息:
upload.addFileRejectedListener(new ComponentEventListener<FileRejectedEvent>() {
@Override
public void onComponentEvent(FileRejectedEvent event) {
filenameField.setInvalid(true);
filenameField.setErrorMessage(event.getErrorMessage());
}
});
和
upload.addFailedListener(new ComponentEventListener<FailedEvent>() {
@Override
public void onComponentEvent(FailedEvent event) {
filenameField.setInvalid(true);
filenameField.setErrorMessage(event.getReason().getMessage());
}
});
并在成功时重置无效状态并设置新文件名:
upload.addSucceededListener(event -> {
filenameField.setValue(StringUtils.trimToEmpty(event.getFileName()));
filenameField.setInvalid(false);
});
这是它的样子 - 不是我的首选解决方案(因为文件名不是错误的,而是文件大小),但目前这对我来说没问题:
另一种选择是使用 Paragraph
,如您链接的示例页面中所示。它的源代码可以在这里找到:addRejectedListener
因此,一旦被拒绝的侦听器被调用,添加一个带有红色文本的段落,并可能将上传背景设置为粉红色(或您希望它具有的任何其他 color/style)。下面是该方法的简化版本(您应该将样式放在单独的 css 文件中,并 set/remove 一个 class 上传)
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);
}
}
这看起来像这样:
但是,除此之外,我会说你的解决方法几乎是一个人可以做的:)