CommandButton produces change event causing two axjax requests - jsf

I have a <p:inputText> with a nested <p:ajax event="change" listener="myValidate"> and a <p:commandButton actionListener="myValidate" process="#form">.
The problem is, that the myValidate method is called twice, because pushing the commandButton first triggers the onChange-Event (when edtiting the text before clicking CommandBt) what then calls the myValidate method. After that the myValidate is called by the CommandButton actionListener.
How can i prevent the double call?
What I need is:
call myValidate when leaving inputText after change text
call myValidate when pushing CommandButton (what is sadly implicit triggering the other one)
thanx for help in advance.

If you specify update and process, the ajax request will be called onBlur (when the field loses focus):
<p:inputText>
<p:ajax event="change" listener="myValidate" update="myForm" process="#form">
</p:inputText>
But note, if the input loses focus in that way that you click on the command button, than there will be 2 subsequent AJAX calls. It's because the first is triggered by the javascript onBlur event, and the second by the onClick event on the button. However, only in that case (if you go first to the other field, it will work as you expect).
The usual solution is to stick to JSF model and validate the whole form on submitting, not every single field on leaving it.

Related

Is there a way to update Primefaces form without losing data in it?

I have form inside dialog and I need to update it when user click button. Button is for showing new fields in this form. Fields are not rendered by default in dialog(render="#{gettForBoolean}").
When I am trying to use RequestContext.getCurrentInstance().update(formID); in backing bean and always all data are gone.
Problem solved. Normal input is not saving to variable when writing, but it can be done by ajax: <p:ajax event="keyup" process="#widgetVar(inputID)"/>
The process attribute avoid you loosing data in AJAX calls:
<p:ajax update="formId" actionListener="#{bean.method}" />

ActionListener method not called when in a conditional rendered block

