1
votes

I am currently working with JSF 2 and Primefaces 5.2, more precisely with p:dataTable. I use p:dataTable with pagination.

From my Java bean, I can't find a way to retrieve any pagination component. I am particularly interested in an object where I can get the selected element in {RowsPerPageDropdown}

<p:dataTable
        var="item"
        value="#{items}"
        rows="10" 
        id="tableItems"      
        paginator="true" paginatorPosition="top" paginatorAlwaysVisible="true"
        paginatorTemplate="{CurrentPageReport} {PreviousPageLink} Page : {JumpToPageDropdown} {NextPageLink} NbrElements : {RowsPerPageDropdown}"
        rowsPerPageTemplate="#{fn:length(items)},10,20,50"
        currentPageReportTemplate="{startRecord}-{endRecord} / {totalRecords}" binding="#{tableComponent.table}">

By inspecting the page, the drop down menu id is tableItems_rppDD.

I tried finding it by printing component id out with a combination of FacesContext.getCurrentInstance().getViewRoot()...getChildren() and findComponent() but with no success.

Does anyone know how to get my hand on the paginator or if it is possible? Or is it a pure Javascript object?

Thanks a lot

Edit:

I am adding dynamically elements to my list (p:dataTable + h:commandLink) .

If you look the dataTable declaration, the first element of the {RowsPerPageDropdown} is the number of elements in the new list (let's call it n). The first time around, if I select this first element from {RowsPerPageDropdown}, it displays n elements.

If I add a new element in the list, the first element of the {RowsPerPageDropdown} becomes n + 1 But the total number of elements displayed in the table is n (the newest element is in the next page).

I have fixed my problem by reimplementing with minor changes {CurrentPageReport}

1
Why do you need access to it? What problem are you trying to solve? Maybe lazyLoading is better for you. You receive the 'page' size (selected in dropdown) in the load method thenKukeltje
If it is just about getting the selected value, you can always look at the request parameters and retrieve it from there. It's id/name is identical to the full id of the datatable appended by :rowKukeltje
@Kukeltje: See update . I will look into lazydatamodel. Thank you bothccheneson

1 Answers

1
votes

Too long for a comment...

DataTable is a single UIComponent, and has not a paginator 'JSF component' (UIComponent).
So, every operation you need to do about pagination must be done directly on DataTable, or on DataModel (when passed as value attribute).

However, depending on what you need to do, you can access its attributes:

DataTable table = [find component somehow: UIComponent.getCurrentComponent(context), context.getViewRoot().findComponent(expr), ...]

// if you need to know currently selected RowsPerPageDropdown (page size)
int rows = table.getRows(); // table.getRowsToRender();

// or you can get the template
String rowsPerPageTemplate = table.getRowsPerPageTemplate();

// and split options
String[] options = rowsPerPageTemplate.split("[,\\s]+");

You can find how DataTable renders the html <select> dropdown in org.primefaces.component.paginator.RowsPerPageDropdownRenderer source code.


@Kukeltje here you are a little example:

The example shows how to get the selected rows dropdown value on server side: choose a rows dropdown value and click the command button.

<p:growl id="messages" autoUpdate="true" showDetail="true"
    showSummary="true" />

<h:form>
    <p:dataTable id="table" var="elem" value="#{testTableBean.valueList}" rows="5"
        paginator="true"
        paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
        rowsPerPageTemplate="#{component.rowCount},5,10,15">
        <p:column>
            <h:outputText value="#{elem}" />
        </p:column>
    </p:dataTable>

    <p:commandButton action="#{testTableBean.execute}" process="@form" value="execute" />

    <p:commandButton process="@form" update="table"
            actionListener="#{testTableBean.valueList.add('value #' += testTableBean.valueList.size())}"
             value="add" />
</h:form>

and

@ManagedBean
@ViewScoped
public class TestTableBean implements Serializable
{
    private static final long serialVersionUID = 1L;

    private final List<String> valueList = new ArrayList<>();

    @PostConstruct
    public void init()
    {
        // add 25 dummy values
        for(int i = 0; i < 25; i++)
        {
            valueList.add("value #" + i);
        }
    }

    public void execute()
    {
        FacesContext context = FacesContext.getCurrentInstance();

        // get current component: CommandButton
        UIComponent component = UIComponent.getCurrentComponent(context);

        // get the naming container: HtmlForm
        UIComponent namingContainer = component.getNamingContainer();

        // find data table by id
        DataTable table = (DataTable) namingContainer.findComponent("table");

        // get the displayed rows value: this value is updated by DataTableRenderer.decode()
        // when user changes rows dropdown (previous ajax request)
        int rows = table.getRows();

        // add as message
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "rows: " + rows, null));
    }

    public List<String> getValueList()
    {
        return valueList;
    }
}

@ccheneson: you don't need to rely on the html side because it is generated by renderers; every information renderers know it is just available and accessible on server side.