I've searched for a while and didn't find a solution, so if it already exists somewhere I apologize.
I currently have a menu being dynamically generated from a database. After the menu is built I want to add a sub menu at the bottom with two reports. One of the reports generates a PDF document to download. I've been able to use the <p:fileDownload/>
tag with a <p:menuitem/>
tag and have been successful.
The problem I'm running into with my dynamic menu is that I'm using a model in the bean to generate it. And I haven't been able to find a way to add the download functionality to a DefaultMenuItem object that is being added to the model. Below is a sample of my code so far (I'm only going to show one report being added to simplify my code. In my example I'll only add one menu item to download a file):
My xhtml:
<h:form id="menu">
<p:menu toggleable="true" tabindex="0" id="screenMenu" model="#{myBean.model}"/>
</h:form>
My Bean:
@ManagedBean(name = "myBean")
@ViewScoped
public class MyBean implements Serializable {
private ArrayList<Menu> menuItems;
private ByteArrayOutputStream output;
private StreamedContent file;
public ArrayList<Menu> getMenuItems(){
return menuItems;
}
public void setMenuItems(ArrayList<Menu> menuItems){
this.menuItems = menuItems;
}
public StreamedContent getFile() {
return file;
}
public void setFile(StreamedContent file) {
this.file = file;
}
public ByteArrayOutputStream getOutput() {
return output;
}
public void setOutput(ByteArrayOutputStream output) {
this.output = output;
}
@PostConstruct
public void init(){
//Code runs here that loads up the list of menu items from database
//Load the model with the returned menu items
DynamicMenuModel model = new DynamicMenuModel();
for(Menu menuItem : menuItems){
DefaultMenuItem item = new DefaultMenuItem(menuItem.getTitle());
item.setParam("screen", menuItem.getScreen());
item.setCommand("#{myBean.selectMenuItem}");
model.addElement(item);
}
//Extra item added to model in order to download file
DefaultMenuItem item = new DefaultMenuItem("Download Report");
item.addCommand("#{myBean.downloadReport}");
/*
*******************************************************************************
***How would I add code to include the <p:fileDownload/> tag functionality??***
*******************************************************************************
*/
model.addElement(item);
}
public void downloadReport(ActionEvent event){
output = new ByteArrayOutputStream();
/*
Code goes here that grabs information and creates a pdf document and
saves it to the output object
*/
ByteArrayInputStream stream = new ByteArrayInputStream(output.toByteArray());
file = new DefaultStreamedContent(stream, "pdf", "report.pdf");
FileDownloadActionListener download = new FileDownloadActionListener();
download.processAction(event); //<--It's not liking this
}
public String selectMenuItem(ActionEvent event){
MenuItem menuItem = ((MenuActionEvent) event).getMenuItem();
String screen = menuItem.getParams().get("screen").get(0);
return "/" + screen + "?faces-redirect=true";
}
}
I've tried making the "downloadReport" method have an ActionEvent parameter and pass that into the processAction() method of a newly created FileDownloadActionListener object, but how that would even work doesn't make sense to me. Thought I'd try it anyway.
Let me know if you need any other information from me. Any syntax errors or anything that would make this code not work is purely from me condensing a bunch of code in the little bit I've shown. Right now it runs fine if I use the <p:fileDownload/>
tag with a separate menu. I just can't do that with my dynamic menu because the <ui:repeat>
tag doesn't work inside the <p:menu>
tag.
Any advice would be helpful.
Thanks!