简体   繁体   中英

Primefaces DataTable doesn't update the display value with a drop box, if the value attribute of <p:selectOneMenu> and <h:outputText> is different

I have a dataTable using Primefaces 3.5 as shown below .

在此处输入图片说明

Now I'm editing the second row with the id 43 as shown in the following image .

在此处输入图片说明

When I click the tick (the right most column), the row is edited as can be seen in the following picture .

在此处输入图片说明

It can easily noticed that the name of the state is changed from xxxx to zzz but the country appears to remain the same which is expected to be updated to America from Germany .

Actually, the changes have been made to the database but they don't seem to be reflected to the dataTable on completion of the rowEdit event.

To observe the change made to the country, the page is required to be reload. Only when this page is reloaded, it displays the correct data as shown below .

在此处输入图片说明


This is the column in which the country drop box is listed.

<p:ajax event="rowEdit" listener="#{stateManagedBean.onRowEdit}" update=":form:dataTable :form:systemMessages :form:messages" process=":form:dataTable :form:systemMessages :form:messages"/>
<p:ajax event="rowEditCancel" listener="#{stateManagedBean.onRowEditCancel}" update=":form:systemMessages :form:messages" process=":form:systemMessages :form:messages"/>


<p:column headerText="Country" sortBy="#{state.country.countryName}" filterBy="#{state.country.countryName}" filterMaxLength="45">                    
    <p:cellEditor>
        <f:facet name="output">
            <h:outputText value="#{state.country.countryName}" />
        </f:facet>
        <f:facet name="input">
            <p:selectOneMenu id="cmbCountryMenu" value="#{state.country.countryId}" rendered="true" editable="false" converter="#{longConverter}" converterMessage="The supplied value is incorrect." required="true" requiredMessage="Select an appropriate option." style="width:100%;">
                <f:selectItems var="country" value="#{stateManagedBean.countries}"  itemLabel="${country.countryName}" itemValue="${country.countryId}" itemLabelEscaped="true" rendered="true"/>
            </p:selectOneMenu>
        </f:facet>
    </p:cellEditor>
</p:column>

And the following is the onRowEdit() method (in JSF managed bean) which is triggered when the tick is clicked.

public void onRowEdit(RowEditEvent event)
{
    StateTable stateTable=(StateTable) event.getObject();

    if(stateService.update(stateTable))
    {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Success : ",  "The row with the id "+stateTable.getStateId()+" has been updated successfully.");
        FacesContext.getCurrentInstance().addMessage(null, message);
    }
}

The full code of JSF managed bean and JSF page .


In the rowEdit() method (as above), stateTable.getCountry().getCountryId() displays the updated countryId but using this country object to refer to the corresponding country name like stateTable.getCountry().getCountryName() just displays the old country name (not the updated one). What is the way to get around this?


Important:

In the XHTML code snippet above, the value attribute of both,

<h:outputText value="#{state.country.countryName}"/>
                       ^^^^^^^^^^^^^_^^^^^^^^^^^
<p:selectOneMenu id="cmbCountryMenu" value="#{state.country.countryId}" .../>
                                              ^^^^^^^^^^^^^_^^^^^^^^^

is different which is essential to display country names instead of displaying country ids and referring to the corresponding country ids.

If they are changed to reflect the same value attribute,

<h:outputText value="#{state.country.countryId}"/>
                       ^^^^^^^^^^^^^_^^^^^^^^^
<p:selectOneMenu id="cmbCountryMenu" value="#{state.country.countryId}" .../>
                                              ^^^^^^^^^^^^^_^^^^^^^^^

then it works as expected (Primefaces showcase example(s) demonstrate(s) just like this).


It is the same as updating a footer value dynamically showing the total of numeric values of a column. The footer is not updated while updating a row in that column. The issue has been reported here .

The problem is that you are not changing the whole country object. Because you use #{state.country.countryId} as value of the p:selectOneMenu just the property countryId of the currently selected country is changing, but the country, ie other properties like countryName will remain. 国家,即其它属性,如countryName将保持不变。

You have to change the value of p:selectOneMenu to #{state.country} and the itemValue of f:selectItems to #{country} . Look at the showcase for p:selectOneMenu .

Additionally, as country is a POJO for which no converter is available by default, you will have to implement a countryConverter and use it for the conversion when selecting an item via p:selectOneMenu .

Use the following code for the p:selectOneMenu and the this article as support for implementing the converter.

<p:selectOneMenu id="cmbCountryMenu" value="#{state.country}" rendered="true" editable="false" converter="#{countryConverter}" converterMessage="The supplied value is incorrect." required="true" requiredMessage="Select an appropriate option." style="width:100%;">
    <f:selectItems var="country" value="#{stateManagedBean.countries}"  itemLabel="#{country.countryName}" itemValue="#{country}" itemLabelEscaped="true" rendered="true"/>
</p:selectOneMenu>

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