Primefaces-如何向菜单项动态添加上下文菜单
我想以编程方式创建带有MenuItems的p:menu(它可以工作),并且每个MenuItem都应该有p:contextMenu(它不能工作) ManagedBean:Primefaces-如何向菜单项动态添加上下文菜单,primefaces,menu,contextmenu,menuitem,Primefaces,Menu,Contextmenu,Menuitem,我想以编程方式创建带有MenuItems的p:menu(它可以工作),并且每个MenuItem都应该有p:contextMenu(它不能工作) ManagedBean: @ManagedBean(name="leftMenuView") @SessionScoped public class LeftMenuView { private MenuModel model; @PostConstruct public void init() { model
@ManagedBean(name="leftMenuView")
@SessionScoped
public class LeftMenuView {
private MenuModel model;
@PostConstruct
public void init() {
model = new DefaultMenuModel();
DefaultMenuItem item = new DefaultMenuItem("Redirect");
item.setId("redirectMenuItem");
model.addElement(item);
ContextMenu ctxMenu = new ContextMenu();
ctxMenu.setFor("redirectMenuItem");
MenuModel ctxModel = new DefaultMenuModel();
MenuItem ctxItem = new DefaultMenuItem("Remove from favorities");
ctxModel.addElement(ctxItem);
ctxMenu.setModel(ctxModel);
}
(...)
}
视图:
它在整个菜单栏上显示上下文菜单。单击菜单项或只是菜单组件并不重要
当我将其更改为:
uiComponent = (UIComponent) rootView
.findComponent(":leftForm:leftMenu:redirectMenuItem");
uiComponent.getChildren().add(ctxMenu);
我得到“java.lang.IllegalArgumentException:leftMenu”
换句话说,我想得到这种行为:
uiComponent = (UIComponent) rootView
.findComponent("leftForm");
uiComponent.getChildren().add(ctxMenu);
<h:form>
<p:menu id="menu_id">
<p:menuitem id="gmail_id" value="Gmail"/>
<p:menuitem id="hotmail_id" value="Hotmail" />
</p:menu>
<p:contextMenu for="gmail_id">
<p:menuitem value="Save" />
<p:menuitem value="Delete"/>
</p:contextMenu>
</h:form>
但是以编程方式(从源代码)。在PrimeFaces类BaseMenureUnderer,encodeEnd()中,您在后端设置的Id会再次被GenerateUniqueID(..)覆盖 我为此提出了一个问题 如果你愿意,就投票吧。这似乎是一个错误。 它仍然存在于PrimeFaces 5.3.5中 所以答案是,目前无法为菜单项设置ID 这是我目前设置ID的解决方法: 将其放在faces-config.xml中,以使用您自己的MenuRender
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.MenuRenderer</renderer-type>
<renderer-class>de.yourPackage.CustomMenuRenderer</renderer-class>
</renderer>
</render-kit>
org.primefaces.component
org.primefaces.component.menurender
de.yourPackage.custommenurender
然后创建一个custommenurender类,如下所示,只做了一点更改,不覆盖ID:
public class CustomMenuRenderer extends CustomBaseMenuRenderer {
protected void encodeScript(FacesContext context, AbstractMenu abstractMenu) throws IOException {
Menu menu = (Menu) abstractMenu;
String clientId = menu.getClientId(context);
WidgetBuilder wb = getWidgetBuilder(context);
wb.initWithDomReady("PlainMenu", menu.resolveWidgetVar(), clientId)
.attr("toggleable", menu.isToggleable(), false);
if (menu.isOverlay()) {
encodeOverlayConfig(context, menu, wb);
}
wb.finish();
}
protected void encodeMarkup(FacesContext context, AbstractMenu abstractMenu) throws IOException {
ResponseWriter writer = context.getResponseWriter();
Menu menu = (Menu) abstractMenu;
String clientId = menu.getClientId(context);
String style = menu.getStyle();
String styleClass = menu.getStyleClass();
String defaultStyleClass = menu.isOverlay() ? Menu.DYNAMIC_CONTAINER_CLASS : Menu.STATIC_CONTAINER_CLASS;
if (menu.isToggleable()) {
defaultStyleClass = defaultStyleClass + " " + Menu.TOGGLEABLE_MENU_CLASS;
}
styleClass = styleClass == null ? defaultStyleClass : defaultStyleClass + " " + styleClass;
writer.startElement("div", menu);
writer.writeAttribute("id", clientId, "id");
writer.writeAttribute("class", styleClass, "styleClass");
if (style != null) {
writer.writeAttribute("style", style, "style");
}
writer.writeAttribute("role", "menu", null);
encodeKeyboardTarget(context, menu);
if (menu.getElementsCount() > 0) {
writer.startElement("ul", null);
writer.writeAttribute("class", Menu.LIST_CLASS, null);
encodeElements(context, menu, menu.getElements());
writer.endElement("ul");
}
writer.endElement("div");
}
protected void encodeElements(FacesContext context, Menu menu, List<MenuElement> elements) throws IOException {
ResponseWriter writer = context.getResponseWriter();
boolean toggleable = menu.isToggleable();
for (MenuElement element : elements) {
if (element.isRendered()) {
if (element instanceof MenuItem) {
MenuItem menuItem = (MenuItem) element;
String containerStyle = menuItem.getContainerStyle();
String containerStyleClass = menuItem.getContainerStyleClass();
containerStyleClass = (containerStyleClass == null) ? Menu.MENUITEM_CLASS : Menu.MENUITEM_CLASS + " " + containerStyleClass;
if (toggleable) {
UIComponent parent = ((UIComponent) menuItem).getParent();
containerStyleClass = (parent instanceof Submenu) ? containerStyleClass + " " + Menu.SUBMENU_CHILD_CLASS : containerStyleClass;
}
writer.startElement("li", null);
writer.writeAttribute("class", containerStyleClass, null);
writer.writeAttribute("role", "menuitem", null);
if (containerStyle != null) {
writer.writeAttribute("style", containerStyle, null);
}
if (menuItem.getId() != null) {
writer.writeAttribute("id", menuItem.getId(), null);
}
encodeMenuItem(context, menu, menuItem);
writer.endElement("li");
}
else if (element instanceof Submenu) {
encodeSubmenu(context, menu, (Submenu) element);
}
else if (element instanceof Separator) {
encodeSeparator(context, (Separator) element);
}
}
}
}
@SuppressWarnings("unchecked")
protected void encodeSubmenu(FacesContext context, Menu menu, Submenu submenu) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String label = submenu.getLabel();
String icon = submenu.getIcon();
String style = submenu.getStyle();
String styleClass = submenu.getStyleClass();
styleClass = styleClass == null ? Menu.SUBMENU_TITLE_CLASS : Menu.SUBMENU_TITLE_CLASS + " " + styleClass;
boolean toggleable = menu.isToggleable();
//title
writer.startElement("li", null);
if (toggleable) {
writer.writeAttribute("id", submenu.getClientId(), null);
}
writer.writeAttribute("class", styleClass, null);
if (style != null) {
writer.writeAttribute("style", style, null);
}
if (menu.getId() != null) {
writer.writeAttribute("id", menu.getId(), null);
}
writer.startElement("h3", null);
if (menu.isToggleable()) {
encodeIcon(context, label, Menu.EXPANDED_SUBMENU_HEADER_ICON_CLASS);
}
if (icon != null) {
encodeIcon(context, label, "ui-submenu-icon ui-icon " + icon);
}
if (label != null) {
writer.writeText(label, "value");
}
writer.endElement("h3");
writer.endElement("li");
encodeElements(context, menu, submenu.getElements());
}
protected void encodeIcon(FacesContext context, String label, String styleClass) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("span", null);
writer.writeAttribute("class", styleClass, null);
writer.endElement("span");
}
public类custommenurender扩展了custombasemenurender{
受保护的void encodeScript(FacesContext上下文,AbstractMenu AbstractMenu)引发IOException{
菜单菜单=(菜单)抽象菜单;
字符串clientId=menu.getClientId(上下文);
WidgetBuilder wb=getWidgetBuilder(上下文);
wb.initWithDomReady(“PlainMenu”,menu.resolveWidgetVar(),clientId)
.attr(“可切换”,menu.isToggleable(),false);
if(menu.isOverlay()){
EncodeOverlyConfig(上下文、菜单、wb);
}
wb.finish();
}
受保护的void encodeMarkup(FacesContext上下文,AbstractMenu AbstractMenu)引发IOException{
ResponseWriter=context.getResponseWriter();
菜单菜单=(菜单)抽象菜单;
字符串clientId=menu.getClientId(上下文);
字符串样式=menu.getStyle();
String styleClass=menu.getStyleClass();
字符串defaultStyleClass=menu.isOverlay()?menu.DYNAMIC\u CONTAINER\u CLASS:menu.STATIC\u CONTAINER\u CLASS;
if(menu.isToggleable()){
defaultStyleClass=defaultStyleClass+“”+Menu.togleable\u Menu\u类;
}
styleClass=styleClass==null?defaultStyleClass:defaultStyleClass+“”+styleClass;
startElement(“div”,菜单);
writeAttribute(“id”,clientId,“id”);
writeAttribute(“class”,styleClass,styleClass”);
如果(样式!=null){
writeAttribute(“风格”,风格,风格”);
}
writeAttribute(“角色”、“菜单”,null);
编码键盘目标(上下文、菜单);
如果(menu.getElementsCount()>0){
startElement(“ul”,空);
writer.writeAttribute(“class”,Menu.LIST\u class,null);
编码元素(上下文、菜单、menu.getElements());
作者:恩德莱恩(“ul”);
}
作者:恩德莱恩(“div”);
}
受保护的元素(FacesContext上下文、菜单菜单、列表元素)引发IOException{
ResponseWriter=context.getResponseWriter();
boolean-toggleable=menu.istogleable();
for(菜单元素:元素){
if(element.isRendered()){
if(MenuItem的元素实例){
MenuItem MenuItem=(MenuItem)元素;
字符串containerStyle=menuItem.getContainerStyle();
字符串containerStyleClass=menuItem.getContainerStyleClass();
containerStyleClass=(containerStyleClass==null)?Menu.MENUITEM\u类:Menu.MENUITEM\u类+“”+containerStyleClass;
如果(可切换){
UIComponent父项=((UIComponent)menuItem.getParent();
containerStyleClass=(子菜单的父实例)?containerStyleClass+“”+菜单。子菜单\子菜单\子类:containerStyleClass;
}
作者:startElement(“li”,空);
writeAttribute(“类”,containerStyleClass,null);
writeAttribute(“角色”,“菜单项”,null);
if(containerStyle!=null){
writeAttribute(“样式”,容器样式,空);
}
如果(menuItem.getId()!=null){
writer.writeAttribute(“id”,menuItem.getId(),null);
}
encodeMenuItem(上下文、菜单、菜单项);
作者:恩德莱恩(“李”);
}
else if(子菜单的元素实例){
编码子菜单(上下文、菜单、(子菜单)元素);
}
else if(分隔符的元素实例){
编码分隔符(上下文,(分隔符)元素);
}
}
}
}
@抑制警告(“未选中”)
受保护的子菜单(FacesContext上下文、菜单菜单、子菜单)引发IOException{
ResponseWriter=context.getResponseWriter();
字符串标签=子菜单.getLabel();
字符串图标=子菜单.getIcon();
字符串样式=子菜单.getStyle();
String styleClass=子菜单。getStyleClass();
styleClass=styleClass==null?Menu.SUBMENU\u TITLE\u CLASS:Menu.SUBMENU\u TITLE\u CLASS+“”+styleClass;
boolean-toggleable=menu.istogleable();
//头衔
作者:startElement(“li”,空);
如果(可切换){
writeAttribute(“id”,子菜单.getClientId(),null);
}
writeAttribute(“class”,styleClass,null);
如果(样式!=null){
writer.writeAttribute(“style”,style,null);
}
if(menu.getId()!=null){
writeAttribute(“id”,menu.getId(),null);
}
startElement(“h3”,空);
if(menu.isToggleable()){
编码图标(上下文、标签、菜单、扩展的子菜单、标题、图标、类);
}
如果(图标
public class CustomMenuRenderer extends CustomBaseMenuRenderer {
protected void encodeScript(FacesContext context, AbstractMenu abstractMenu) throws IOException {
Menu menu = (Menu) abstractMenu;
String clientId = menu.getClientId(context);
WidgetBuilder wb = getWidgetBuilder(context);
wb.initWithDomReady("PlainMenu", menu.resolveWidgetVar(), clientId)
.attr("toggleable", menu.isToggleable(), false);
if (menu.isOverlay()) {
encodeOverlayConfig(context, menu, wb);
}
wb.finish();
}
protected void encodeMarkup(FacesContext context, AbstractMenu abstractMenu) throws IOException {
ResponseWriter writer = context.getResponseWriter();
Menu menu = (Menu) abstractMenu;
String clientId = menu.getClientId(context);
String style = menu.getStyle();
String styleClass = menu.getStyleClass();
String defaultStyleClass = menu.isOverlay() ? Menu.DYNAMIC_CONTAINER_CLASS : Menu.STATIC_CONTAINER_CLASS;
if (menu.isToggleable()) {
defaultStyleClass = defaultStyleClass + " " + Menu.TOGGLEABLE_MENU_CLASS;
}
styleClass = styleClass == null ? defaultStyleClass : defaultStyleClass + " " + styleClass;
writer.startElement("div", menu);
writer.writeAttribute("id", clientId, "id");
writer.writeAttribute("class", styleClass, "styleClass");
if (style != null) {
writer.writeAttribute("style", style, "style");
}
writer.writeAttribute("role", "menu", null);
encodeKeyboardTarget(context, menu);
if (menu.getElementsCount() > 0) {
writer.startElement("ul", null);
writer.writeAttribute("class", Menu.LIST_CLASS, null);
encodeElements(context, menu, menu.getElements());
writer.endElement("ul");
}
writer.endElement("div");
}
protected void encodeElements(FacesContext context, Menu menu, List<MenuElement> elements) throws IOException {
ResponseWriter writer = context.getResponseWriter();
boolean toggleable = menu.isToggleable();
for (MenuElement element : elements) {
if (element.isRendered()) {
if (element instanceof MenuItem) {
MenuItem menuItem = (MenuItem) element;
String containerStyle = menuItem.getContainerStyle();
String containerStyleClass = menuItem.getContainerStyleClass();
containerStyleClass = (containerStyleClass == null) ? Menu.MENUITEM_CLASS : Menu.MENUITEM_CLASS + " " + containerStyleClass;
if (toggleable) {
UIComponent parent = ((UIComponent) menuItem).getParent();
containerStyleClass = (parent instanceof Submenu) ? containerStyleClass + " " + Menu.SUBMENU_CHILD_CLASS : containerStyleClass;
}
writer.startElement("li", null);
writer.writeAttribute("class", containerStyleClass, null);
writer.writeAttribute("role", "menuitem", null);
if (containerStyle != null) {
writer.writeAttribute("style", containerStyle, null);
}
if (menuItem.getId() != null) {
writer.writeAttribute("id", menuItem.getId(), null);
}
encodeMenuItem(context, menu, menuItem);
writer.endElement("li");
}
else if (element instanceof Submenu) {
encodeSubmenu(context, menu, (Submenu) element);
}
else if (element instanceof Separator) {
encodeSeparator(context, (Separator) element);
}
}
}
}
@SuppressWarnings("unchecked")
protected void encodeSubmenu(FacesContext context, Menu menu, Submenu submenu) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String label = submenu.getLabel();
String icon = submenu.getIcon();
String style = submenu.getStyle();
String styleClass = submenu.getStyleClass();
styleClass = styleClass == null ? Menu.SUBMENU_TITLE_CLASS : Menu.SUBMENU_TITLE_CLASS + " " + styleClass;
boolean toggleable = menu.isToggleable();
//title
writer.startElement("li", null);
if (toggleable) {
writer.writeAttribute("id", submenu.getClientId(), null);
}
writer.writeAttribute("class", styleClass, null);
if (style != null) {
writer.writeAttribute("style", style, null);
}
if (menu.getId() != null) {
writer.writeAttribute("id", menu.getId(), null);
}
writer.startElement("h3", null);
if (menu.isToggleable()) {
encodeIcon(context, label, Menu.EXPANDED_SUBMENU_HEADER_ICON_CLASS);
}
if (icon != null) {
encodeIcon(context, label, "ui-submenu-icon ui-icon " + icon);
}
if (label != null) {
writer.writeText(label, "value");
}
writer.endElement("h3");
writer.endElement("li");
encodeElements(context, menu, submenu.getElements());
}
protected void encodeIcon(FacesContext context, String label, String styleClass) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("span", null);
writer.writeAttribute("class", styleClass, null);
writer.endElement("span");
}
public class CustomBaseMenuRenderer extends BaseMenuRenderer {
@Override
protected void encodeMenuItem(FacesContext context, AbstractMenu menu, MenuItem menuitem) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String title = menuitem.getTitle();
String style = menuitem.getStyle();
boolean disabled = menuitem.isDisabled();
writer.startElement("a", null);
writer.writeAttribute("tabindex", "-1", null);
if (shouldRenderId(menuitem)) {
writer.writeAttribute("id", menuitem.getClientId(), null);
}
if (title != null) {
writer.writeAttribute("title", title, null);
}
String styleClass = this.getLinkStyleClass(menuitem);
if (disabled) {
styleClass = styleClass + " ui-state-disabled";
}
writer.writeAttribute("class", styleClass, null);
if (style != null) {
writer.writeAttribute("style", style, null);
}
if (disabled) {
writer.writeAttribute("href", "#", null);
writer.writeAttribute("onclick", "return false;", null);
}
else {
setConfirmationScript(context, menuitem);
String onclick = menuitem.getOnclick();
//GET
if (menuitem.getUrl() != null || menuitem.getOutcome() != null) {
String targetURL = getTargetURL(context, (UIOutcomeTarget) menuitem);
writer.writeAttribute("href", targetURL, null);
if (menuitem.getTarget() != null) {
writer.writeAttribute("target", menuitem.getTarget(), null);
}
}
//POST
else {
writer.writeAttribute("href", "#", null);
UIComponent form = ComponentTraversalUtils.closestForm(context, menu);
if (form == null) {
throw new FacesException("MenuItem must be inside a form element");
}
String command;
if (menuitem.isDynamic()) {
String menuClientId = menu.getClientId(context);
Map<String, List<String>> params = menuitem.getParams();
if (params == null) {
params = new LinkedHashMap<String, List<String>>();
}
List<String> idParams = new ArrayList<String>();
idParams.add(menuitem.getId());
params.put(menuClientId + "_menuid", idParams);
command = menuitem.isAjax() ? buildAjaxRequest(context, menu, (AjaxSource) menuitem, form, params) : buildNonAjaxRequest(context, menu, form, menuClientId, params, true);
}
else {
command = menuitem.isAjax() ? buildAjaxRequest(context, (AjaxSource) menuitem, form)
: buildNonAjaxRequest(context, ((UIComponent) menuitem), form, ((UIComponent) menuitem).getClientId(context), true);
}
onclick = (onclick == null) ? command : onclick + ";" + command;
}
if (onclick != null) {
if (menuitem.requiresConfirmation()) {
writer.writeAttribute("data-pfconfirmcommand", onclick, null);
writer.writeAttribute("onclick", menuitem.getConfirmationScript(), "onclick");
}
else {
writer.writeAttribute("onclick", onclick, null);
}
}
}
encodeMenuItemContent(context, menu, menuitem);
writer.endElement("a");
}
@Override
protected boolean shouldRenderId(MenuElement element) {
if (element instanceof UIComponent) {
return shouldWriteId((UIComponent) element);
}
return false;
}
@Override
protected void encodeMarkup(FacesContext context, AbstractMenu abstractMenu) throws IOException {
// TODO Auto-generated method stub
}
@Override
protected void encodeScript(FacesContext context, AbstractMenu abstractMenu) throws IOException {
// TODO Auto-generated method stub
}
}
MenuModel model = new DefaultMenuModel();
DefaultSubMenu subMenu = new DefaultSubMenu("some submenu");
DefaultMenuItem menuItem = new DefaultMenuItem("some item");
subMenu.addElement(menuItem);
model.addElement(subMenu);
model.generateUniqueIds();
for (AuthTransactions subMenus : subTransactions){
String subMenuName = getI18NString(subMenus.getLabelId(),locale);
DefaultMenuItem item = new DefaultMenuItem(
subMenuName == null ? subMenus.getTransactionCode()
: subMenuName);
item.setCommand("#{" + subMenus.getViewClassName()
+ defaultMethodName + "}");
item.setParam("menuTransactionCode",
subMenus.getTransactionCode());
item.setOnclick("PF('statusDialog').show()");
item.setTitle(subMenus.getTransactionCode());
item.setIcon(subMenus.getIcon());
userMenuModel.addElement(item);
ContextMenu ctxMenu = new ContextMenu();
ctxMenu.setFor("leftmenu:"+subMenus.getTransactionCode());
DynamicMenuModel ctxModel = new DynamicMenuModel();
DefaultMenuItem ctxItem = new DefaultMenuItem("Add/Remove"
+subMenus.getTransactionCode() + " to favorites","ui-icon-star");
ctxItem.setCommand("#{currentUserManager.toggleFavorite}");
ctxItem.setParam("menuTransactionCode", subMenus.getTransactionCode());
ctxItem.setAjax(true);
ctxItem.setOnclick("PF('statusDialog').show()");
ctxItem.setUpdate(":topBar");
ctxModel.addElement(ctxItem);
ctxMenu.setModel(ctxModel);
contextMenuList.add(ctxMenu);
}
<ps:menu id="sm_leftmenu" model="#{userMenuModel}" stateful="false" />
<c:if test="#{userMenuModel != null and userMenuModel.elements !=null and !empty userMenuModel.elements}">
<ul id="leftmenu:sm_leftmenu" class="layout-menubar-container">
<c:forEach var="item" items="#{userMenuModel.elements}">
<li id="#{item.id}" role="menuitem">
<h:commandLink value="#{item.value}" action="#{item.command}" title="#{item.title}" onclick="PF('statusDialog').show();" id="#{item.title}">
<f:param name="menuTransactionCode" value="#{item.title}" />
<i class="#{item.icon} yellow" style="float:left;padding-right:5px;"></i>
</h:commandLink>
</li>
</c:forEach>
</ul>
</c:if>
<h:panelGroup rendered="#{currentUserManager.contextMenuList != null and !empty currentUserManager.contextMenuList}">
<h:dataTable value="#{currentUserManager.contextMenuList}" var="contextMenu">
<h:column>
<p:contextMenu binding="#{contextMenu}" model="#{contextMenu.model}" for="#{contextMenu.for}" styleClass="favCtx"/>
</h:column>
</h:dataTable>
</h:panelGroup>