2

I'm trying to set the value of the HTML title element (inside h:head element) dynamically based on view parameters. I'm setting the value to be used in a preRenderView system event. I've noticed that the EL to fetch the title is being evaluated before the preRenderView event is fired! Why is that and is there anything I can do?

If I grab the generated title value in a h:outputText somewhere in the page it is displayed as expected.

Facelet:

<h:head>
    <title>#{myBean.title}</title>
</h:head>

Bean:

public void preRenderView(ComponentSystemEvent event) {
    title = "Person: " + firstname " " + lastname; 
}
Ryan
  • 7,499
  • 9
  • 52
  • 61
  • Can't reproduce your problem on Mojarra 2.0.3 nor 2.1.1. What JSF impl/version are you using? – BalusC Jun 08 '11 at 16:42
  • I'm using GlassFish 3.1 and I think that comes with Mojarra 2.1. – Ryan Jun 08 '11 at 16:45
  • 1
    The example I gave above is a simplification - I'm actually using a template so that each of my pages can have their own dynamic title: <ui:insert> name="title"></ui:insert>. Maybe this matters? – Ryan Jun 08 '11 at 16:47
  • Can't reproduce on GF 3.1 as well. How exactly are you invoking the `preRenderView`? – BalusC Jun 08 '11 at 16:48
  • Ahhh... You just answered my question! I recently moved the preRenderView to a preRenderComponent on an empty component so that ajax requests wouldn't trigger the preRenderView event. That broke the dynamic title! Thanks. Let me know how to give you points because I'm new at StackOverflow. – Ryan Jun 08 '11 at 17:00
  • Ah, you're basically using Ajax requests to navigate? Anyway, by coincidence, I already posted an answer. – BalusC Jun 08 '11 at 17:01
  • Thanks again. I'm not using Ajax to navigate, but I've got a page with a TabPane and each Tab can be saved independently with Ajax. These Ajax saves trigger the preRenderView system event! There is a discussion on how to deal with this on StackOverflow actually: http://stackoverflow.com/questions/2830834/jsf-fevent-prerenderview-is-triggered-by-fajax-calls-and-partial-renders-somet – Ryan Jun 08 '11 at 17:14

1 Answers1

4

I can't reproduce this on Mojarra 2.0.2 ~ 2.0.6 and 2.1.1. I used the following test bean

@ManagedBean
@RequestScoped
public class Bean {

    private String title = "default";

    public void preRenderView(ComponentSystemEvent event) {
        title = "newtitle";
    }

    public String getTitle() {
        return title;
    }

}

And the following view:

<!DOCTYPE html>
<html lang="en" 
    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="#{bean.preRenderView}" />
    <h:head>
        <title>#{bean.title}</title>
    </h:head>
    <h:body>
        <h1>Peek-a-boo</h1>
    </h:body>
</html>

And also the following master template

<!DOCTYPE html>
<html lang="en"
    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="#{bean.preRenderView}" />
    <h:head>
        <title><ui:insert name="title">Default title</ui:insert></title>
    </h:head>
    <h:body>
        <ui:insert name="content">Default content</ui:insert>
    </h:body>
</html>

with this definition

<ui:composition template="/template.xhtml"
    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"
>
    <ui:define name="title">
        #{bean.title}
    </ui:define>
    <ui:define name="content">
        <h1>Peek-a-boo</h1>
    </ui:define>
</ui:composition>

All works equally fine. The title becomes newtitle in all cases. It also didn't really matter where the <f:event> was placed in the template. Before head, inside body, in the master template or in the template definition.

Probably the problem is in the way how you invoked preRenderView. The above examples should give you a good kickoff to build further on and to naildown your actual problen.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555