Hossein Forghani
Hossein Forghani

Reputation: 51

How to disable sorting on Primefaces lazy datatable?

I have a datatable with lazy data model and pagination. I want to disable default sorting when I click on "search" button and enable it again when I click on "display" button. So didn't put "sortBy" in my xhtml file and instead, I set it dynamically in my backing bean.

Everything works properly until I click on the header to flip sort order between descending and ascending. It means the "search" button disables the sorting and "display" button enables it correctly if I don't click on the header. But when I click on the header and then click the "search" button, in load funciton of LazyDataModel, value of the argument sortField is "date" and the datatable will be sorted by date though the "date" column is not colored apparently!!

This is my datatable:

<h:form id="contents-form">
...
    <p:dataTable id="tbl" widgetVar="tbl" var="msg" value="#{homeController.messagesModel}" lazy="true"
                 currentPageReportTemplate="سطر {startRecord}-{endRecord} از {totalRecords}"
                 paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                 paginator="true" rows="10" rowsPerPageTemplate="5,10,15"
                 emptyMessage="هیچ پیامکی وجود ندارد."
                 selection="#{homeController.selectedMessages}" rowSelectMode="checkbox"
                 rowKey="#{msg.id}" filteredValue="#{homeController.filteredMessage}"
                 editable="true" editMode="cell"
                 style="width:100%" dir="rtl">

        <f:facet name="header">
            <p:commandButton value="خروجی" action="#{homeController.prepareExport}" icon="fa fa-save"
                             update="export-dlg-box" oncomplete="PF('exportDlgBox').show()"/>
            <p:commandButton value="واژگان" action="#{homeController.showListTermsChart}"
                             icon="fa fa-bar-chart" update="contents-form chart-form msgs"
                             oncomplete="PF('chartDlgBox').show()"/>
        </f:facet>

        <p:ajax event="cellEdit" listener="#{homeController.onCellEdit}" oncomplete="updateDescFilter()"/>

        <p:column selectionMode="multiple" style="width:16px;text-align:center"/>

        <p:column headerText="فرستنده" style="width:100px" filterBy="#{msg.sender.number}"
                  sortBy="#{msg.sender.number}">
            <p:commandLink action="#{homeController.setPhoneNumToShow(msg.sender)}" update="phone-form"
                           oncomplete="PF('phoneDlgBox').show()" styleClass="simple-command-link">
                <h:outputText value="#{msg.sender.number}"/>
            </p:commandLink>
        </p:column>

        <p:column headerText="گیرنده" style="width:100px" filterBy="#{msg.receiver.number}"
                  sortBy="#{msg.receiver.number}">
            <p:commandLink action="#{homeController.setPhoneNumToShow(msg.receiver)}" update="phone-form"
                           oncomplete="PF('phoneDlgBox').show()" styleClass="simple-command-link">
                <h:outputText value="#{msg.receiver.number}"/>
            </p:commandLink>
        </p:column>

        <p:column headerText="متن" sortBy="#{msg.text}">
            <h:outputText value="#{msg.getTrimmedText()}"/>
        </p:column>

        <p:column headerText="زمان" style="width:100px" filterBy="#{msg.date}" sortBy="#{msg.date}">
            <f:facet name="filter">
                <p:calendar pattern="yyyy-MM-dd">
                    <p:ajax event="dateSelect" oncomplete="PF('tbl').filter()" update="tbl"/>
                </p:calendar>
            </f:facet>
            <h:outputText value="#{msg.getJalaliDate()}"/>
        </p:column>

        <p:column headerText="منبع" style="width:70px" filterBy="#{msg.source}" sortBy="#{msg.source}">
            <f:facet name="filter">
                <p:selectOneMenu onchange="PF('tbl').filter()" style="width:30px; direction:ltr">
                    <f:selectItem itemLabel="همه" itemValue="#{null}" noSelectionOption="true"/>
                    <f:selectItems value="#{homeController.sources}" var="source"
                                   itemValue="#{source}" itemLabel="#{source}"/>
                </p:selectOneMenu>
            </f:facet>
            <h:outputText value="#{msg.source}"/>
        </p:column>

        <p:column headerText="توضیح" style="width:70px" filterBy="#{msg.description}"
                  sortBy="#{msg.description}">
            <f:facet name="filter">
                <p:selectOneMenu id="desc-filter-select" onchange="PF('tbl').filter()"
                                 style="width:30px; direction:ltr">
                    <f:selectItem itemLabel="همه" itemValue="#{null}" noSelectionOption="true"/>
                    <f:selectItems value="#{homeController.descriptions}" var="desc"
                                   itemValue="#{desc}" itemLabel="#{desc}"/>
                </p:selectOneMenu>
            </f:facet>
            <p:cellEditor>
                <f:facet name="output"><h:outputText value="#{msg.description}"/></f:facet>
                <f:facet name="input"> <p:inputText id="desc-input" value="#{msg.description}"
                                                    style="width:85%"/></f:facet>
            </p:cellEditor>
        </p:column>

        <p:column headerText="جزئیات" style="width:40px">
            <p:commandLink action="#{homeController.setMessageToShow(msg)}" ajax="true"
                           update="img-dlg-box" oncomplete="PF('imgDlgBox').show()">
                <i class="fa fa-blue fa-desktop"/>
            </p:commandLink>
        </p:column>

        <p:column headerText="مشاهده گفتگو" style="width:40px">
            <p:commandLink action="#{homeController.showConversation(msg.sender, msg.receiver)}"
                           ajax="true" update="conv-dlg-box" oncomplete="PF('convDlgBox').show()">
                <i class="fa fa-blue fa-wechat"/>
            </p:commandLink>
        </p:column>
    </p:dataTable>
