Trigger actionListener with partialSubmit - jsf

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

Related

JSF multiple actionListeners called in order with update

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>

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}" />

JSF inputText reads value only with required="true"

Can anyone explain why h:inputText must have required="true" when setting the property in controller and updating with ajax(See example below)?
Does not work:
<h:inputText id="textFieldId" value="#{model.itemValue}">
Works:
<h:inputText id="textFieldId" value="#{model.itemValue}" required="true">
Action:
<p:commandLink value="edit">
<p:ajax event="click" listener="#{controller.edit(item)}" process="#this" update="#form"/>
</p:commandLink>
Idea behind is that I want to press button for item and be able to edit so I need to propagate this item to inputText.
I dont see any reason for having required set to true.
Thanks
The PrimeFaces p:commandLink is by default already ajax enabled, so there is no need to nest a p:ajax tag inside it.
<p:commandLink value="edit" actionListener="#{controller.edit(item)}"
process="#this" update="#form"/>
But keep in mind that if you add a process="#this", the input is not processed on the server, just the commandLink. If the 'item' field is passed correctly in this case is unclear to me.

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.

Reset input fields without executing validation

I have a Facelets view as below:
<h:form id="f1">
<p:panelGrid id="p1" columns="2">
<p: inputText value="Distance Travelled::/><p:inputText value="#{airTransportUsage.distance}" immediate="true"
required="true" requiredMessage="Distance Travelled Field cannot be left blank.."
converterMessage="Distance Travelled must be a number"
validatorMessage="Distance Travelled must be a valid number.."
id="dis">
<f:validateLongRange minimum="1"/>
</p:inputText>
<p:commandButton value="Reset" action="#{airTransportUsage.reset}" update=":f1:p1" />
</p:panelGrid>
</h:form>
When the reset button is clicked, the corresponding method can never be executed due to validation. I can't use immediate="true" on my reset button as it creates some other problems.
The <p:commandButton> processes indeed by default the entire form (process="#form"), you can change this by specifying only the current component in the process attribute.
<p:commandButton value="Reset" ... process="#this" />
However, this will fail if the form is already been validated beforehand. The input fields which have been marked invalid won't be updated with the new model value (which you've resetted yourself). If you're using PrimeFaces 3.4, then embed <p:resetInput> in the button:
<p:commandButton value="Reset" ... process="#this">
<p:resetInput target="#form" />
</p:commandButton>
If you aren't on PrimeFaces 3.4 yet and can't upgrade to it, you can use OmniFaces ResetInputAjaxActionListener for this.
A completely different alternative is to just refresh the current page by a fresh new GET request.
<p:button value="Reset" />
This worked for me in PrimeFaces 5.3
<p:commandButton action="#{bean.reset()}" value="Reset" process="#this" update="#form" resetValues="true" />
You can probably replace the "#form" target of the update attribute to a specific component if you want.

Resources