Column-specific context menu for Primefaces DataTable

被刻印的时光 ゝ 提交于 2019-12-13 06:19:39

问题


How can I define context menu for each column differently in Primefaces datatable? Putting <p:contextMenu> inside <p:column> does not work properly. I want context menu to be different depending on which column user right-clicked in.

This does not work (context menu is created the same for all columns):

<p:dataTable value="#{values}" var="value" selectionMode="single" selection="#{selectedValue}" id="table">
    <p:column headerText="Col 1">
        <h:outputText value="#{value.balance}">
            <f:convertNumber type="currency"></f:convertNumber>
        </h:outputText>
        <p:contextMenu>
            <p:menuitem value="Report"></p:menuitem>
            <p:menuitem value="Change"></p:menuitem>
        </p:contextMenu>
    </p:column>
    <p:column headerText="col 2" >
        <h:outputText value="#{value.balance2}">
            <f:convertNumber type="currency"></f:convertNumber>
        </h:outputText>
    <p:contextMenu>
        <p:menuitem value="Something else"></p:menuitem>
    </p:contextMenu>
    </p:column>
</p:dataTable>

How to add column-specific context menu in Primefaces dataTable either by using PF components, extending PF components, or adding custom JavaScript?


回答1:


Have you tried(I have just tested with Primefaces 3.5): ContextMenu can be attached to any JSF component, each of rows in primefaces datatable has private and dynamic id(ex: :carList:0:test1 :carList:1:test1 ...), so I think you should use contextMenu inside column:

                 <p:column headerText="Model">  
                    <p:panel id="test1">
                        <h:outputText value="#{carr.model}" />
                        <p:contextMenu for="test1" widgetVar="cMenu">
                            <p:menuitem value="Edit Cell" icon="ui-icon-search"
                                        onclick="product.showCellEditor();return false;" />
                            <p:menuitem value="Hide Menu" icon="ui-icon-close"
                                        onclick="cMenu.hide()" />
                        </p:contextMenu>
                    </p:panel>
                </p:column>  
                <p:column headerText="MANUFAC" style="width:20%">  
                    <p:panel id="test2">
                        <h:outputText value="#{carr.manufacturer}" />
                        <p:contextMenu for="test2" widgetVar="cMenu2">
                            <p:menuitem value="Edit Cell" icon="ui-icon-search"
                                        onclick="product.showCellEditor();return false;" />
                            <p:menuitem value="Hide Menu" icon="ui-icon-close"
                                        onclick="cMenu2.hide()" />
                            <p:menuitem value="Hide Menu" icon="ui-icon-close"
                                        onclick="cMenu2.hide()" />
                        </p:contextMenu>
                    </p:panel>
                </p:column>

If you want to specify row:

<p:column headerText="Model" style="width:30%">  
                    <p:panel id="test1">
                        <h:outputText value="#{carr.model}" />
                        <p:contextMenu rendered="#{carr.model eq 'SENT'}" for="test1" widgetVar="cMenu">
                            <p:menuitem value="Edit Cell" icon="ui-icon-search"
                                        onclick="product.showCellEditor();return false;" />
                            <p:menuitem value="Hide Menu" icon="ui-icon-close"
                                        onclick="cMenu.hide()" />
                        </p:contextMenu>
                        <p:contextMenu rendered="#{carr.model eq 'WAITING'}" for="test1" widgetVar="cMenu3">

                            <p:menuitem value="Hide Menu" icon="ui-icon-close"
                                        onclick="cMenu3.hide()" />
                        </p:contextMenu>
                    </p:panel>
                </p:column>  



回答2:


an alternative way is to use the p:menuButton instead. the p:menuButton can be changed to look like a p:contextMenu it's all about styleClass.

  1. create custom styleclass to change the down arrow

    .contextButton .ui-state-default .ui-icon{
        background:url(YOUR_IMAGE_PATH);
    }
    
  2. create custom styleclass to hide the button border and background

    .contextButton .ui-button { border: none; background: none; }

    .contextButton .ui-button.ui-state-hover, .ui-button.ui-state-focus, .ui-button.ui-state-active { border: none; background: none; }

  3. use the custom styleClass in the p:menuButton

    <p:menuButton value="" styleClass="contextButton">
    P:MENUITEM HERE
    </p:menuButton>

you may refer here for working example




回答3:


Optional for attribute defines which component the contextMenu is attached to. When for is not defined, contextMenu is attached to the page meaning, right-click on anywhere on page will display the menu.

That's what Primefaces Documentation says about the contextMenu tag. So, in the way you have, it's attached to the page meaning. Using for attribute you will be able to integrate with Primefaces Components, but probably no with an specific table column.

Also Datatable documentation suggests that you can only do that when making a selection into the table, as it seems it has special ways to adapt it to tree nodes.

However I highly recommend you looking through docs before asking.



来源:https://stackoverflow.com/questions/16099698/primefaces-contextmenu-different-menu-based-on-selected-item

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!