jsf methods expression valuechanged event don't work or work different in inputtext and selectOneMenu - jsf

i'm new with jsf technology and use of managed bean.
I'm reading the Java Platform, Enterprise Edition The Java EE Tutorial release 7 but it seems to be not clear, i have different problem how in example below :
<h:selectOneMenu value="#{user.age}" onchange="submit()" valueChangeListener="#{user.ageChanged}">
<f:selectItems value="#{user.ages}" />
<f:converter converterId="javax.faces.Integer"/>
</h:selectOneMenu>
<h:inputText id="name" value="#{user.name}" required="true" validator="#{user.validateName}" valueChangeListener="#{user.nameChanged}" onchange ="submit()" />
the first one do the job, but the second not it displays:
'managedBean.User' does not have the property nameChanged.
but ageChanged is not a property but the first example do the job
but i'm using method expression to refers method nameChanged that it's present on the bean user,
i'm confusing, too with use or not of the bracket on methods expression:
valueChangeListener="#{user.nameChanged}" or valueChangeListener="#{user.nameChanged()}" what is the properly way to use methods expression?
i say this cause in another example having method with no parameters, the two approaches had different behave, first the same error about property missing, the second Apparently worked.
any help? a speak about method expressions it's appreciated to. thank you.

Related

f:convertNumber failing when currencySymbol is obtained from bean via EL

Hi in my project I need to visualize currency value, as far in my f:convertNumber
I use a fixed currencySymbol; everything is ok, but when I try to get the symbol with an expression language like this:
<h:outputText value="#{rowItem.value}">
<f:convertNumber currencySymbol="#{rowItem.getCurrencySymbol()}" groupingUsed="true" maxFractionDigits="2" type="currency" />
</h:outputText>
it is like the method getCurrencySymbol is not called, I am sure there is something I am missing.
That will happen if #{rowItem} is only available during view render time, such as when it's specified by <h:dataTable var="rowItem">, as the variable name itself already suggests. It can also happen if #{rowItem} gets changed between building the view and rendering the view, such as when it's coming from a dropdown component in the same form. The <f:convertNumber> is namely a taghandler, not an UI component. It gets executed during view build time, not during view render time. The desired #{rowItem} value is not per definition available during view build time.
This all is explained in JSTL in JSF2 Facelets... makes sense? In that answer, you can substitute "JSTL" with <f:convertNumber> as they both are taghandlers and thus have exactly the same lifecycle.
There's no solution in standard JSF API without creating a custom converter and changing the view or model. You can find possible solutions in this answer: How to set converter properties for each row/item of h:dataTable/ui:repeat?
The JSF utility library OmniFaces offers <o:converter> out the box for exactly this problem. Use it as follows:
<h:outputText value="#{rowItem.value}">
<o:converter converterId="javax.faces.Number" currencySymbol="#{rowItem.getCurrencySymbol()}" type="currency" />
</h:outputText>
(note that I omitted the other two properties as those are the default already when type="currency" is used)

JSF Combine ui:param with composite component

you have saved me many times ago with this forum, but now I am really stuck and don't now where to search any longer...
I always get the following error message (warning level, but method is also not executed correctly):
javax.el.PropertyNotFoundException: Target Unreachable, identifier 'editor' resolved to null: javax.faces.FacesException: #{cc.attrs.selectionListener}
I have isolated the problem to a few lines of code:
This is my main file:
<c:forEach items="#{myBean.getEditors()}" var="currentEditor" >
<ui:include src="#{currentEditor.getPanel()} >
<ui:param name="editor" value="#{currentEditor} />
</ui:include>
</c:forEach>
The bean.getEditors() (session scoped) just returns a list with one single entry at the moment. The 'editor' is a POJO with some simple attributes and two listener methods. The listener method does only write a log entry. (Should of course do more in future)
The file which is included looks like this:
<h:selectOneMenu value="#{editor.menuValue}>
<f:selectItem itemValue="Value 1" />
<f:selectItem itemValue="Value 2" />
<a4j:ajax event="change" listener="#{editor.menutListener()}" />
</h:selectOneMenu>
<myComponent:treeComponent id="tree" selectionListener="#{editor.treeListener()} />
The component I created consists of a richfaces tree and when clicking on a node the following method is called:
<a4j:jsFunction name="performSelection" action="#{cc.attrs.selectionListener} />
I am quite confident that the composition itself is ok because I use it also at different places. When I remove the action from the a4j:jsFunction it also works perfect.
For me it smells a bit like the bug JSF 1223
The workaround does not work for me - probably because I create the param in the forEach.
I had similar problems (ui:param + component) before, but was able to solve them with giving the full path as attribute instead of a parameter. But this does not work here because it is used in too many different places.
Please help, I cannot be the only one with this problem, but I simply do not find any other threads for this.
Edit:
Today with a fresh mind I came even closer to the problem. You can forget the whole include/ forEach stuff...
<myComponent:treeComponent id="tree" selectionListener="#{myBean.getSingleEditor().treeListener()} />
Does work, while
<ui:param name="editor" value="#{myBean.getSingleEditor()} />
<myComponent:treeComponent id="tree" selectionListener="#{editor.treeListener()} />
does not work.
Well the JAVA code is performed, but the error is written to the log and the render and oncomplete method of the jsFunction do not work.
I also tried to use "data" instead of "action" for testing. No error is written to log, but JAVA method is not even called.
After many days of try&error I found a solution that is working for me:
I splitted up the listener method to one parameter with the JAVA class and one parameter with the the method name (as simple String)
The action method now looks like:
<a4j:jsFunction name="performSelection" action="#{cc.attrs.listenerClass[cc.attrs.listenerMethodName]}" />
Not nice but working... Perhaps it helps someone - or anybody can explain more...
By the way, the following was not working for me:
<a4j:jsFunction name="performSelection" action="#{cc.attrs.listenerClass[staticMethodName]}" />
While this was ok...
<a4j:jsFunction name="performSelection" action="#{cc.attrs.listenerClass.staticMethodName()}" />
Don't know - perhaps my head is running agains the same wall again and again...

