简体   繁体   中英

f:ajax in ui:repeat renders h:outputText but fails to render/update h:inputText

I have a problem with <f:ajax> on a <h:inputText> inside <ui:repeat> . It successfully renders a <h:outputText> with the new value, but not a <h:inputText> (both are bound to the same property). However, if I change the <f:ajax> to render @form or @all , it works. But I obviously don't want/need to render the whole form.

I'm using Mojarra 2.2.4. Here's the index.xhtml

<h:form>
    <table>
        <ui:repeat var="line" value="#{myBean.lines}">
            <tr>
                <td>
                    <h:inputText value="#{line.number}">
                        <f:ajax event="change" execute="@this" render="desc1 desc2" listener="#{myBean.onChangeLineNumber(line)}"/>
                    </h:inputText>
                </td>
                <td>
                    <h:inputText id="desc1" value="#{line.desc}"/>
                    <h:outputText id="desc2" value="#{line.desc}"/>
                </td>
            </tr>
        </ui:repeat>
    </table>
</h:form>

And here's the relevant bit of the @ViewScoped bean:

public void onChangeLineNumber(Line line)
{
    line.setDesc("Some new text " + System.currentTimeMillis());
}

How is this caused and how can I solve it?

This is caused by a bug in state management of Mojarra's <ui:repeat> which is fixed as per issue 3215 as reported by my fellow Arjan Tijms (actually for a completely different problem, the fix just happens to solve exactly your problem as well). The fix is available in Mojarra 2.2.7 . So upgrading to at least that version should do it.

Otherwise, your best bet is to replace it by a <h:dataTable> , the component which is designed for exactly the functional requirement of rendering a HTML table based on a collection. It also saves some HTML boilerplate.

<h:form>
    <h:dataTable value="#{myBean.lines}" var="line">
        <h:column>
            <h:inputText value="#{line.number}">
                <f:ajax render="desc1 desc2" listener="#{myBean.onChangeLineNumber(line)}"/>
            </h:inputText>
        </h:column>
        <h:column>
            <h:inputText id="desc1" value="#{line.desc}"/>
            <h:outputText id="desc2" value="#{line.desc}"/>
        </h:column>
    </h:dataTable>
</h:form>

(note that I removed event="change" and execute="@this" from the <f:ajax> as those are the defaults already, there's no need to repeat the defaults)

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