I've got this code where some buttons show only under a certain condition, like this:
<h:panelGroup rendered="#{mayusculasBean.jefeCerca}">
<h:panelGrid columns="4">
<h:commandButton value="Listar"
actionListener="#{gestorEmpleados.listarEmpleados}"
immediate="true"/>
...`
</h:panelGroup>
The rendered attribute is working ok. The problem is that the actionListener method is not being called when the commandButton is pressed. However, if I get rid of the rendered attribute, the button is working properly.
I think it might be related to the different phases of the Jsf request, so when the commandButton is pressed the rendered attribute, I don't know why, evaluates to false, therefore avoiding the call to the actionListener method... but it's just a guess, I really have no idea.
Any help?
If your mayusculasBean is #RequestScoped, then, after response committed, your command button component will not be tracked by the server.
If this is your case, you need to change your mayusculasBean to a wider scope such as #ViewScoped.

Execution order of events when pressing PrimeFaces p:commandButton

I am trying to execute a JSF2 bean method and show a dialog box after completion of the method on click of PrimeFaces <p:commandButton>.
<p:commandButton id="viewButton" value="View"
actionlistener="#{userBean.setResultsForSelectedRow}" ajax="false"
update=":selectedRowValues"
oncomplete="PF('selectedRowValuesDlg').show()">
</p:commandButton>
<p:dialog id="selectedRowValues" widgetVar="selectedRowValuesDlg" dynamic="true">
<h:outputText value="#{userBean.selectedGroupName}" />
</p:dialog>
When I click on the command button, the bean action listener method setResultsForSelectedRow executes properly, but it does not show the dialog box when the method completes. If I remove actionlistener, it shows the dialog box. I do not know what is going wrong.
What is the execution order of events? Is it possible to execute actionlistener and oncomplete simultaneously?
It failed because you used ajax="false". This fires a full synchronous request which in turn causes a full page reload, causing the oncomplete to be never fired (note that all other ajax-related attributes like process, onstart, onsuccess, onerror and update are also never fired).
That it worked when you removed actionListener is also impossible. It should have failed the same way. Perhaps you also removed ajax="false" along it without actually understanding what you were doing. Removing ajax="false" should indeed achieve the desired requirement.
Also is it possible to execute actionlistener and oncomplete simultaneously?
No. The script can only be fired before or after the action listener. You can use onclick to fire the script at the moment of the click. You can use onstart to fire the script at the moment the ajax request is about to be sent. But they will never exactly simultaneously be fired. The sequence is as follows:
User clicks button in client
onclick JavaScript code is executed
JavaScript prepares ajax request based on process and current HTML DOM tree
onstart JavaScript code is executed
JavaScript sends ajax request from client to server
JSF retrieves ajax request
JSF processes the request lifecycle on JSF component tree based on process
actionListener JSF backing bean method is executed
action JSF backing bean method is executed
JSF prepares ajax response based on update and current JSF component tree
JSF sends ajax response from server to client
JavaScript retrieves ajax response
if HTTP response status is 200, onsuccess JavaScript code is executed
else if HTTP response status is 500, onerror JavaScript code is executed
JavaScript performs update based on ajax response and current HTML DOM tree
oncomplete JavaScript code is executed
Note that the update is performed after actionListener, so if you were using onclick or onstart to show the dialog, then it may still show old content instead of updated content, which is poor for user experience. You'd then better use oncomplete instead to show the dialog. Also note that you'd better use action instead of actionListener when you intend to execute a business action.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
Differences between action and actionListener
I just love getting information like BalusC gives here - and he is kind enough to help SO many people with such GOOD information that I regard his words as gospel, but I was not able to use that order of events to solve this same kind of timing issue in my project. Since BalusC put a great general reference here that I even bookmarked, I thought I would donate my solution for some advanced timing issues in the same place since it does solve the original poster's timing issues as well. I hope this code helps someone:
<p:pickList id="formPickList"
value="#{mediaDetail.availableMedia}"
converter="MediaPicklistConverter"
widgetVar="formsPicklistWidget"
var="mediaFiles"
itemLabel="#{mediaFiles.mediaTitle}"
itemValue="#{mediaFiles}" >
<f:facet name="sourceCaption">Available Media</f:facet>
<f:facet name="targetCaption">Chosen Media</f:facet>
</p:pickList>
<p:commandButton id="viewStream_btn"
value="Stream chosen media"
icon="fa fa-download"
ajax="true"
action="#{mediaDetail.prepareStreams}"
update=":streamDialogPanel"
oncomplete="PF('streamingDialog').show()"
styleClass="ui-priority-primary"
style="margin-top:5px" >
<p:ajax process="formPickList" />
</p:commandButton>
The dialog is at the top of the XHTML outside this form and it has a form of its own embedded in the dialog along with a datatable which holds additional commands for streaming the media that all needed to be primed and ready to go when the dialog is presented. You can use this same technique to do things like download customized documents that need to be prepared before they are streamed to the user's computer via fileDownload buttons in the dialog box as well.
As I said, this is a more complicated example, but it hits all the high points of your problem and mine. When the command button is clicked, the result is to first insure the backing bean is updated with the results of the pickList, then tell the backing bean to prepare streams for the user based on their selections in the pick list, then update the controls in the dynamic dialog with an update, then show the dialog box ready for the user to start streaming their content.
The trick to it was to use BalusC's order of events for the main commandButton and then to add the <p:ajax process="formPickList" /> bit to ensure it was executed first - because nothing happens correctly unless the pickList updated the backing bean first (something that was not happening for me before I added it). So, yea, that commandButton rocks because you can affect previous, pending and current components as well as the backing beans - but the timing to interrelate all of them is not easy to get a handle on sometimes.
Happy coding!

PrimeFaces dialog validation errors

What i want to do is like basic row selection example at Primefaces showcase(http://www.primefaces.org/showcase/ui/datatableRowSelectionByColumn.jsf) I want to update my datatable's row. The problem is when i click to update button at datatable, dialogbox appears with validation errors.
Second thing is what is the order of method execution times.(action-update-onclick-f:setPropertyActionListener)
<p:commandButton id="updateButtonId"
action="#{myController.showCompanyEditPanel}"
update=":tabView:companyForm:companyEditPanel"
onclick="companyDialog.show()"
icon="ui-icon-pencil" title="update">
<f:setPropertyActionListener value="#{company}" target="#{myController.selectedCompany}" />
</p:commandButton>
<p:dialog id="editCompanyDialogId" header="CompanyEdit" widgetVar="companyDialog" resizable="false">
<p:panel id="companyEditPanel" >
//some stuff here
</p:panel>
</p:dialog>
You seem to be missing a major point of using a <p:commandButton> here, as well as seem to be mixing client-side and server-side events.
First on <p:commandButton>. This component is designed to POST (partial) form data to the current URL, do business job in action(listener) method and return updated components / perform navigation. You can of course 'attach' JavaScript events to all those attributes.
Second, onclick, oncomplete, and other on... attribute are corresponding to some client-side events. In particular, onclick function is triggered when button was clicked, oncomplete function is called when DOM was updated after the AJAX call, i.e. the elements specified in <p:ajax update="..."> or simply in update="..." attribute of <p:commandButton>.
Third, all action listeners (thus, actionListener attribute, <f:actionListener> tag, <f:setPropertyActionListener> tag) will be executed right in the order they are specified in your tag, see this answer for more elaboration. The last one to be executed is action method, after which response is sent back.

PrimeFaces CommandButton that Doesn't Process Data

I have a JSF/PrimeFaces form page set up to edit some configuration details. At the bottom are Submit and Cancel buttons implemented as CommandButton. The Cancel button looks like this:
<p:commandButton
action="priorPage.xhtml?faces-redirect=true"
value="Cancel" />
The problem is that the view bean still winds up doing more processing on the data that's been entered into the form than I'd like. It isn't updating anything in the database, but if (say) I enter a string into a field that's looking for a numeric in the bean, it still produces errors.
Part of my solution is, of course, to get the bean to gracefully handle that sort of bad data, and I'm working on it. But I'd also like to tweak that button so that it just takes the user to the prior page. Is there some attribute I can set that will prevent the form from being processed at all?
The <p:commandButton> submits the form. You don't want to submit the form. You should then not use the <p:commandButton>, but just <p:button>.
<p:button value="Cancel" outcome="priorPage.xhtml" />
See also:
Difference between h:button and h:commandButton

Resources