Surface ColumnToggler does not work with pagination

I have a datatable along with sort, filter and column. First, when I select and deselect a column on the same page, everything is fine.

enter image description here

enter image description here As you can see, my first column is gone

My problem is here when I navigate to the next page with the pagination tool and if I want to deselect the column it only displays the column header, not their rows, as you can see below: enter image description here The initial hidden column is now displayed, but we have a gap. The last column is now empty, and the first takes on the value of the second column.

This is my data structure:

<p:dataTable id="datatable" var="mon" value="#{X.resultQuery}" 
                         first="#{dataTableController.first}"
                         resizableColumns="true"
                         rows="20"
                         paginator="true"
                         paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                         rowsPerPageTemplate="30,40,50"
                         draggableColumns="true"
                         paginatorPosition="bottom" 
                         selectionMode="single" rowKey="#{mon[4]}"
                         >   
                <f:facet name="header">
                    <p:commandButton id="toggler" type="button" value="Hide Columns" icon="ui-icon-calculator" />
                    <p:columnToggler datasource="datatable" trigger="toggler">
                        <p:ajax event="toggle"  listener="#{columnTogglerController.onToggle}" />
                    </p:columnToggler>
                </f:facet>

      

This is my ColumnTogglerController:

public class ColumnTogglerController implements Serializable {

private List<Boolean> list;

/**
 * Creates a new instance of ColumnTogglerController
 */
public ColumnTogglerController() {
}

public List<Boolean> getList() {
    return list;
}

public void setList(List<Boolean> list) {
    this.list = list;
}

@PostConstruct
public void init() {
    setList(Arrays.asList(true, true, true, true, true, true, true, true, true, true, true));
}

public void onToggle(ToggleEvent e) {
    list.set((Integer) e.getData(), e.getVisibility() == Visibility.VISIBLE);

}

      

}

Basically my program is based on this blog: http://blog.primefaces.org/?p=3341

Thanks for the help.

+3


source to share


1 answer


I have encountered this by chance lately. blog really works. The task draggableColumns="true"

changes the index of the columns. So, instead of a list, I used 2 cards:

private final Map<String, Boolean> colVisibilityMap = new HashMap<>();
private final Map<Integer, String> colIndexMap = new HashMap<>();

      

During initialization, I set colIndexMap and colVisibilityMap (and I used id / clientId as key). When I change the order of the columns, I update the colIndexMap. And on switching, I update the colVisibilityMap base to colIndexMap.



public Map<String, Boolean> getColVisibilityMap() {
    return Collections.unmodifiableMap(colVisibilityMap);
}

private String getColumnId(String fullId) {
    String[] idParts = fullId.split(":");
    return idParts[idParts.length - 1];
}

@PostConstruct
public void init() {
    FacesContext context = FacesContext.getCurrentInstance();
    DataTable table = (DataTable) context.getViewRoot().findComponent(":form:tableid");
    List<UIColumn> columns = table.getColumns();
    for (int i = 0; i < columns.size(); i++) {
        final String columnId = this.getColumnId(columns.get(i).getClientId());
        colIndexMap.put(i, columnId);
        colVisibilityMap.put(columnId, true);
    });
}

public void onColumnReorder(AjaxBehaviorEvent e) {
    List<UIColumn> columns = ((DataTable) e.getSource()).getColumns();
    for (int i = 0; i < columns.size(); i++) {
        this.colIndexMap.put(i, this.getColumnId(columns.get(i).getClientId()));
    }
}

public void onToggle(ToggleEvent e) {
    // If we use list here, e.getData() may not be the correct index due to column reordering.
    this.colVisibilityMap.put(this.colIndexMap.get((Integer) e.getData()), e.getVisibility() == Visibility.VISIBLE);
}

      

Here is the code in my JSF page:

<p:dataTable id="tableid" widgetVar="tableWidgetVar" draggableColumns="true" paginator="true"
<!-- ommitted other attributes -->
>
    <p:ajax event="colReorder" listener="#{bean.onColumnReorder}"/>
    <f:facet name="header">
        <p:commandButton id="toggler" type="button" value="Columns"/>
        <p:columnToggler datasource="tableid" trigger="toggler">
            <p:ajax event="toggle" listener="#{bean.onToggle}"/>
        </p:columnToggler>
    </f:facet>
    <p:column id="col1" visible="#{bean.colVisibilityMap['col1']}">
        <!-- ommitted -->
    </p:column>
    <p:column id="col2" visible="#{bean.colVisibilityMap['col2']}">
        <!-- ommitted -->
    </p:column>
    <!-- and so on... -->
</p:dataTable>

      

+3


source







All Articles