</h:form>

My "search" button:

<p:commandButton value="جست‌وجو" action="#{homeController.search}" update=":contents-form:tbl msgs"
                                     icon="fa fa-search"/>

My "display" button:

<p:commandButton value="نمایش" icon="fa fa-desktop" action="#{homeController.loadArchive}"
                 update="contents-form msgs"/>

search method in the backing bean:

public void search() {
    if (this.selectedArchive == null) {
        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, "خطا!", "لطفا یک مجموعه را انتخاب کنید"));
        return;
    }

    if ((this.textQuery != null && !this.textQuery.equals(""))
            || (this.selectedNodes != null && this.selectedNodes.length > 0)) {
        logger.info(String.format("searching '%s' in archive %d ...", this.textQuery, this.selectedArchive.getId()));
        List<String> selectedWords = this.getSelectedWords(this.selectedNodes);
        searchText(this.textQuery, selectedWords);
    } else {
        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, "خطا!", "برای جست‌وجو هیچ متنی وارد نشده و هیچ واژه‌ای انتخاب نشده است."));
        return;
    }

    extractChoices();

    // Disable default sorting:
    DataTable table = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent(":contents-form:tbl");
    table.setValueExpression("sortBy", null);
    table.setValueExpression("sortOrder", null);
}

And loadArchive method in the backing bean:

public void loadArchive() {
    if (this.selectedArchive == null) {
        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, "خطا!", "لطفا یک مجموعه را انتخاب کنید"));
        return;
    }
    this.messagesModel = new LazyMessageModel(this.selectedArchive, true, this.messageService);

    extractChoices();

    // Enable default sorting:
    FacesContext context = FacesContext.getCurrentInstance();
    ExpressionFactory ef = context.getApplication().getExpressionFactory();
    DataTable table = (DataTable) context.getViewRoot().findComponent(":contents-form:tbl");
    ValueExpression sortVe = ef.createValueExpression(context.getELContext(), "#{msg.date}", Message.class);
    table.setValueExpression("sortBy", sortVe);
    table.setSortOrder("descending");

    logger.info(String.format("archive %d loaded", (this.selectedArchive.getId())));
}

Spec:

Upvotes: 2

Views: 2294

Answers (1)

Hossein Forghani
Hossein Forghani

Reputation: 51

I finally found a clean solution! Just I must reset the table in addition to setting sortBy null after clicking "search" button:

public void search() {
    // Do something ...
    DataTable table = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent(":contents-form:tbl");
    table.reset();
    table.setValueExpression("sortBy", null);
}

Upvotes: 3

Related Questions