2

I am using jstl for small testing. And it is not working how it is supposed to work

here is the small code:

<c:set var="id" value="#{mBlog.blog.id}"/>
                    ${id}    //printing  4  
                    <c:if test="${id > 0}">
                        <h:commandButton value="Update" action="#{mBlog.update}"/>  //is not rendered
                    </c:if>

                    <c:if test="${id == 0}">
                        <h:commandButton value="Save" action="#{mBlog.save}"/>  //is not rendered
                    </c:if>

I do not know what is wrong. in the display i see only 4, nothing else.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Elbek
  • 3,434
  • 6
  • 37
  • 49
  • 1
    Just to rule out the obvious, are you importing the correct taglib library for `h`? I don't see anything obviously wrong with your `c:if` conditions; you can easily check whether execution enters these conditions by putting other, non-taglib content in them. – Amos M. Carpenter Mar 19 '12 at 23:46
  • 1
    it seems the problem is not related to jstl. it is related to jsf. I have a quick question: when the load method gets called before rendering the page or after rendering? in one page i have this listener and after that the lines of code i wrote top. it is rendering jstl tags before calling load method. Is it correct? – Elbek Mar 19 '12 at 23:49

1 Answers1

6

JSTL tags and JSF UI components doesn't run in sync as you'd expect from the coding. Long story short: JSTL in JSF2 Facelets... makes sense? Read this carefully.

In your particular case, the JSTL <c:if> tag condition seems to be dependent on the result of the JSF <f:event> tag. At the moment the <c:if> runs, during the view build time, the <f:event> hasn't run yet, because it runs during pre render view event. Hence the #{mBlog.blog.id} is always null or any other default.

You need to use JSF component's rendered attribute instead. It also keeps your code cleaner.

<h:commandButton value="Update" action="#{mBlog.update}" rendered="#{mBlog.blog.id gt 0}" />
<h:commandButton value="Save" action="#{mBlog.save}" rendered="#{mBlog.blog.id eq 0}" />

You've however another potential future problem when invoking the action. Make sure that the bean is put in view scope, not in the request scope.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • thanks for answer. I did it before coming to jstl. When i do that the jsf button does not invoke method(ie update() method in bean). I splited them into two forms. Not good way nut i can survive. – Elbek Mar 20 '12 at 19:30
  • So your bean was not in view scope. See also the last sentence in my answer. This symptom is typical for request scoped beans wherein the button is rendered based on some request based condition which is not correctly evaluated during the apply request values phase of the subsequent request. If making the bean view scoped is really not an option, you'd need to move whatever the `f:event` is doing into the `@PostConstruct` method and use `@ManagedProperty` instead of ``. – BalusC Mar 20 '12 at 19:31
  • By the way i found the problem. Problem is in this page there where prerenderview listener to this page. But jsf calls this method after rendering all jstl tags. that is in jstl mBlog.blog.id coming null. I am setting blog attr in prerenderview listener, but this listener gets called after rending jstl tag in this page. I do not know but seems it should not be like that. JSF should call first listener bind to that page then should render. But it is doing in reversed order. – Elbek Mar 20 '12 at 19:33
  • No your problem is that you misunderstood the lifecycle of JSTL tags and the lifecycle of JSF. As said, please carefully read the linked answer http://stackoverflow.com/questions/3342984/jstl-in-jsf2-facelets-makes-sense Another interesting read is this: http://stackoverflow.com/questions/2118656/hcommandlink-hcommandbutton-is-not-being-invoked (point 5 is applicable for you). – BalusC Mar 20 '12 at 19:34
  • SO JSTL tags gets rendered before invoking prerenderview litener? – Elbek Mar 20 '12 at 19:35
  • As said in that linked answer, JSTL tags runs when building the JSF component tree. They do not run when rendering the JSF component tree. – BalusC Mar 20 '12 at 19:36
  • It would be more nice if you didn't ignore links. I do not post them for decoration :) – BalusC Mar 20 '12 at 19:37