How to execute a bean method inside foreach without button or link in jsf? - jsf

I am looping a list containing strings in foreach, so in every iteration the variable in foreach loop should be passed as a parameter to a bean method written inside the foreach loop. I searched many sites but everywhere I am finding solution that bean method cannot be executed without commandbutton or link. Is there any solution to execute bean method without any commandbutton or link.
<c:forEach var="name" items="#{bean.stringList}"
varStatus="loopCounter">
<!--I have to execute the method here passing "name" as parameter-->
</c:forEach>

Since EL 2.2 you can invoke non-getter methods with arguments. So you could use:
<c:forEach var="name" items="#{bean.stringList}"
varStatus="loopCounter">
<c:set var="dummy" value="#{bean.yourMethod(name)}" />
</c:forEach>
However, you are most likely are trying to solve something here that can be done in more elegant ways like a PhaseListener, a #PostConstruct method, a f:viewAction, etc.
See also
How to implement a PhaseListener which runs at end of lifecycle?
Why use #PostConstruct?
When to use f:viewAction / preRenderView versus PostConstruct?

Related

How to invoke a managed bean action method in on* attribute of a JSF component

I'd like to invoke a managed bean action method in an on* attribute. In my particular case I need to logout an user if the user is idle for 3 minutes as below:
<p:idleMonitor onidle="#{mybean.processTimeOut()}" timeout="180000" />
However, the managed bean action method is immediately invoked as the page loads. How is this caused and how can I solve it?
Like as all other on* attributes on all JSF components, the onidle attribute must represent a JavaScript callback, not a JSF backing bean action method. Any EL expressions in on* attributes would be evaluated immediately as String value expressions during generating the HTML output in expectation that they print (part of) JavaScript code.
It's exactly like as if you're doing <h:outputText value="#{mybean.processTimeout()}">. If you had removed the parentheses (), you'd have faced a PropertyNotFoundException which was also a hint at its own of it being evaluated as a value expression instead of a method expression.
In order to invoke a JSF backing bean method using JavaScript, you need an additional <p:remoteCommand>.
<p:idleMonitor onidle="processTimeout()" timeout="180000" />
<p:remoteCommand name="processTimeout" action="#{mybean.processTimeOut}" />
If you're not on PrimeFaces, head to the alternatives posted in this related answer: How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?

Primefaces dataTable call method multiple times when click commandButton. why?

<p:commandButton value="Get Name List" update="nameinfo"/>
<p:dataTable id="nameinfo" var="nam" value="#{namefinder.dofind}"></p:dataTable>
"namefinder" is managed bean [ #ManagedBean(name = "namefinder")]
"dofind" is the method which find the name list and it return the value as namefinder class object list
Problem is: "dofind" method is call 7 times.
why doing like this?
Because this is the way JSF is working, and this is correct according to Java Bean principles. Getter can be called multiple times, as much as the caller wishes.
The value attribute of p:dataTable expects getter method and is calling that method multiple times. You can't guarantee how many times will a getter be called. Instead, you should do no logic in getter method.
Instead, provide the method that will be called by your p:commandButton and refresh the collection there. dofind should be the field of JavaBean with the list of rows, no logic should be done there.

PropertyNotFoundException EL Expressions not resolving?

I have code similar to this in my facelet...
<c:foreach items=#{myBean.listOfA} var="a">
<c:foreach items=#{myBean.listOfB} var="b">
<c:set var="aName" value="#{a.name}">
<c:set var="component" value="#{b.associatedComponent(aName)}">//this wont resolve
//do stuff with component
</c:foreach>
</c:foreach>
myBean is a session scoped bean. Both A and B classes are maintained in lists inside the bean but are just model objects not managed beans.
That being said the method b.associatedComponent(a) I am assuming should resolve to b.getAssociatedComponent(A a) which I have checked many times. All methods are public. What can I do to make the method accessible to EL?
No matter what I try I get a PropertyNotFoundException on associatedComponent.
P.S. I also tried moving the method to the bean like this...
<c:set var="component" value="#{myBean.associatedComponent(b, aName)}">
This also does not work and throws the same PropertyNotFoundException.
This will not work, as the c:set tag expects a ValueExpression for the value attribute.
This means that you are only able to use properties - not methods.
If you use arguments like here #{b.associatedComponent(aName)} then what you have is a method call, not a property call. This however is a valid MethodExpression and can be used in places like the action attribute of a command link.
See the API documentation and spec for more details on this.

Execute managedBean method only for a specific page

For a page, I need to initialize potentially a huge list of object.
For now, I populate this list in a #PostConstruct method
Is it possible to execute a method only on a specific page?
Or is there a JSF tag to simply execute a method and nothing more ?
It's not an important issue for me but there must be a solution.
I'm using JSF 2.
You may add this to your page:
<f:event type="preRenderView" listener="#{backingBean.desiredMethod()}" />
This will execute the desiredMethod() before the RenderView lifecycle phase.

commandLink is not fired in a page with a param in its URI

When I call a method in a page with a param in its URI, the method is not invoked unless I pass the parameters of the uri again. For example if I have:
http://maywebsite/myapp/mypage.xhtml?mykey=myvalue
This method results in error (obviously because it renders the page again without params, but the method foo is never invoked):
<h:commandLink value="Do Action" actionListener="#{mybean.foo}"/>
So I added an ajax to only update the component, but the button is not getting fired:
<h:commandLink value="Do Action" actionListener="#{mybean.foo}">
<f:ajax render="somecomponent"/>
</h:commandLink>
When I passed the param values again, the button invokes the method just fine:
<h:commandLink value="Do Action" actionListener="#{mybean.foo}">
<f:param name="mykey" value="myvalue"/>
<f:ajax render="somecomponent"/>
</h:commandLink>
However, this button is included (ui:include) in many pages with different param keys and values. How can I invoke the method without passing the param values?
Im using glassfish 3.1.2, jsf 2.0
Apparently the bean is request scoped and the parameter plays a role in the way how the command link is rendered (e.g. by the rendered attribute on one of its parent components, or by a dynamic include of the template containing the command link).
All those conditions are namely re-evaluated during apply request values phase of the form submit. The developer has to make sure that all those conditions are exactly the same as when the form was presented to the enduser. So, when the bean is request scoped and the parameter is absent, then the command link appears as non-rendered in the component tree and this way its action won't be invoked.
Putting the bean in the view scope is the easiest way to fix this (unless you're using a dynamic <ui:include>, this is then more complicated, you'd need to turn off partial state saving for the particular view).
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated - point 5

Resources