h:command button oncomplete action - jsf

When downloading file from server if i use a4j:commandLink file download fail(mean file written to browser screen) if i use h:commandLink it is okay.I want to show a rich modal panel when file downloading but standard components not have a on complete action so i cant hide modal panel after file downloaded .How can i workaround this issue,I am using rich faces 3.3
<h:commandLink value="Download"
action="#{logSearcher.downloadFile}"
onclick="Richfaces.showModalPanel('ajaxLoadingModalBox',{width:450, top:200})"
immediate="true" >
<f:setPropertyActionListener value="#{log}"
target="#logSearcher.selectedLogLine}"
/>
</h:commandLink>

You can use de rich:componentControl or the JS API show function (#{rich:component('mp')}.show).
http://livedemo.exadel.com/richfaces-demo/richfaces/modalPanel.jsf?s=blueSky#

The <a4j:commandLink> sends by default an asynchronous (ajax) request. You cannot download files using asynchronous requests. JavaScript simply does not offer facilities to turn a XMLHttpRequest response into a Save As dialog. You need to download files using a normal synchronous request. The <h:commandLink> does that.
Your best bet is to use the onclick attribute of <h:commandLink> to close the modal panel. If necessary with a setTimeout().

Related

JSF 1.2 to open external link in new tab. without distrubing current flow [duplicate]

I need to open a JSF page in a new window by POST on click of a <h:commandButton>. I know I can acheive this using the JavaScript. But I would like to achive this using JSF and not JavaScript.
How can I achieve this? I'm using JSF 2.0.
The only non-JS way is to set target="_blank" in the parent <h:form>.
<h:form target="_blank">
...
<h:commandButton value="Open in new Window" />
</h:form>
This however affects all non-ajax(!) actions which are performed in the very same form. So if you're smart, make the action which shouldn't open in a new window an ajax action. However, ajax is also JavaScript and you mentioned that you don't want to use JS (I hope you don't get shocked once you discover that PrimeFaces is actually full of JavaScript).
If you absolutely need to restrict it to a single action, then you really can't go around asking little help to JavaScript.
<h:form>
...
<h:commandButton value="Open in new Window" onclick="this.form.target='_blank'" />
</h:form>
When you restrict the target only to a single action, maybe you want to get the form in its initial state.
With the oncklick action you set the target of the form to a _blan page.
After the click, the page is opened in a new tab/page (triggers the action event).
At last, the onblur action is triggered and set the form again to its initial state (the rest of the buttons will open in the _self page)
With this code, you can restrict to only a h:commandbutton to open in a new page.
The rest of the buttons will be opened in the self page:
<h:commandButton
onclick="this.form.target='_blank'"
onblur="this.form.target='_self'"
id="listadoRebuts"
action="#{giaquaBusquedaCorte.abrirListadoRebuts}"
value="#{msg.seqVisorbtnRecibos}">
</h:commandButton>

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

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.

what happens when click submit button while uploading file with ajax

I have a form with two fields:
<h:form>
<p:fileUpload fileUploadListener="#{mybean.fileUpload}" mode="advanced" auto="true" />
<h:inputText value="#{mybean.discription}"/>
<h:commandButton action="#{mybean.submit}" value="Submit"/>
</h:form>
If the file is large, it needs some seconds to upload completely. The form don't use ajax.
To be a user, i choose a file (large file) then click submit button immediately.
What happens with the file, null or submit method wait until file to be uploaded completety?
Thanks.
I think it is important to understand how really the file will be uploaded by p:fileUpload component. It will be done in one of two ways: it will create a hidden separate form put the input type="file" there and submit this form or it will use flash to upload the file which also doesn't use original form.
All this means that it can not be synchronized in browser and when you click submit button it will not wait until the file is uploaded.
Still it can be synchronized on the server. If you use JBoss Seam than probably method calls will be synchronized(as far as I rememeber jboss seam synchronizes ajax requests on server side). If you use some other framework(Spring) than it won't be syncronized and it can happen that #{mybean.submit} will be called earlier than #{mybean.fileUpload} or even the state on the server can be lost and #{mybean.fileUpload} won't be called at all.
But in any case the file will be uploaded to the server but can be ignored by the bean.

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!

Open new window by POST using h:commandButton

I need to open a JSF page in a new window by POST on click of a <h:commandButton>. I know I can acheive this using the JavaScript. But I would like to achive this using JSF and not JavaScript.
How can I achieve this? I'm using JSF 2.0.
The only non-JS way is to set target="_blank" in the parent <h:form>.
<h:form target="_blank">
...
<h:commandButton value="Open in new Window" />
</h:form>
This however affects all non-ajax(!) actions which are performed in the very same form. So if you're smart, make the action which shouldn't open in a new window an ajax action. However, ajax is also JavaScript and you mentioned that you don't want to use JS (I hope you don't get shocked once you discover that PrimeFaces is actually full of JavaScript).
If you absolutely need to restrict it to a single action, then you really can't go around asking little help to JavaScript.
<h:form>
...
<h:commandButton value="Open in new Window" onclick="this.form.target='_blank'" />
</h:form>
When you restrict the target only to a single action, maybe you want to get the form in its initial state.
With the oncklick action you set the target of the form to a _blan page.
After the click, the page is opened in a new tab/page (triggers the action event).
At last, the onblur action is triggered and set the form again to its initial state (the rest of the buttons will open in the _self page)
With this code, you can restrict to only a h:commandbutton to open in a new page.
The rest of the buttons will be opened in the self page:
<h:commandButton
onclick="this.form.target='_blank'"
onblur="this.form.target='_self'"
id="listadoRebuts"
action="#{giaquaBusquedaCorte.abrirListadoRebuts}"
value="#{msg.seqVisorbtnRecibos}">
</h:commandButton>

Resources