I have a paged PrimeFaces Datatable with a context menu, and i wish to implement multi-select, where the menu items in the context menu will depend on the number of items se
Maybe too late but here is my solution...
Context menu with javascript:
<p:contextMenu id="searchResultTableContextMenuId" for="searchResultTableId" beforeShow="return true;"
widgetVar="searchResultTableContextMenuVar">
<p:menuitem value="#{msgs['label.resultlistAction.edit']}"
disabled="#{curSelectedDocsCount ne 1}" icon="fa fa-pencil"
oncomplete="PF('editPropertyDialogVar').show();" update=":editPropertyFormId" />
<p:menuitem value="#{msgs['label.resultlistAction.delete']}"
disabled="#{curSelectedDocsCount le 0}" icon="fa fa-trash"
actionListener="#{deleteDocumentBL.initFromResultList()}"
oncomplete="PF('deleteDocumentsDialogVar').show();" update=":deleteDocumentsFormId" />
<p:menuitem value="#{msgs['label.resultlistAction.download']}"
disabled="#{curSelectedDocsCount ne 1}" icon="fa fa-download" ajax="false"
action="#{contentBL.downloadMainContent(curSearch.getViewId(), curSearch.selectedSearchResults.get(0))}" />
<p:menuitem value="#{msgs['label.resultlistAction.clearSelectionId']}" disabled="#{curSelectedDocsCount lt 1}" icon="fa fa-times-circle-o"
action="#{curSearch.clearSelectedSearchResults()}" update="@(.resultlistActionGrid) @(.searchResultTable)"
oncomplete="PF('hitlistTableVar').unselectAllRows();" />
</p:contextMenu>
<!-- javascript to fix problem that the context menu hides if it is updated in ajax event contextMenu -->
<script type="text/javascript">
var currentEvent;
$(document).ready(function () {
PrimeFaces.widget.ContextMenu.prototype.show = function (e) {
// hide other contextmenus if any
$(document.body).children('.ui-contextmenu:visible').hide();
if (e) {
currentEvent = e;
}
var win = $(window),
left = e.pageX,
top = e.pageY,
width = this.jq.outerWidth(),
height = this.jq.outerHeight();
//collision detection for window boundaries
if ((left + width) > (win.width()) + win.scrollLeft()) {
left = left - width;
}
if ((top + height ) > (win.height() + win.scrollTop())) {
top = top - height;
}
if (this.cfg.beforeShow) {
this.cfg.beforeShow.call(this);
}
this.jq.css({
'left': left,
'top': top,
'z-index': ++PrimeFaces.zindex
}).show();
e.preventDefault();
};
});
</script>
The dataTable needs to handle some ajax events for context menu showing and updating:
<p:dataTable id="searchResultTableId" ...>
<p:ajax event="rowSelect" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
<p:ajax event="rowUnselect" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
<p:ajax event="toggleSelect" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
<p:ajax event="rowSelectCheckbox" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
<p:ajax event="rowUnselectCheckbox" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
<p:ajax event="contextMenu" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" oncomplete="PF('searchResultTableContextMenuVar').show(currentEvent);" />
</p:dataTable>