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

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

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>

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.

Commandbutton works only on second click until a <h:selectBooleanCheckbox> on a HashMap is removed

I'm working with JSF 2.2.9, i have the following dataTable and buttons:
<h:commandButton id="commandButtonRemoverSelected"
actionListener="#{managedBeanName.removeSelected()}"
class="btn btn-primary" value="Sim">
</h:commandButton>
<h:dataTable var="bean" value="#{managedBeanName.beans}" styleClass="table table-hover"
binding="#{managedBeanName.dataTable}">
<h:column headerClass="smallColumn">
<f:facet name="header">
<h:selectBooleanCheckbox valueChangeListener="#{managedBeanName.selectAll}">
<f:ajax execute="#form" render="#all" />
</h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox value="#{managedBeanName.registrosSelecionados[bean]}" />
</h:column>
</h:dataTable>
The button "commandButtonRemoverSelected" just call actionListener on second click. When i remove the following line from datatabe everything works fine (the commandButton is called on first click):
<h:selectBooleanCheckbox value="#{managedBeanName.registrosSelecionados[bean]}" />
So, my managedBean have a MAP called 'registrosSelecionados' that should store a pair "Bean,Boolean". See:
private Map<Bean, Boolean> registrosSelecionados = new HashMap<Bean, Boolean>();
SOLUTION
I solved the problem with a workaround and i would share this:
1 - I noted that every first commandButton click the 'getRegistrosSelecionados()' is called and actionListener don't. So i imagine that JSF is processing getRegistrosSelecionados() and don't processing actionListener, i don't know why and this is the real problem. In second click the actionListener is processed because all checkboxs already sent to ManagedBean, in first click.
2 - So, my workaround is force that each click in checkbox call JSF request and don't wait for commandButton submit. In this way when commandButton is clicked all checkbox was processed.
<h:selectBooleanCheckbox value="#{cc.attrs.managedBeanName.registrosSelecionados[bean]}">
<f:ajax execute="#this" render="#this" />
</h:selectBooleanCheckbox>
My checkbox received the ajax to execute only itself and render itself, when i click in commandButton i just need execute the commandButton and render the form again:
<h:commandButton id="commandButtonRemoverSelected"
actionListener="#{cc.attrs.managedBeanName.removeSelected()}"
class="btn btn-primary" value="Sim">
<f:ajax execute="#this" render="#form" />
</h:commandButton>
This workaround works for me, as i didn't found a better solution for this problem.

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.

Resources