1
votes

I have a JSF 2.2.0-m12 application with primefaces 3.5. Since I ported the application from JBoss 7.1.1 to Tomcat 7.0.39, the first change of an inputfield (inputtext, slider, button,...) after reloading a page works fine, but the second change does nothing. I searched for the differences between the first and the second request:

1st request:

  • JSF phases: Phases from 1 till 6 are executed
  • In Firebug 'network -> all -> POST zinsrechner.xhtml -> post' is a viewstate:
contentForm contentForm
contentForm:inputZinsatz        2.0
contentForm:j_idt157:anla...    277
contentForm:j_idt157:maxA...    25
contentForm:j_idt157:slid...    277
contentForm:j_idt72:saveA...    10000
contentForm:j_idt72:saveA...    20000
contentForm:selectSparArt       false
javax.faces.ViewState        -1622287370124327744:4775655032591022279
javax.faces.behavior.even...    slideEnd
javax.faces.partial.ajax        true
javax.faces.partial.event       slideEnd
javax.faces.partial.execu...    contentForm:j_idt157:sliderAnlageDauer
javax.faces.partial.rende...    contentForm
javax.faces.source              contentForm:j_idt157:sliderAnlageDauer

2nd request:

  • JSF phases: After Phase 1 the 6 is executed
  • In Firebug 'network -> all -> POST zinsrechner.xhtml -> post' is no viewstate:
contentForm contentForm
contentForm:inputZinsatz        2.0
contentForm:j_idt157:anla...    460
contentForm:j_idt157:maxA...    25
contentForm:j_idt157:slid...    460
contentForm:j_idt72:saveA...    10000
contentForm:j_idt72:saveA...    20000
contentForm:selectSparArt       false
javax.faces.behavior.even...    slideEnd
javax.faces.partial.ajax        true
javax.faces.partial.event       slideEnd
javax.faces.partial.execu...    contentForm:j_idt157:sliderAnlageDauer
javax.faces.partial.rende...    contentForm
javax.faces.source              contentForm:j_idt157:sliderAnlageDauer

Now I'm not sure, if the missing ViewState causes the incorrect behaviour.

In my pages are three not enclosing forms. For each form is a hidden viewstate tag rendered in the outcoming html(condensed):

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Zinsrechner</title>
<body>
<div class="wrapper">
    <form id="headerForm" name="headerForm" method="post"
        action="/Tools_Web/pages/rechner/zinsrechner.xhtml"
        enctype="application/x-www-form-urlencoded">
        <input type="hidden" name="headerForm" value="headerForm" />

        <header>
            <html xmlns="http://www.w3.org/1999/xhtml">
                <script type="text/javascript"> ... </script>
                <nav>...</nav>
            </html>
            <h1>Zinsrechner</h1>
        </header>
        <input type="hidden" name="javax.faces.ViewState"
            id="j_id1:javax.faces.ViewState:0"
            value="863948539220421748:307506195687956782" autocomplete="off" />
    </form>


    <div id="contentOutline">
        <div id="content">
            <div class="wrapper">
                <form id="contentForm" name="contentForm" method="post"
                    action="/Tools_Web/pages/rechner/zinsrechner.xhtml"
                    enctype="application/x-www-form-urlencoded">
                    <input type="hidden" name="contentForm" value="contentForm" />
                    <div id="sidebar"></div>
                    <div id="zinsrechner">
                        <!-- Headline -->
                        <header>
                            <div style="padding: 0 1em; float: right;">
                                <span
                                    title="Zinssatz pro Jahr"><span id="contentForm:j_idt70"
                                    class="ui-inplace ui-hidden-container"><span
                                        id="contentForm:j_idt70_display" class="ui-inplace-display"
                                        style="display: inline">2.0%</span><span
                                        id="contentForm:j_idt70_content" class="ui-inplace-content"
                                        style="display: none"><input
                                            id="contentForm:inputZinsatz" name="contentForm:inputZinsatz"
                                            type="text" value="2.0"
                                            style="width: 70px; right: 0px; top: 0 position:absolute"
                                            class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" />
                                        <script id="contentForm:inputZinsatz_s" type="text/javascript">PrimeFaces.cw('InputText','widget_contentForm_inputZinsatz',{id:'contentForm:inputZinsatz',behaviors:{change:function(event) {mojarra.ab('contentForm:inputZinsatz',event,'valueChange','@form','@form headerForm footerForm')},change:function(event) {PrimeFaces.ab({source:'contentForm:inputZinsatz',event:'change',process:'contentForm:inputZinsatz',update:'contentForm'}, arguments[1]);}}});</script></span></span>
                                <script id="contentForm:j_idt70_s" type="text/javascript">PrimeFaces.cw('Inplace','widget_contentForm_j_idt70',{id:'contentForm:j_idt70',effect:'fade',effectSpeed:'normal',event:'click',toggleable:true});</script>
                                </span>
                            </div>
                        </header>


                        <div>
                            <!-- More input elements -->
                        </div>
                    </div>
                    <input type="hidden" name="javax.faces.ViewState"
                        id="j_id1:javax.faces.ViewState:0"
                        value="863948539220421748:307506195687956782" autocomplete="off" />
                </form>
            </div>
        </div>
    </div>
    <form id="footerForm" name="footerForm" method="post"
        action="/Tools_Web/pages/rechner/zinsrechner.xhtml"
        enctype="application/x-www-form-urlencoded">

        <input type="hidden" name="footerForm" value="footerForm" />

        <footer></footer>
        <input type="hidden" name="javax.faces.ViewState"
            id="j_id1:javax.faces.ViewState:0"
            value="863948539220421748:307506195687956782" autocomplete="off" />
    </form>
