13

I know that it is really easy to create a FileDownloader and call extend with a Button. But how do I start a download without the Button?
In my specific situation right now I have a ComboBox and the file I'd like to send to the user is generated after changing its value, based on the input. The file should be sent immediately without waiting for another click. Is that easily possible?

Thanks raffael

raffael
  • 2,427
  • 4
  • 26
  • 42
  • The problem with the hidden button is, that this does not work on devices with iOS. I'd rather use MenuBar and MenuItem, but this is not yet supported by Vaadin - see [Github issue #4057](https://github.com/vaadin/framework/issues/4057). And the suggested workaround when using MenuBar and MenuItem would result in using hidden buttons ... – bingele28 Mar 14 '18 at 07:51

2 Answers2

15

I found a solution myself. Actually two. The first one uses the deprecated method Page.open()

public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();

public DownloadComponent() {
    cb.addValueChangeListener(this);
    cb.setNewItemsAllowed(true);
    cb.setImmediate(true);
    cb.setNullSelectionAllowed(false);
    setCompositionRoot(cb);
}

@Override
public void valueChange(ValueChangeEvent event) {
    String val = (String) event.getProperty().getValue();
    FileResource res = new FileResource(new File(val));
    Page.getCurrent().open(res, null, false);
}
}

The javadoc here mentions some memory and security problems as reason for marking it deprecated


In the second I try to go around this deprecated method by registering the resource in the DownloadComponent. I'd be glad if a vaadin expert comments this solution.

public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();
private static final String MYKEY = "download";

public DownloadComponent() {
    cb.addValueChangeListener(this);
    cb.setNewItemsAllowed(true);
    cb.setImmediate(true);
    cb.setNullSelectionAllowed(false);
    setCompositionRoot(cb);
}

@Override
public void valueChange(ValueChangeEvent event) {
    String val = (String) event.getProperty().getValue();
    FileResource res = new FileResource(new File(val));
    setResource(MYKEY, res);
    ResourceReference rr = ResourceReference.create(res, this, MYKEY);
    Page.getCurrent().open(rr.getURL(), null);
}
}

Note: I do not really allow the user to open all my files on the server and you should not do that either. It is just for demonstration.

raffael
  • 2,427
  • 4
  • 26
  • 42
7

Here is my work-around. It works like a charm for me. Hope it will help you.

  1. Create a button and hide it by Css (NOT by code: button.setInvisible(false))

    final Button downloadInvisibleButton = new Button();
    downloadInvisibleButton.setId("DownloadButtonId");
    downloadInvisibleButton.addStyleName("InvisibleButton");
    

    In your theme, add this rule to hide the downloadInvisibleButton:

    .InvisibleButton {
        display: none;
    }
    
  2. When the user clicks on menuItem: extend the fileDownloader to the downloadInvisibleButton, then simulate the click on the downloadInvisibleButton by JavaScript.

    menuBar.addItem("Download", new MenuBar.Command() {
      @Override
      public void menuSelected(MenuBar.MenuItem selectedItem) {
        FileDownloader fileDownloader = new FileDownloader(...);
        fileDownloader.extend(downloadInvisibleButton);
        //Simulate the click on downloadInvisibleButton by JavaScript
        Page.getCurrent().getJavaScript()
           .execute("document.getElementById('DownloadButtonId').click();");
      }
    });
    
Nhat Nam NGUYEN
  • 1,252
  • 11
  • 15
  • imho this is not working cause every click on the same item will add an extension for the invisibleButton and therefore it will fire one dowload first time, but two download the second...and so on.. – Lorenzo Sciuto Jun 09 '15 at 10:21
  • 1
    Lorenzo: Before calling extend(), you need to remove all old extensions of the button. – Nhat Nam NGUYEN Jun 09 '15 at 12:09