Browser specific behavior of JSF while I have one ajax listener and another action listener for command button - jsf

I have
<p:inputText id="sales-person">
<p:ajax event="change"
update="employee_name" listener="#{quoteBean.rebuildServiceDataList}"/>
</p:inputText>
... and
<p:commandButton id="confirm-button" process="#{breadcrumb.breadcrumb_base_name}" value="#{shop_msgs['continue.label']}" actionListener="#{quoteBean.showPayUI}" />
Skipped some part of code for understanding.
Basically when I change something on the input text it will call some ajax method to fetch some data, validate etc. And when I click on command button it will submit.
In Chrome browser if I type something and directly click on submit button, it is actually first firing onchange event, this calls the ajax then action listener for command button will execute.
But in case of IE if I do the above mentioned step, it will only execute the onchanage and calls the ajax method. The actionListner will not be invoked.
Can anybody please help me with this?
Edit 1: I tried even with onclick in command button, even that is not called in case of IE. When I try to click on button only the onchange event of text box is executed.
Thanks in advance.

Use the developer tools of IE browser by pressing F12.
Are there any error messages in console? What happens with the ajax call?
My first thought, I doubt that there is a lack in your Bean or similar, because basically it works.
From my experience (in connection with datatables), IE has indeed more troubles dealing with java script than Firefox or Chrome for example.

Related

commandLink onclick action issue

I'm having trouble with the Syntax with just starting.
Once the user clicks ("Book"), I want to immediately switch the user to a specific WebPage - but I'm not sure how to write it.
I have created different aspects and been able to successfully invoke my action, but after viewing tutorials I've not been able to find the syntax for making the user change WebPage upon onclick
<h:commandLink onclick
action="#{booking.lesson(item)}"
value="Book"
</h:commandLink>

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!

JSF listener triggers buttons onclick

<h:form>
<h:selectOneMenu value="#{productBean.productName}">
<f:selectItem itemValue="" itemLabel="..." />
<f:selectItems value="#{productBean.pizza}" var="pizza" itemValue="#{pizza.name}" itemLabel="#{pizza.name}" />
<f:ajax listener="#{productBean.valueChanged(productBean.productName)}" render="pizzaResult pizzaButton" />
</h:selectOneMenu>
<h:commandButton value ="Dodaj do zamówienia" disabled="#{productBean.isDisabled}" id="pizzaButton" onclick="#{productBean.order}"/>
<h:outputText id="pizzaResult" value="#{productBean.message}" />
</h:form>
This is my JSF form. I used valueChanged listener to make button diabled in ome cases and it works good. But I don't get why it triggers also the buttons onclick. How to do something which enable me to use button ONLY after clicking it?
I noticed that when I delete the disabled option it works good:/ But why I cannot trigger the action when button is enabled in the moment?
onclick is a client side attribute so you shouldn't try to bind it to managed bean method calls and it looks as though you did onclick=#{productBean.order} (apart from the missing quotes). This may be the cause of your problems.
OK i did that. The problem is that the button may appear as enabled (disabled="false") but its client side change and server don't know about it and application thinks that the button is still disabled. Even it looks like enabled button it won't work with action="#{something}".
You have to let server know about the change. THe only thing i did is adding the #ViewScoped to the managed bean. Now the action of disabling and enabling the button is also being seen by the server and works perfectly.
However i have a question. Client side verifaction is a bad idea. Disabled button is the only thing which prevent user from sending empty itemValue or product(in my case) which is unavailable (is_available = 0 in DB). The question is: Is it enough to ensure that it will be safe?
edit: Unfortunately after clicking the button the buttons appear enabled even though the oneSelectMenu is turned to the first, empty value. After changing the list it works again as previously, and after clicking again the situation takes time again.

Open primefaces dialog on error in prerenderview event listener

I have a problem with open and close a primefaces dialog on error in a prerenderview event listener. I use the event listener to load data from a third-party system, which under some circumstances needs special authentication.
So far when the special authentication is required i set a property on a request scoped bean and use the visible property of the dialog to decide if the dialog should be visible or not.
<p:dialog widgetVar="#{name}" resizable="false" modal="true"
closable="false" id="#{name}Dialog" width="375"
useWindow="true"
visible="#{specialAuthenticationBean.authenticationRequired}">
Hint: #{name} is an include parameter.
Is this the recommended way to do it?
If yes how can i close the dialog when the cancel or ok button was clicked?
So far for the cancel button i tried this with the following code but without success.
<p:commandButton id="cancel" value="#{messages['cancel']}" onclick="#{name}.hide()" type="button" />
Any ideas?
UPDATE: I tried out different things and found the cause. The dialog did not close because there were three includes for the same dialog with different parameters, but the visible-condition was true for all three dialogs.
And now i ask myself if it is really necessary to have three instances of the same dialog, only because the login buttons execute different actions (bean methods). What i really want to do is after one bean method invocation leads to open the authentication dialog, execute the same bean method again after submit the correct authentication data in the authentication dialog.

Primefaces onclick and onsuccess differences

I have the following situation:
after clicking a button, some business logic is done and after it is done, a new tab with a report should be visible.
<p:commandButton value="this button" update="growlMain"
actionListener="#{myBean.businesslogic}"
onstart="ajaxDialog.show();"
oncomplete="ajaxDialog.hide();"
onsuccess="window.open('./report.jsp', '_newtab');" />
This does not work :(
If the business logic only lasts some milliseconds, the following works:
<p:commandButton value="this button" update="growlMain"
actionListener="#{myBean.fastbusinesslogic}"
onclick="window.open('./report.jsp', '_newtab');" />
the onclick opens a new tab, also things like onstart but it doesn't work with onsuccess or oncomplete. Why? And is there a solution for business logic that lasts some seconds?
onclick is called before the ajax request is even created (pure client side) while oncomplete and onsuccess are executed after the server responded to the ajax request. So, if you need to execute some business logic before showing a dialog, for example, you want to go with oncomplete. That's what I always use.
You can also condition your javascript inside oncomplete to perform only if there's no validation errors. Intuitively I think onsuccess would behave like that and only execute when there's no validation errors, but that's not how it goes. I don't really know the difference between them. I assume there's a way to flag success=false in the backing beans, but I couldn't really find it in the documentation.
If you want to check for validation in your oncomplete attribute, this is how you'd do:
oncomplete="if (!args.validationFailed){someDialog.hide()}"
In this case, you would only close the dialog if the fields are properly validated. You can actually inject parameters from the backing bean and use them in the javascript after the request has been served. In your backing bean you can do something like this:
RequestContext.getCurrentInstance().addCallbackParam("showDialog", false);
And you can access the parameter like this in your incomplete attribute:
oncomplete="if (args && args.showDialog){someDialog.show()}else{ alert('the bean didnt let me open the dialog')}"
Anyway, I hope that helps.
I have noticed that onsuccess for PrimeFaces command button does not work. The oncomplete however works and does the needful even if there is an error , such as in my case shows a success dialog even if there is an error in my business logic. Tried to use onsuccess but doesn't work.
You could try oncomplete as below:
<p:commandButton value="this button" update="growlMain"
actionListener="#{myBean.businesslogic}"
onstart="ajaxDialog.show();"
oncomplete="ajaxDialog.hide(); window.open('./report.jsp', '_newtab');"/>
You can see the difference here:
Primefaces and ajax onsuccess event
or with onsuccess you can do something before full loading DOM

Resources