Sorry i forgot to precise : i'm on primefaces 5.1
I found my solution !
In a first time, I put my p:columns inside a p:datatable which is inside a p:column and it's work ! The columntoggler change visibility of this whole column. So i can't hide column per column...
But i also use the pagination and columntoggler/pagination didn't work very well together... I can hide a column but if i change my page (using the paginator) in datatable, the column will re-appear empty ! But if i refresh the whole page, the paginator work correctly...
that's why i used this part of solution : Primefaces ColumnToggler does'nt work with pagination
Precisely a script to check/uncheck column visibility.
<script>
function updateToggles(widget){
$( widget.jqId + ' .ui-chkbox .ui-chkbox-box').each(function() {
var chkbox = $(this);
if(chkbox.hasClass('ui-state-active')) {
widget.check(chkbox);
} else {
widget.uncheck(chkbox);
}
});
}
</script>
<p:dataTable
id="datatable-factures"
value="#{listFactureHandler.table}"
var="facture"
label="Facture"
nativeElements="true"
paginator="true"
rowKey="#{facture.id}"
rowSelectMode="checkbox"
selection="#{listFactureHandler.selection}"
sortBy="#{facture.dateFacture.time}"
sortOrder="descending">
<f:facet name="header">
<p:commandButton id="toggler" type="button" value="Personnaliser" style="float:right;" />
<p:columnToggler widgetVar="columnToggler" id="columnToggler" datasource="datatable-factures" trigger="toggler" ><p:ajax event="toggle" listener="#{dsHandler.onToggleColumn}"/></p:columnToggler>
<p:ajax event="page" oncomplete="updateToggles(PF('columnToggler'))"/>
</f:facet>
<p:ajax event="toggleSelect" update=":formulaire:insert-actions" />
<p:ajax event="rowSelectCheckbox" update=":formulaire:insert-actions" />
<p:ajax event="rowUnselectCheckbox" update=":formulaire:insert-actions" />
<p:column selectionMode="multiple" styleClass="text-center" toggleable="false" />
[...]
<p:column id="columns-champs-perso" headerText="Champs Personnalisés" visible="false">
<p:dataTable id="subfacture" value="#{facture}">
<p:columns headerText="#{champs.libelle}" id="champspersos#{index}" value="#{listFactureHandler.dossier.champsPersonnalises}" columnIndexVar="index" var="champs">
<h:outputText value="#{facture.getChampPersonnalise(champs.code).valeur}" />
</p:columns>
</p:dataTable>
An handler (dsHandler) memorize datatable states.
On pre-rendering, i do something like that :
Map<String, Boolean> map = objlState.getColumnsVisibles();
for (String id : map.keySet()) {
Column objCol = (Column) FacesContext.getCurrentInstance().getViewRoot().findComponent(id);
if (objCol != null) {
objCol.setVisible(map.getOrDefault(id, true));
}
}
I memorize columns id, not indexes because columntoggler return columnIndex+visibility and did not pay attention to columns which are not rendered. (but datatable.getChildCount() return column number and take care of not rendered columns.
In hope that will help someone a day ;)