Issue
I am able to use Upload Component to upload file from page to my file system like below.
return (MultiFileReceiver) (String fileName, String mimeType) -> {
try {
File file = new File(uploadFileDirectory,fileName);
return fileOutputHandlerService.fileOutput(file);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
But when it comes to download that file with given path I can't accomplish that. Only explanation to do that is using Anchor element. but I want to use ContextMenu component to trigger a download . I have a contextmenu Component derived from a Grid
fileListContext = grid.addContextMenu();
fileListContext.addItem("Download",uiListener.fileDownloadRequestListener());
I implemented that context menu listener like below. I want to click that context menu pop up and prompt browser to open save location for user to start download.
private ComponentEventListener <GridContextMenu.GridContextMenuItemClickEvent<FileEntity>> fileDownloadRequestListener(){
//created stream user and anchor element. how to trigger download attribute of anchor?
return selectedFile-> {
StreamResource resource = new StreamResource(selectedFile.getItem().get().getFileName(),
()->fileInputHandlerService.fileInput(selectedFile.getItem().get()));
anchor = new Anchor(resource,"a");
anchor.getElement().setAttribute("download",true);
anchor.setVisible(true);
add(anchor);
};
}
Solution
Just adjust your fileDownloadRequestListener
to this and it should work:
private ComponentEventListener<GridContextMenu.GridContextMenuItemClickEvent<FileEntity>> fileDownloadRequestListener() {
return selectedFile -> {
StreamResource resource = new StreamResource(selectedFile.getItem().get().getFileName(),
() -> fileInputHandlerService.fileInput(selectedFile.getItem().get()));
anchor = new Anchor(resource, "a");
Element element = anchor.getElement();
element.setAttribute("download", true);
// Hide the anchor from the user
element.getStyle().set("display", "none");
add(anchor);
// Trigger click and remove when ready
element.executeJs("return new Promise(resolve =>{this.click(); setTimeout(() => resolve(true), 150)})", element).then(jsonValue -> remove(anchor));
}
Answered By - nailer_boxer
Answer Checked By - David Marino (JavaFixing Volunteer)