command link doesn't work in ui:repeat - jsf-2

I have a <p:commandLink> inside a <ui:repeat> in my xhtml page, my bean scope is set to 'View'. I am using JSF2.0 with primefaces 3.4. Here is the code snippet.
<ui:repeat value="#{bean.selectedJob.conversions}" var="conversion">
<p:commandLink styleClass="contextMenuItem"
update=":form:outputParent" immediate="true"
action="#{bean.method()}"
oncomplete="$('#outputFilterContextMenu').hide();">
<h:outputText value="#{conversion.convType}: #{conversion.convNodeName}" />
</ui:repeat>
but command link doesn't invoke the back end method. I have tried it with actionListener instead of action but that doesn't work either.
Any help or suggestion will be highly appreciated.
Thanks

When the commandLink is inside <ui:repeat>, the bean, which action is called, must be SessionScoped.

Related

JSF Ajax called only 1st time

In JSF2 I have an XHTML like this:
<h:form id="myForm">
...
<c:forEach items="#{myController.header}" var="hd" varStatus="count">
#{hd}
<h:selectOneMenu value="#{myController.type[count.index]}" id="formtype" >
<f:selectItem itemValue="Nop" itemLabel="Nop" />
<f:selectItem itemValue="Yep" itemLabel="Yep" />
<f:ajax render="#form" />
</h:selectOneMenu>
#{myController.type[count.index]}
<h:selectBooleanCheckbox value="#myController.valid[count.index]}" id="valid">
<f:ajax render="#form"/>
</h:selectBooleanCheckbox>
#{myController.valid[count.index]}
</c:forEach>
...
</h:form>
And my managed bean has:
private String[] type;
private boolean[] valid;
which I initialise (type = new String[...]; and assign a value to each position) when the named bean is 1st loaded.
If I modify the combo or the check box, it works, the value is changed in the managed bean and the new value gets printed (rendered) in the JSF page. But only the 1st time. Next changes do not modify anything at all. It is strange because I have similar code in other apps and works fine, so I am doing something incorrectly but cannot find it. My template has a h:header and I cannot see any logs in the JS console or in TomEE (I only see .INFO - The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/myApp]] after start() had already been called. The second call will be ignored but I think it is unrelated). I have tried to add execute="#this"/execute="#form" and others unsuccessfully, and check all points of this post but nothing seems to apply to me.
What is the mistake I am not seeing?
EDIT
#Named(value = "myController")
#ViewScoped
public class MyController implements Serializable {
...
I also have a <h:messages globalOnly="true" showDetail="true" showSummary="true" /> in my template.
I think I got it, finally!
Thanks to two things:
Point 3 in BalusC answer. I added an id to my message in the template <h:messages id="msg" and then use <f:ajax render="#form msg"..... This made an error j_idt1: Validation Error: Value is required to appear.
Then I could find the solution in this post: to change the required parameter from true to <f:viewParam required="#{!facesContext.postback}". This was not required in my other apps because required was "false", since it could be called with parameter or without it. When it was called with a parameter, it worked because by serendipity the page could be called without it.
Ran into the exact same problem, my <f:ajax> tag would work the first time and then nothing... no error or anything on the page. After a few hours and countless googling nothing was turning up. (Most of the questions on StackOverflow were actually having the opposite problem, the Ajax wouldn't fire the first time but then it would work fine). I finally stumbled on this question which described exactly what I was seeing.
I was previously trying to re-render only a section of the page, but I noticed that once I changed the render attribute to "#all", I got the same error message describe above:
j_idt1: Validation Error: Value is required
I scrolled up and noticed I had a <f:viewParam> with required set to "true". I made the change described by user1156544 and that did the trick.

Update a PrimeFaces component after every ajax action

How can I have a PrimeFaces component, e.g. a p:commandButton, getting updated after every ajax function in the page? I need something that would work with a complex html, with lots of forms, dialogs etc
this is what you are looking for
<p:outputPanel autoUpdate="true">
<p:commandButton ... />
</p:outputPanel>

<a4j:commandLink> action not fired inside <form>

I am working on an enhancement project. There is a parent <form> element. I have an XHTML file included inside this parent form. The included XHTML file has an <a4j:commandLink>. This action is not getting called.
Now, this will work if i wrap the <a4j:commandLink> inside an <h:form>. This way, the parent form's action is called as well as the <a4j:commandLink>'s action. But nesting forms is not encouraged.
I can't use the parent form's action because it goes to a servlet and my action is in a
request scoped bean. I cant access the bean in the servlet.
Any help on how to make the action call without the <h:form> is highly appreciated.
Here is how it looks like:
<form id="parentFormId" name="parentFormId" action="aservletaction">
<a4j:outputPanel id="includedRegion">
<ui:include src="setupView.xhtml"></ui:include>
</a4j:outputPanel>
</form>
Contents of setupView.xhtml:
<ui:composition>
<a4j:outputPanel>
<h:form>
<a4j:commandLink action="#{myBean.actionMethod}"
render="adatatableid" limitRender="true"/>
</h:form>
</ui:composition>
RichFaces components have to be inside a form otherwise they won't work (at least the executable ones).
Now, <a4j:commandLink> (and commandButton) executing the whole form is the default behaviour, to change it use the execute attribute:
<a4j:commandLink execute="#this" … >
This will limit the execution only to the link.
It ought not work. Do not nest forms, as its not legal in HTML in general and in HTML code rendered by JSF in particular. So, you've got a following construct in your code:
<form>
...
<h:form>
...
</h:form>
...
</form>
Get rid if it and it'll work as expected, i.e. by creating a plain form-to-form structure.

JSF2 Dynamic form is not being submitted

I have a form that is defined in a separate jsf page. This is is included to the main page when i click a link. Now the form is being displayed correctly. But the problem is that the submit button is not calling the action function defined.
The code to include the page( As suggested in this question: JSF2 Dynamically loading pages by ajax
<h:panelGroup id="editdivparent" layout="block">
<h:panelGroup id="editdiv" rendered="#{formsBean.edituserdiv}" layout="block">
<h:form id="userform" class="form-horizontal">
<ui:include src="edituserdetails.xhtml">
</ui:include>
</h:form>
</h:panelGroup>
</h:panelGroup>
The included page contains just the form elements with submit button:
<h:commandButton action="#{userBean.register() }" value="Update">
</h:commandButton>
I am getting no errors. On submitting the form the current page is redisplayed. I have put some print statements in the action function. Also there is a query error is put. None of them are being generated.
Am i doing something wrong here?
The commandButton action property already expects a method expression, so just take the parenthesis out, like this:
<h:commandButton action="#{userBean.register}" value="Update" />
Also, make sure you don't have nested forms when making templates with includes.
I hope it helps.

dynamic ui:include with el-expression?

I'm using JSF 2.0.
Is there a way to make this code work?
<ui:repeat value="#{theBean.tabList}" var="tab">
<h:panelGroup rendered="#{theBean.chose == tab.tabHash}">
<h:outputText value="TESTING #{tab.tabName} (#{tab.tabFile})" />
<ui:include src="#{tab.tabFile}" />
</h:panelGroup>
</ui:repeat>
Specifically, the line <ui:include src="#{tab.tabFile}" />.
Currently I get a blank page (Meaning, I guess, that #{tab.tabFile} evaluated to null\empty.)
Thanks!
The <ui:include> runs during view build time (to generate the JSF component tree) while the <ui:repeat> runs during view render time (to generate the HTML output), which is after the view build time. Use <c:forEach> instead of <ui:repeat>, it runs during view build time as well.
See also:
c:forEach vs ui:repeat in Facelets

Resources