Following example shows how to use an AJAX request to refresh some components and at the same time make the browser ask back for a file to be downloaded:
final AJAXDownload download = new AJAXDownload()
{
@Override
protected IResourceStream getResourceStream()
{
return createResourceStream(item.getModelObject());
}
};
item.add(download);
item.add(new AjaxLink<Void>("link") {
@Override
public void onClick(AjaxRequestTarget target)
{
// do whatever with the target, e.g. refresh components
target.add(...);
// finally initiate the download
download.initiate(target);
}
});
|
We have to add a custom behavior which enables us to initiate the download after the AJAX request has been completed. The overridden hook method provides an IResourceStream (e.g. a FileResourceStream) to serve the actual content.
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AbstractAjaxBehavior;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.util.resource.IResourceStream;
/**
* @author Sven Meier
* @author Ernesto Reinaldo Barreiro (reiern70@gmail.com)
* @author Jordi Deu-Pons (jordi@jordeu.net)
*/
public abstract class AJAXDownload extends AbstractAjaxBehavior
{
private boolean addAntiCache;
public AJAXDownload() {
this(true);
}
public AJAXDownload(boolean addAntiCache) {
super();
this.addAntiCache = addAntiCache;
}
/**
* Call this method to initiate the download.
*/
public void initiate(AjaxRequestTarget target)
{
String url = getCallbackUrl().toString();
if (addAntiCache) {
url = url + (url.contains("?") ? "&" : "?");
url = url + "antiCache=" + System.currentTimeMillis();
}
// the timeout is needed to let Wicket release the channel
target.appendJavaScript("setTimeout(\"window.location.href='" + url + "'\", 100);");
}
public void onRequest()
{
ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(getResourceStream(),getFileName());
handler.setContentDisposition(ContentDisposition.ATTACHMENT);
getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
}
/**
* Override this method for a file name which will let the browser prompt with a save/open dialog.
* @see ResourceStreamRequestTarget#getFileName()
*/
protected String getFileName()
{
return null;
}
/**
* Hook method providing the actual resource stream.
*/
protected abstract IResourceStream getResourceStream();
}
|