1

I am in a little bit of trouble with my preRenderView-Event. My page also uses a commandbutton to submit data but unfortunately the preRenderView-Event is always called before the buttons action is invoked.

The preRenderView-Event is responsible for loading data from a service. Since the page is simple and doesnt have to store any data I dont need any Session or ViewScoped-Beans.

As far as I understood the event is called in the Render-Response-Phase and the action in the button should happen somewhat earlier.

<h:body>
    <f:metadata>
        <f:viewParam name="id" value="#{bean.id}" converter="converter.SetOfLongConverter"/>
        <f:event type="preRenderView" listener="#{bean.initializeData}" />
    </f:metadata>

    <ui:composition template="/META-INF/templates/myTemplate.xhtml">
        <ui:param name="title" value="#{bean.title}"/>
        <ui:define name="content">
            <h:outputText value="#{bean.description}" />
            <h:form>
                    <h:panelGrid columns="2">
                        <h:outputLabel value="Model" for="model" />
                        <h:inputText id="model" value="#{bean.model}" />
                        <h:outputLabel value="Manufacturer" for="manufacturer" />
                        <h:inputText id="manufacturer"
                            value="#{bean.manufacturer}" />
                        <h:outputLabel value="Year" for="year" />
                        <h:inputText id="year" value="#{bean.year}" />
                    </h:panelGrid>
                    <h:commandButton value="Create" type="submit"  action="#{bean.create}" rendered="#{bean.createMode}"/>
                    <h:commandButton value="Save" type="submit" action="#{bean.save}" rendered="#{!bean.createMode}" />
                </h:form>       
        </ui:define>
    </ui:composition>
</h:body>

I added some Console-Messages to verify when the method in the bean is called and when I have the preRenderView-event it never happens.

Any advice what I am doing wrong here?

lostiniceland
  • 3,729
  • 6
  • 38
  • 50

1 Answers1

1

The <f:metadata> has to go inside <ui:define> of an <ui:composition>.

See also <f:metadata> tag documentation (emphasis mine):

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.


Update: it turns out that the action method is not invoked at all. You've there a rendered attribute on the command button which seems according the symptoms to be dependent on a request based variable instead of a view based variable. Putting the managed bean in the view scope should fix this problem. See also commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the clarification but it still doesnt trigger the action. I used the example provided by the link, defining a f:view and a metadata define-section. – lostiniceland Mar 19 '12 at 15:04
  • Oh, the bean action method is **not invoked at all**? Your question was not that clear. I understood that it was invoked *after* the listener method, which I guessed to be caused by wrong location of the `` which may cause undeterministic behaviour. I now see that you've a `rendered` attribute on the button (which escaped my attention because it was outside the viewport). In that case, putting bean in view scope should fix it. See also point 5 of http://stackoverflow.com/questions/2118656/hcommandlink-hcommandbutton-is-not-being-invoked – BalusC Mar 19 '12 at 15:06
  • thats it...thanks. Maybe I can find another solution so I wont need the ViewScope. – lostiniceland Mar 19 '12 at 15:17
  • 1
    Pass the request based condition where the `rendered` attribute depends on along to the next request by `` nested inside ``. – BalusC Mar 19 '12 at 15:23