How to access object methods using dataTable in JSF?

I'm working with LastFM api, let's say I have a class called Artist which I call in this dataTable:
<h:dataTable var="artist" value="#{personEAO.topArtists}" >
<h:column>Artist : #{artist.name} </h:column>
</h:dataTable>
Artit have a field which refers to his picture :
artist.getImageURL(ImageSize.LARGE)
Which works fine, but how do I call this method in my jsf page using dataTable ?
I searched around for Javadocs, but I couldn't find them anywhere. The answer depends on what kind of constant ImageSize.LARGE is.
If ImageSize is an enum, just do:
<h:graphicImage value="#{artist.getImageURL('LARGE')}" />
But if it isn't and is thus a public static constant, then one of the ways is to wrap it in some helper bean which returns exactly that:
<h:graphicImage value="#{artist.getImageURL(someHelperBean.ImageSize_LARGE)}" />
I of course assume that your environment supports EL 2.2.

Populate by code SelectOneMenu based on custom meta-data in attributes

I need a solution to populate by code SelectOneMenu using some meta-data specified as an attribute to this component.
Here is the detail of my requirement.
1) The developer would specify some thing like this:
<h:selectOneMenu id="someComponent" value="#{someController.someModel.someField}">
<f:attribute name="entity" value="somepackage.SomeEntity" />
</h:selectOneMenu>
2) When the page containing the above is requested for the first time, the server should be able to read the 'entity' attribute
3) Once the 'entity' is read, the server will do the needful to populate dynamically 'someComponent'.
I have no issue with the code that should use the 'entity' attribute and generate the content to be show in 'someComponent'. My issue is to found the appropriate place to call efficiently this code.
I have tried the PhaseEventListener for 'After Render Response Phase' but with no luck. It looks like I'm missing something fundamental as I'm new to JSF.
Have someone went through the same experiment?
Thank you in advance.
Younes Ouadi
If you target an EL 2.2 container which supports invoking methods with arguments and/or supply JBoss EL with your webapp so that it works on EL 2.1 as well, then it should be possible with the following construct:
<h:selectOneMenu id="someComponent" value="#{someController.someModel.someField}">
<f:selectItems value="#{someProvider.selectItems('somepackage.SomeEntity')}" />
</h:selectOneMenu>
with
public List<SelectItem> getSelectItems(String className) {
// ...
}
I'd introduce some lazy loading and/or request-based caching mechanism as well as a getter can be called more than once during bean's life.

What is the JSF behaviour, if you bind the same backing bean property to two input fields in the same form?

Is there a defined behaviour in JSF, if two input fields are bound to the same session scoped Backing Bean property.
Here is my code snippet
<h:form id="myForm">
<h:inputText id="field1" value="#{TheBackingBean.theProperty}" />
<h:inputText id="field2" value="#{TheBackingBean.theProperty}" />
<h:commandButton id="continueButton" action="#{TheBackingBean.doSomething}" />
</h:form>
My question: If field1 and field2 receive different values, what will be bound to the backing bean property? Is this even allowed?
I know this is a crude scenario. My motivation is, that we have htmlunit tests running for our application. In our JSF application we want to use a cool ajaxified custom component. This doesnt work together very well with htmlunit. So my idea was, I just put in a hidden field that binds to the same property. The unit test then fills the hidden field instead of the "real" thing.
Regards
I think this kind of code is allowed, but I am not sure of the value of theProperty after the submission. What I think is that JSF will do the following:
TheBackingBean.setTheProperty(field1.value);
TheBackingBean.setTheProperty(field2.value);
However, nothing - as far as I know - specifies the order of the setter calls. Thus, after the update values JSF phase, you will not be sure if theProperty will be equal to field1.value or field2.value.
Concerning your scenario, you say that you want to bind the same property to an inputText and an hiddenText. As the hiddenText will not submit its value, unlike the inputText, this problem will not occur. Indeed, if you have this kind of JSF code:
<h:inputText id="field1" value="#{TheBackingBean.theProperty}"/>
<h:inputHidden id="field2" value="#{TheBackingBean.theProperty}"/>
then JSF will only do:
TheBackingBean.setTheProperty(field1.value);
during the submission phase.

Resources