简体   繁体   中英

p:commandButton not working within a p:dataTable while using filter

I am using JSF, Primefaces 5.2 and GlassFish 4.1.

I have set up a simple project to test and replicate my larger issue and found it is repeatable within the test project.

I have a simple page with a simple list of objects. I am using the <p:dataTable> and using the global search capability and pagination.

Table Code

<ui:define name="content">
    <h:form id="carsForm" >
        <p:dataTable id="singleDT" var="c" value="#{testFlow.cars}" widgetVar="carsTable" rows="10" paginator="true"
                     paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                     rowsPerPageTemplate="5,10,15" emptyMessage="No cars found with the given criteria" reflow="true"
                     filteredValue="#{testFlow.filteredCars}">

            <f:facet name="header">
                <p:outputPanel class="fright">
                    <h:outputText value="Search all fields: " />
                    <p:inputText id="globalFilter" onkeyup="PF('carsTable').filter()" style="width:200px" placeholder="Enter keyword" />
                </p:outputPanel>
                <p:outputPanel class="Fleft">
                    <p:commandButton value="New Car" action="addCar" />
                </p:outputPanel>
                <div class="EmptyBox5"></div>
            </f:facet>

            <p:column filterBy="#{c.id}" headerText="ID" sortBy="#{c.id}" >
                <h:outputText value="#{c.id}"/>
            </p:column>

            <p:column filterBy="#{c.m}" headerText="Model Year" sortBy="#{c.modelYear}" >
                <h:outputText value="#{c.modelYear}"/>
            </p:column>

            <p:column filterBy="#{c.make}" headerText="Make" sortBy="#{c.make}" >
                <h:outputText value="#{c.make}"/>
            </p:column>

            <p:column filterBy="#{c.model}" headerText="Model" sortBy="#{c.model}" >
                <h:outputText value="#{c.model}"/>
            </p:column>

            <p:column filterBy="#{c.color}" headerText="Color" sortBy="#{c.color}" >
                <h:outputText value="#{c.color}"/>
            </p:column>

            <p:column style="width: 200px; text-align: center">
                <p:commandButton actionListener="#{testFlow.removeCar(c)}" value="Delete" update="singleDT messages" ajax="true" >
                    <p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
                </p:commandButton>
            </p:column>
        </p:dataTable>

        <div class="EmptyBox5"></div>
        <p:panel>
            <p:commandButton action="returnFromTestFlow" value="Exit the Flow" />
        </p:panel>
    </h:form>

    <p:messages id="messages" autoUpdate="true" closable="true" />

    <p:confirmDialog global="true" showEffect="fade" hideEffect="explode">
        <p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
        <p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
    </p:confirmDialog>
</ui:define>

My Controller has a simple method to remove the object.

Method

public String removeCar(Inventory c) {
    String redirectTo = "/testFlow/testFlow";

    try {
        this.cars.remove(c);
        iFacade.remove(c);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }

    return redirectTo;
}

When I remove all the filtering and sorting, the method is called after I click yes and the row is deleted. While the filtering and sorting is in place, however, the entire table just re displays as empty but no method is ever called. No error appears, and while using the debugger it never hits a break-point within the method in question.

Any help or direction would be greatly appreciated.

I think the problem is that the datatable is first rendered using the list you provided, but when you press a button it searches through the filtered list and since this is empty at first it cannot locate the button. Notice on the other hand, that if you enter a search criteria and delete it again, the buttons work. This is because the filtered list has been populated and the button can now be located. To solve this problem you need to populate the filtered list with all the values pre render. In your case:

In your backing bean:

public void init()
{
    if(!FacesContext.getCurrentInstance().isPostback())
    {
        filteredCars = cars;
    }
}

In your xhtml file:

<f:event type="preRenderView" listener="#{testFlow.init}"/>;

Another way is using the @PostConstruct annotation on your init() function instead of <f:event type="preRenderView /> which is clearer code, but, in my opinion, a bit vague in terms of when the function is called.

Had the same problem, @djst solution didn't work for me, but I ended up fixing the problem by using Omnifaces form ( o:form ) instead of standard h:form . Not sure why, though, but may be worth a try.

当您使用过滤时,primefaces 创建一个列表并显示在结果中,当您从主列表中删除一个项目时,它与显示列表无关,这可能会导致您遇到的问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM