Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF f:viewParam not calling setter if located in template.xhtml

Perhaps somebody can enlighten me.

If putting

<f:metadata>
  <f:viewParam name="test" value="#{test.value}"/>
</f:metadata>

inside a template, the setter

setValue
is never called, i.e. the preRender method 'call()' is called without prior call to setter (see below in code example for reference).

If however, putting the metadata block inside the composition, it gets called as expected.

Is this normal behaviour or am I doing something wrong?
Thanks very much for any insights.
Hanspeter

For reference, here the complete code example of the non working version:

testtemplate.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:ui="http://java.sun.com/jsf/facelets">

     <f:metadata>
        <f:viewParam name="test" value="#{test.value}"/>
     </f:metadata>

     <f:event type="preRenderView" listener="#{test.call}" />

     <h:head>
        <title>Test Template</title>
     </h:head>

     <h:body>
        <ui:insert name="text" />
     </h:body>

</html>

testcomposition.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                 template="/templates/testtemplate.xhtml" 
                 xmlns:f="http://java.sun.com/jsf/core"
                 xmlns:h="http://java.sun.com/jsf/html">

     <ui:define name="text">
        some text
     </ui:define>

</ui:composition>

and here the complete code example of the working version:

testtemplate.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:ui="http://java.sun.com/jsf/facelets">

     <f:event type="preRenderView" listener="#{test.call}" />

     <h:head>
        <title>Test Template</title>
     </h:head>

     <h:body>
        <ui:insert name="text" />
     </h:body>

</html>

testcomposition.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                 template="/templates/testtemplate.xhtml" 
                 xmlns:f="http://java.sun.com/jsf/core"
                 xmlns:h="http://java.sun.com/jsf/html">

     <f:metadata>
        <f:viewParam name="test" value="#{test.value}"/>
     </f:metadata>

     <ui:define name="text">
        some text
     </ui:define>

</ui:composition>
like image 816
hpgisler Avatar asked Mar 04 '12 09:03

hpgisler


1 Answers

This is by specification. It's mentioned in <f:metadata> tag documentation:

Declare the metadata facet for this view. This must be a child of the <f:view>. This tag must reside within the top level XHTML file for the given viewId, or in a template client, but not in a template. The implementation must insure that the direct child of the facet is a UIPanel, even if there is only one child of the facet. The implementation must set the id of the UIPanel to be the value of the UIViewRoot.METADATA_FACET_NAME symbolic constant.

The simple reason is because the metadata is supposed to be view-specific, not template-specific. To achieve your requirement anyway, and you can't /don't want to place <f:metadata> inside an <ui:define> of each template client, then your best bet is using some common bean with a @ManagedProperty.

See also:

  • When using <ui:composition> templating, where should I declare the <f:metadata>?
  • ViewParam vs @ManagedProperty(value = "#{param.id}")
like image 176
BalusC Avatar answered Oct 24 '22 17:10

BalusC