0

I'm using PrimeFaces 3.5 and I faced a problem with partial page rendering. I need to load content from a Facelet file into "dynamic" part of a template.

index.xhtml:

<f:view> 
    <h:form id="form1">
        <p:outputPanel layout="block">
            <p:commandButton action="content-2?faces-redirect=false" update="display" />
        </p:outputPanel>
        <p:outputPanel id="display" layout="block">
            content 1
        </p:outputPanel>
    </h:form>
</f:view>

content-2.xhtml:

<h:body>
    content 2 loaded
</h:body>

When I click on the <p:commandButton>, then content-2.xhtml will be opened. However, this refreshes the whole page. The XML response contains like this:

<partial-response><changes><update id="javax.faces.ViewRoot">

When I change the action attribute to a method expression:

<f:view> 
    <h:form id="form1">
        <p:outputPanel layout="block">
            <p:commandButton action="#{myBean.increment}" update="display" />
        </p:outputPanel>
        <p:outputPanel id="display" layout="block">
            #{myBean.count}
        </p:outputPanel>
    </h:form>
</f:view>

Then the display block updates as expected. The XML response contains like this:

<partial-response><changes><update id="form:display">

Why does the action="content-2?faces-redirect=false" way update the entire page?

I also tried to <ui:composition>, but in this case this reloads "static" part of template. I do not want it.

Mrusful
  • 1,503
  • 1
  • 18
  • 32
  • Are you implying that `#{myBean.method}` returns `content-2.xhtml`? The `faces-redirect=false` is the default already, I don't understand why you're explicitly mentioning this. Are you implying that `action="content-2.xhtml"` behaves differently? – BalusC Apr 10 '13 at 19:56
  • No, sorry, i did update part which with #{myBean.method}. Method body looks like `count++`. And i try `action="content-2.xhtml"` its also refresh `javax.faces.ViewRoot` but `action="#{myBean.increment}"` refresh `display`. I thought what `faces-redirect=false` must have assignment `true` or `false`. – Mrusful Apr 11 '13 at 17:28

1 Answers1

0

This is fully normal and expected behavior if you navigate to a different view by supplying a non-null outcome in the action attribute. JSF will then overrule the partial render with a render of @all. JSF/Facelets won't somehow automagically retain the common components in the tree as you seemed to expect. If you intend to dynamically change the component tree during a partial page rendering, then you need inside the <p:outputPanel id="display" layout="block"> either a dynamic include something like this (section is just an integer)

<ui:include src="section#{bean.section}.xhtml" />

or multiple conditionally rendered sections

<ui:fragment rendered="#{bean.section == 1}"><ui:include src="section1.xhtml" /></ui:fragment>
<ui:fragment rendered="#{bean.section == 2}"><ui:include src="section2.xhtml" /></ui:fragment>
<ui:fragment rendered="#{bean.section == 3}"><ui:include src="section3.xhtml" /></ui:fragment>
<ui:fragment rendered="#{bean.section == 4}"><ui:include src="section4.xhtml" /></ui:fragment>

Each has its own pros and cons depending on whether the include file contains form/input/command components and/or references view scoped beans. The <ui:include> runs namely during view build time like JSTL. See for more detail also JSTL in JSF2 Facelets... makes sense?

The presence of faces-redirect=false is not significant as it's the default already. If it were true, then a JavaScript window.location would be invoked on the target URL.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks, think i understand now. I thought how i can do so what all blocks on the page will might update independently of state of the server. – Mrusful Apr 11 '13 at 18:11