JSF multiple actionListeners called in order with update - jsf

Using JSF 2 I understand I can call multiple actionListeners as such:
<h:commandButton value="Action">
<f:actionListener binding="#{myBean.actionOne()}" />
<f:actionListener binding="#{myBean.actionTwo()}" />
</h:commandButton>
However, I would like to call one actionListener and perform an update to the #form. Once this first call and update are complete call a 2nd actionListener and perform another update. Is this possible?

Yes. With <h:commandScript>.
<h:form>
...
<h:commandButton value="Action" action="#{myBean.actionOne}">
<f:ajax render="#form" onevent="function(data) {
if (data.status === 'success') actionTwo();
}"/>
</h:commandButton>
<h:commandScript name="actionTwo" action="#{myBean.actionTwo}"
render="...">
</h:commandScript>
</h:form>
In case you're not on JSF 2.3 yet, see How to invoke a JSF managed bean on a HTML DOM event using native JavaScript? for alternatives.
In case you're using PrimeFaces (given away by your question history confirms this and using the term 'update' instead of 'render'), the <p:remoteCommand> is the equivalent.
<h:form>
...
<p:commandButton value="Action" action="#{myBean.actionOne}"
update="#form" oncomplete="actionTwo()">
</p:commandButton>
<p:remoteCommand name="actionTwo" action="#{myBean.actionTwo}"
update="...">
</p:remoteCommand>
</h:form>

Related

How can <f:setPropertyActionListener> used with primefaces datatable rowExpansion

can <f:setPropertyActionListener> be used in primefaces datatable rowExpansion? I tried
<p:ajax event="rowToggle" listener="#{queryStudiesBean.onRowToggle}" >
<f:setPropertyActionListener target="#{queryPatientBean.test}" value="sucess"/>
</p:ajax>
but it says
<f:setPropertyActionListener> Parent is not of type ActionSource
also I tried
<p:rowToggler>
<f:setPropertyActionListener target="#{queryPatientBean.test}" value="sucess"/>
</p:rowToggler>
but it gives the same error, is there anyway to use it?
<f:setPropertyActionListener> works with ActionSource components like <p:commandLink> and <p:commandButton>.
<p:rowExpansion>
<p:commandLink>
<f:setPropertyActionListener>
</p:commandLink>
</p:rowExpansion>
I knew how to do it finally, I put the <f:setPropertyActionListener> inside remoteCommand, which in turn needs to be inside a form:
<form>
<p:remoteCommand name="callButton" ajax="false" id="callButton" action="#{queryPatientBean.printTest()}">
<f:setPropertyActionListener target="#{queryPatientBean.test}" value="success"/>
</p:remoteCommand>
</form>
then I called this remoteCommand from <p:ajax> onstart:
<p:ajax event="rowToggle" onstart="callButton();" listener="#{queryStudiesBean.onRowToggle}" />

h:commandButton not working [duplicate]

How to update a div and do partial submission using <h:commandButton>, I have previously used <p:commandButton> to do partial submission by setting the ajax attribute to true and the update attribute to :statusBlock, where the id of the <h:panelGroup> is statusBlock. I am having some designing issues with <p:commandButton> so I cannot use it so I have to use <h:commandButton>.
This is to be done by nesting a <f:ajax> in it.
In effects,
<p:commandButton ... process="#form" update=":statusBlock" />
does exactly the same as
<h:commandButton ...>
<f:ajax execute="#form" render=":statusBlock" />
</h:commandButton>
Note that the subtle difference with the PrimeFaces equivalent is that PrimeFaces defaults to #form in the process/execute, while the <f:ajax> one defaults to #this, so you might need to explicitly specify execute="#form" over all place where you didn't specify the process attribute in the PrimeFaces component.
See also:
Communication in JSF 2.0 - Ajax (asynchronous) POST form
You can just use the standard components alongside f:ajax e.g.
<h:form id="myForm">
<h:commandButton value="Push Me">
<f:ajax execute="myForm" render="statusBlock" />
</h:commandButton>
<h:panelGroup id="statusBlock">
</h:panelGroup>
</h:form>

Trigger actionListener with partialSubmit

I have the following code:
<h:panelGrid columns="2" styleClass="labelValueContainer" columnClasses="one,two">
<p:outputLabel value="Value" />
<p:inputText id="englishValue" styleClass="englishValue" value="#{labelsManager.addLabelsBean.engValue}" />
</h:panelGrid>
<p:commandButton value="COPY" styleClass="copyButton" process="englishValue" partialSubmit="true" actionListener="#{labelsManager.setValueForCopy}">
What I'm trying to do is to submit only one inputText and trigger an actionLister (or an action) with ajax. If I remove partialSubmit="true" the method "setValueForCopy" is trigger but when I add again actionListener is not triggered anymore and I don't know way.
If anyone have a better solution for submiting an input and trigger a method I'm ready to listen.
Thanks!
When using partialSubmit="true", only things in process="..." will be submitted (and processed). This is missing the <p:commandButton> itself.
Add it via #this:
<p:commandButton ... process="#this englishValue" partialSubmit="true" ... />
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes

Pass parameter to f:ajax inside c:foreach loop

I am trying to pass a parameter to an ajax event, this is an example of what I mean:
<h:panelGrid id="pictures" columns="3">
<c:forEach items="#{createProduct.pictures}" var="picture">
<h:graphicImage value="#{picture.source}" />
<h:inputText value="#{picture.alt}" />
<p:commandButton value="Remove">
<f:ajax execute="#form"
listener="#{createProduct.removePicture(picture)}"
render="#form" />
</p:commandButton>
</c:forEach>
</h:panelGrid>
I know this code won't work because you cannot pass a parameter through the ajax listener. Though this is merely an example of what I am trying to accomplish. I have tried using <f:param id="picture" value="#{picture}" /> allong with the ajax tag, though this results in a duplicate component ID form:picture since it is in a loop.
I need this parameter inside the method in order to determine which picture to remove.
How can I solve this with ajax?
I am using a #ViewScoped CDI-bean.
First, I suggest replacing c:forEach with ui:repeat tag. Second, as you are using Primefaces, you should use all its strength. So, commandButton can be more easily written:
<p:commandButton value="Remove" process="#form" update="#form" action="#{createProduct.removePicture(picture)}"/>
and that's it. Don't complicate.
By the way, primefaces commandButton is sends AJAX request by default, you don't need (and you must not use) f:ajax tag.

The attribute update is not defined in the component commandButton

I have this JSF commandButton which I use to delete rows from table:
<h:commandButton id="deleterow" value="HiddenDelete" action="#{BatteryProfileTabGeneralController.saveData}" style="display:none" update="growl">
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
In Netbeans 7.3 I get this error:
The attribute update is not defined in the component commandButton
I use update attribute to display message when I successfully delete row. Can I replace this attribute with similar attribute?
The update attribute is specific to PrimeFaces <p:commandButton>. It's a convenience replacement of the standard JSF equivalent <f:ajax render>.
So, basically, the <p:commandButton ... update="growl" /> does essentially the same as:
<h:commandButton ...>
<f:ajax render="growl" />
</h:commandButton>
Note that when the <p:growl id="growl"> is not inside the same form, then you should refer it using an absolute client ID instead, perhaps <f:ajax render=":growl">. If you would like to update the current form as well, then use <f:ajax render="#form :growl">. This is perhaps your case as you've currently already a render="#form" but still keeps asking about explicitly updating the growl, which suggests that it is actually not enclosed in the form at all.

Resources