</div>

I tried unsuccessfully to solve the problem with the JS described here: h:commandButton/h:commandLink does not work on first click, works only on second click

and the following configurations in web.xml:

<context-param>
<param-name>com.sun.faces.autoCompleteOffOnViewState</param-name>
<param-value>false</param-value>
</context-param>

<context-param>
<param-name>com.sun.faces.enableViewStateIdRendering</param-name>
<param-value>false</param-value>
</context-param>

Edited This is the xhtml page:

<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
template="/template/baseLayout.xhtml"
xmlns:ad="http://java.sun.com/jsf/composite/components/ad">
<ui:param
    name="title"
    value="Zinsrechner" />
<ui:param
    name="bgClass"
    value="whiteGrid" />
<ui:define name="content">
    <div id="zinsrechner">
        <!-- Headline -->
        <header>
            <p:selectOneButton
                id="selectSparArt"
                value="#{zinsrechner.monthly}"
                styleClass="selectSparArt">
                <f:selectItem
                    itemLabel="Anlagebetrag"
                    itemValue="#{false}" />
                <f:selectItem
                    itemLabel="Sparbetrag"
                    itemValue="#{true}" />
                <p:ajax
                    event="change"
                    update="contentForm"
                    process="selectSparArt"
                    listener="#{zinsrechner.onMonthlyChange()}" />
            </p:selectOneButton>
            <div style="padding: 0 1em; float: right;">
                <span title="Monatlicher Sparbetrag">
                    <p:inplace label="#{zinsrechner.saveAmount}€" rendered="#{zinsrechner.monthly}">
                        <p:inputText
                            style="width: 70px; margin-right: 10px;"
                            id="inputSparbetrag"
                            value="#{zinsrechner.saveAmount}">
                            <p:ajax
                                event="change"
                                update="contentForm"
                                process="inputSparbetrag"
                                listener="#{zinsrechner.onSaveAmountChange()}" />
                            </p:inputText>
                        </p:inplace>
                    </span>

                <span title="Zinssatz pro Jahr">
                    <p:inplace label="#{zinsrechner.interestRate}%">
                        <p:inputText
                            style="width: 70px; right:0px; top: 0 position:absolute"
                            id="inputZinsatz"
                            value="#{zinsrechner.interestRate}">
                            <p:ajax
                                event="change"
                                update="contentForm"
                                process="inputZinsatz"
                                listener="#{zinsrechner.onInterestRateChange()}" />
                                <f:ajax execute="@form" render="@form :headerForm :footerForm"></f:ajax>
                        </p:inputText>
                    </p:inplace>
                </span>
            </div>
        </header>

        <!-- Y-Achse -->
        <ad:yAxis
            component="#{zinsrechner}"
            editable="true"
            inputId="saveAmount"
            inputMaxValueId="saveAmountMax"
            rendered="true"
            sliderId="saveAmountSlider"></ad:yAxis>

        <!-- Chartcontainer -->
        <ad:barChart
            component="#{zinsrechner}"
            rendered="true"
            renderSumBarLeft="false"
            renderSumBarRight="false" />


        <!-- X-Achse -->
        <ad:xAxis
            component="#{zinsrechner}"
            sliderId="sliderAnlageDauer"
            editable="true"
            inputId="anlagedauer"
            inputMaxValueId="maxAnlagedauer"
            rendered="true"
            renderSumBarLeft="false"
            renderSumBarRight="false"></ad:xAxis>
    </div>
</ui:define>

What can I do to pass the ViewStatus to the server? Could the missing ViewState be the reason for the incorrect behaviour?

Thanks for your help. If you need more information, just ask!

1
Maybe you should add source code - the xhtml and the primefaces components that you use. If "after reloading a page" works but after that it stops working, sounds much like an javascript event handler that got lost.Jens
@Jens: Thanks for your comment. I added the xhtml page.Karina
PF 3.5 is not designed for JSF 2.2. You should use PF 4.0 for that. Please test using regular JSF components to exclude PF 3.5 from being the cause, or downgrade to JSF 2.1. By the way, having both <p:ajax> and <f:ajax> in a single input component doesn't look right.BalusC
BalusC is right. If you are not using anything in particular from JSF 2.2 you should downgrade to JSF 2.1. Also, please explain the intention of the two ajax components (that BalusC spotted). Or remove them (if mistaken) and try again.Jens
Thanks BalusC and Jens, that was the point. After downgrading to JSF 2.1 it works. The <f:ajax> was a test, which I forgot to delete.Karina

1 Answers

2
votes

Like BalusC and Jens said the problem are the versions of Primefaces and JSF:

PF 3.5 is not designed for JSF 2.2. You should use PF 4.0 for that. Please test using regular JSF components to exclude PF 3.5 from being the cause, or downgrade to JSF 2.1.

After downgrading to JSF 2.1 it works.