Menu is a navigation component with one level of submenus.
<h:form>
<p:growl id="messages" showDetail="true"/>
<div class="card">
<h5>Inline</h5>
<p:menu>
<p:submenu label="Options">
<p:menuitem value="Save (Non-Ajax)" action="#{menuView.save}" update="messages" ajax="false"
icon="pi pi-save"/>
<p:menuitem value="Update" action="#{menuView.update}" update="messages" icon="pi pi-refresh"/>
<p:menuitem value="Delete" action="#{menuView.delete}" update="messages" icon="pi pi-times"/>
</p:submenu>
<p:submenu label="Navigations">
<p:menuitem value="Website" url="http://www.primefaces.org" icon="pi pi-external-link"/>
<p:menuitem value="Internal" outcome="/ui/menu/menubar" icon="pi pi-upload"/>
<p:menuitem value="Update (right click open in new tab)" action="#{menuView.update}" update="messages" url="http://www.primefaces.org" icon="pi pi-thumbs-up"/>
</p:submenu>
</p:menu>
</div>
<div class="card">
<h5>Overlay</h5>
<p:commandButton id="dynaButton" value="Show" type="button" icon="pi pi-bars"/>
<p:menu overlay="true" trigger="dynaButton" my="left top" at="left bottom">
<p:submenu label="Options">
<p:menuitem value="Save (Non-Ajax)" action="#{menuView.save}" update="messages" ajax="false"
icon="pi pi-save"/>
<p:menuitem value="Update" action="#{menuView.update}" update="messages" icon="pi pi-refresh"/>
<p:menuitem value="Delete" action="#{menuView.delete}" update="messages" icon="pi pi-times"/>
</p:submenu>
<p:submenu label="Navigations">
<p:menuitem value="Website" url="http://www.primefaces.org" icon="pi pi-external-link"/>
<p:menuitem value="Internal" outcome="/ui/menu/menubar" icon="pi pi-upload"/>
<p:menuitem value="Update (right click open in new tab)" action="#{menuView.update}" update="messages" url="http://www.primefaces.org" icon="pi pi-thumbs-up"/>
</p:submenu>
</p:menu>
</div>
<div class="card">
<h5>Programmatic</h5>
<p:menu model="#{menuView.model}" toggleable="true" />
</div>
<div class="card">
<h5>Toggleable</h5>
<p:menu toggleable="true">
<p:submenu label="Options">
<p:menuitem value="Save (Non-Ajax)" action="#{menuView.save}" update="messages" ajax="false"
icon="pi pi-save"/>
<p:menuitem value="Update" action="#{menuView.update}" update="messages" icon="pi pi-refresh"/>
<p:menuitem value="Delete" action="#{menuView.delete}" update="messages" icon="pi pi-times"/>
</p:submenu>
<p:submenu label="Navigations">
<p:menuitem value="Website" url="http://www.primefaces.org" icon="pi pi-external-link"/>
<p:menuitem value="Internal" outcome="/ui/menu/menubar" icon="pi pi-upload"/>
<p:menuitem value="Update (right click open in new tab)" action="#{menuView.update}" update="messages" url="http://www.primefaces.org" icon="pi pi-thumbs-up"/>
</p:submenu>
</p:menu>
</div>
</h:form>
package org.primefaces.showcase.view.menu;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import java.io.IOException;
import java.io.Serial;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import io.quarkus.runtime.annotations.RegisterForReflection;
import org.primefaces.model.menu.DefaultMenuItem;
import org.primefaces.model.menu.DefaultMenuModel;
import org.primefaces.model.menu.DefaultSubMenu;
import org.primefaces.model.menu.MenuModel;
@Named
@ViewScoped
@RegisterForReflection(serialization = true)
public class MenuView implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private MenuModel model;
@PostConstruct
public void init() {
model = new DefaultMenuModel();
//First submenu
DefaultSubMenu firstSubmenu = DefaultSubMenu.builder()
.label("Options")
.expanded(true)
.build();
DefaultMenuItem item = DefaultMenuItem.builder()
.value("Save (Non-Ajax)")
.icon("pi pi-save")
.ajax(false)
.command("#{menuView.save}")
.update("messages")
.build();
firstSubmenu.getElements().add(item);
item = DefaultMenuItem.builder()
.value("Update")
.icon("pi pi-refresh")
.command("#{menuView.update}")
.update("messages")
.build();
firstSubmenu.getElements().add(item);
item = DefaultMenuItem.builder()
.value("Delete")
.icon("pi pi-times")
.command("#{menuView.delete}")
.update("messages")
.build();
firstSubmenu.getElements().add(item);
model.getElements().add(firstSubmenu);
//Second submenu
DefaultSubMenu secondSubmenu = DefaultSubMenu.builder()
.label("Navigations")
.expanded(false)
.build();
item = DefaultMenuItem.builder()
.value("Website")
.url("http://www.primefaces.org")
.icon("pi pi-external-link")
.build();
secondSubmenu.getElements().add(item);
item = DefaultMenuItem.builder()
.value("Internal")
.icon("pi pi-upload")
.command("#{menuView.redirect}")
.build();
secondSubmenu.getElements().add(item);
model.getElements().add(secondSubmenu);
}
public MenuModel getModel() {
return model;
}
public void redirect() throws IOException {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath());
}
public void save() {
addMessage("Save", "Data saved");
}
public void update() {
addMessage("Update", "Data updated");
}
public void delete() {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "Delete", "Data deleted");
FacesContext.getCurrentInstance().addMessage(null, message);
}
public void sleepAndSave() throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
save();
}
public void sleepAndUpdate() throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
update();
}
public void sleepAndDelete() throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
delete();
}
public void addMessage(String summary, String detail) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary, detail);
FacesContext.getCurrentInstance().addMessage(null, message);
}
}