Home > OS >  Primefaces ajax event contextMenu causes default right click menu to show
Primefaces ajax event contextMenu causes default right click menu to show

Time:07-15

I have a fairly simple <p:dataTable> in which I list some person data. The users should be able to add and remove persons. However, I have an issue with setting the selection value.

Let me show you what I mean. Following is the p:dataTable as well as the p:contextMenu (context menu is defined after the table).

<p:dataTable id="personTable" var="person"
    value="#{model.getPersons()}"
    selectionMode="single" selection="#{model.personSelection}"
    scrollable="true" rowKey="#{person.id}" scrollHeight="200"
    disableContextMenuIfEmpty="true">
    <p:ajax event="rowSelect" />
    <p:ajax event="rowDblselect" update="@widgetVar(personDialog)"
        oncomplete="PF('personDialog').show()" />
    <p:column headerText="Name" sortable="true"
        sortBy="#{person.firstName}">
        <h:outputText value="#{person.firstName}" />
    </p:column>
    <p:column headerText="Address" sortable="true"
        sortBy="#{person.address}">
        <h:outputText value="#{person.address}" />
    </p:column>
</p:dataTable>
<p:contextMenu for="personTable" id="ctxPerson">
    <p:menuitem value="Delete" update="personTable"
        partialSubmit="true" process="@this" ajax="true"
        actionListener="#{personService.removePerson(model)}" />
</p:contextMenu>

Now, with this code, to delete a person, the users have to select a row with left-click. This updates the selection as needed. Then the user can right-click to open the context menu and delete the selected person.

What does not work, is leaving out the selection step with left-click. So if the user enters the page, right-clicks a row to delete the person, the selection is empty.

Now this isn't optimal. I did some google searches and found another ajax event: <p:ajax event="contextMenu"/> which does trigger update of the selection when right-clicking. BUT adding this ajax event causes the browsers default context menu to always show over my own (my own context menu does open, but is behind default one):

enter image description here

And this is what it looks like without the ajax event contextMenu:

enter image description here

I am looking for a non-javascript way to A) update the selection on right-click only B) not show the browsers default right click menu on the datatable.

Any help is appreciated!


I am on primefaces 11.0.0, as the newer version 11.0.6 is not available through maven repository.

CodePudding user response:

Fixed for 12.0.0: https://github.com/primefaces/primefaces/issues/8376

MonkeyPatch (just add to your application JS file):

if (PrimeFaces.widget.DataTable) {
    PrimeFaces.widget.DataTable.prototype.onRowRightClick = function(event, rowElement, cmSelMode, fnShowMenu) {
        var row = $(rowElement),
            rowMeta = this.getRowMeta(row),
            selected = row.hasClass('ui-state-highlight');

        this.assignFocusedRow(row);

        if (cmSelMode === 'single' || !selected) {
            this.unselectAllRows();
        }

        this.selectRow(row, true);

        this.fireRowSelectEvent(rowMeta.key, 'contextMenu', fnShowMenu);

        if (this.cfg.disabledTextSelection) {
            PrimeFaces.clearSelection();
        }

        return this.hasBehavior('contextMenu');
    }
}
  • Related