Disabling an a4j:commandButton after click - jsf

I have an a4j command button which displays a loader in a pop-up panel using a4j:status onstart and onstop events. After action method linked with a4j:commandButton is completed, I want the button to be displayed as disabled on the screen.
I have created a boolean variable in backing bean of disableBtn which gets set to true in action method of a4j commandButton. when I render the button, the pop-up containing the loader doesn;t disappear
<h:form>
<a4j:status id="waitingMessage"
onstart="#{rich:component('modalPanelId')}.show()"
onstop="#{rich:component('modalPanelId')}.hide()">
</a4j:status>
<rich:popupPanel id="modalPanelId" modal="true"
autosized="true">
<h:graphicImage library="images" name="loading.gif" />
</rich:popupPanel>
<rich:panel id="updatePanel">
<div>
<a4j:commandButton value="Confirm Action"
styleClass="btn right"
disabled="#{bean.disableBtn}"
actionListener="#{bean.confirmAction}"
execute="#this" render="updatePanel"
immediate="true" />
</div>
</rich:panel>
</h:form>
Pop-up panel with loader should disappear upon completion of action of a4j:commandButton and button should be rendered as disabled.

A source of action cannot disable itself (I don't recall if this is a JSF thing or just RichFaces). Once the action is finished you got to have another component disable and rerender the button in response, simple a4j:jsFunction should do. Something like:
<a4j:jsFunction name="setEnabled" render="button">
<a4j:param name="enabled" assignTo="#{bean.buttonEnabled}"/>
</a4j:jsFunction>
<a4j:commandButton … oncomplete="setEnabled(false)" />

It's possible to disable the element with pure JavaScript onclick handler:
<a4j:commandButton
onclick="setTimeout('document.getElementById(\'' + this.id + '\').disabled=true;', 50);"

Related

Popup not rendering in JSF

I have a4j command button in one xhtml page and popup panel in other. I want to open the the popup on commandbutton click in first page.
the command button
auth.xhtml
<a4j:commandButton id="Add" value="Add New" type="submit"
action="#{controller.add}"
render=":addPopupForm:addPopupOp">
<a4j:param value="true" assignTo="#{controller.ind}" ></a4j:param>
</a4j:commandButton>
addPopup.xhtml
<h:form id="addPopupForm">
<a4j:outputPanel id="addPopupOp" ajaxRendered="true">
<rich:popupPanel id="addPopup" domElementAttachment="parent" show="true"
rendered="true" height="600" width="1000" >
Row is added
</rich:popupPanel>
</rich:outputPanel>
</h:form>
I'm not a richfaces user but in general JSF , you can't re-render elements which are not rendered in the first place.
So in your case you should point to addPopupForm , like this :
<a4j:commandButton id="Add" value="Add New" type="submit"
action="#{controller.add}"
render=":addPopupForm" >
Or wrap the a4j:outputPanel with some wrapper that will be always rendered
Also, take a look at this: Can you update an h:outputLabel from a p:ajax listener?
Just rendering the panel does not mean showing it. You have to attach the popup "show" attribute to a property:
show="#{bean.showPopup}"
Set the showPopup boolean in the action method (action="#{controller.add}") and then do render="addPopupForm"

JSF commanbutton refreshes the page and popup menu disappears immediately

I am trying to show a popup menu in by checking some conditions, such as if something is not selected show popup etc. and if everyhing is fine submit the page. Here is the code:
<h:commandButton onclick="if (#{moneyTransferManager.showPopup()})
#{rich:component('popup')}.show();" value="Devam" >
<rich:componentControl target="popup" operation="show" />
</h:commandButton>
<rich:popupPanel id="popup" modal="false" autosized="true" resizeable="false">
<f:facet name="header">
<h:outputText value="Simple popup panel" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#" onclick="#{rich:component('popup')}.hide();
return false;">
X
</h:outputLink>
</f:facet>
<p>
The popup panel is open and closed from the javascript function of component client side object. The following code
hide this panel:
<f:verbatim>#</f:verbatim> #{rich:component('popup')}.hide()
</p>
</rich:popupPanel>
then after button is clicked, popup shows for like a second and then page is refreshed and popup is lost. To prevent refreshing page i tried:
<f:ajax execute="#form" render="#none" />
but then if everything is right and if i don't need a popup i need to submit the page by commandbutton, but since i say render=#"none" i cannot do this. So what can i do about this situation?
Thanks
<h:commandButton> has a default button type submit which submits enclosing h:form when it is clicked. That is why the page refreshes when you click.
<h:button> should be used for java script usage.In addition, <h:commandButton> becomes <h:button> if type attribute is set to button.
<h:button onclick="if (#{moneyTransferManager.showPopup()})
#{rich:component('popup')}.show();" value="Devam"/>
Or
<h:commandButton type="button" onclick="if (#{moneyTransferManager.showPopup()})
#{rich:component('popup')}.show();" value="Devam" >
See Also :
Difference between h:button and h:commandButton

PrimeFaces commandButton & UIBlock

I have the following code inside a registration form. Basically the button calls an action (an Ejb method and an Action listener which is an utility method).
When the user submits the registration form, a primefaces dialog should appear telling the user that registration is being processed. The same dialog disappears once the form is submitted. This can be achieved by Primefaces UIBlock; however, it requires the commandButton to be ajax enabled.
I thought about using : onstart = display some modal dialog & onsuccess or on complete = hide this dialog (<p:dialog widgetVar="dialog" ...) but this solution requires ajax to be enabled for primefaces commandButton.
Any clues on how I could achieve this while setting ajax to false inside a PrimeFaces commandButton?
Thanks
<h:form id="form_register">
<p:panel id="panel_register">
<div align="center" style="padding: 5px;">
<p:commandButton id="register" ajax="true"
actionListener="#{mailBean.deliverEmail(newMember.email,newMember.name, newMember.username, newMember.password, newMember.isadmin)}"
action="#{memberController.register}" value="Register"
label="Register">
<f:setPropertyActionListener target="#{requestScope.wait}"
value="#{true}" />
</p:commandButton>
</div>
<p:blockUI block="panel_register" trigger="register">
<h:outputText value="Please wait..." />
<br />
<p:graphicImage value="#{resource['gfx/gif.gif']}" />
</p:blockUI>
EDIT: Thanks guys. I was mis-using the update the attribute in commandButton. Now things work fine.
You should use the onstart and oncomplete actions to display/hide the dialog.
<p:commandButton id="register" onstart="dlg.show()" oncomplete="dlg.hide()" />

which event is fired after the action event?

I want to display the header of the modal popup with the value chatBean.selectedUser. The thing that happens is that onclick event is fired before action event so the page is not refreshed when the onclick event is fired. Hence I cannot get the header of modal pop up as the value contained in chatBean.selectedUser. Is there anyway that I can display the header of modal popup with the value chatbean.selectedUser after that the page is submitted?
Here is the relevant part of the view:
<h:form>
<p:selectOneMenu value="#{chatBean.selectedUser}" id="select">
<f:selectItems value="#{chatBean.friendList}" var="users" itemLabel="#{users.firstName}" itemValue="#{users.firstName}"/>
</p:selectOneMenu>
<p:commandButton id="basic" value="Basic" onclick="dlg.show()" type="button" action="#{chatBean.refresh}"></p:commandButton>
<p:dialog id="modalDialog" header="#{chatBean.selectedUser}" widgetVar="dlg" modal="true" height="100">
<h:outputText value="This is a Modal Dialog." />
<h:inputText></h:inputText>
</p:dialog>
</h:form>
You should show the dialog only when the action is completed, not before. Use the oncomplete attribute instead.
<p:commandButton ... oncomplete="dlg.show()" />
Don't forget to explicitly update the dialog's content before opening it. I don't see that anywhere in your code. Perhaps you're using RequestContext#update() or something, but normally you'd use update attribute for this.
<p:commandButton ... update="modelDialog" oncomplete="dlg.show()" />
Also, the type="button" is strange. This way the action wouldn't be invoked at all, but perhaps that's just a careless leftover of experimentation. Remove it.

Primefaces how to update content in a dialog and keep the dialog centered?

I have a dialog that contains no content on page load and I'm dynamically setting the content of a dialog box based on the link that a user clicks on.
<p:dialog widgetVar="dlg" modal="true" id="dialog">
<p:panel id="fullArticle">
<h:outputText value="#{content.newsArticle}" escape="false" />
</p:panel>
</p:dialog>
...
...
<p:commandLink value="Read more" actionListener="#{content.getFullArticle}" onclick='dlg.show();' update=":fullArticle">
<f:attribute name="contentId" value="#{news.contentId}" />
</p:commandLink>
The problem i'm having is that when you click the "Read More" link, it shows the dialog, but the dialog is not centered on the page. If i change the udpate attribute on the commandLink to update=":dialog", the dialog flashes as if it's opening and then closing right away.
How can I update the dialog and have it be centered with dynamic content?
The onclick is executed before the ajax request. You need to open the dialog in oncomplete instead. This will be executed after the ajax request and update. The <p:dialog> is namely by default hidden unless its visible attribute evaluates true.
<p:commandLink value="Read more" actionListener="#{content.getFullArticle}"
update=":dialog" oncomplete="dlg.show()">
Unrelated to the concrete problem, are you aware that you can pass fullworthy objects as method arguments since EL 2.2? This makes the <f:attribute> and actionListener "hack" superfluous:
<p:commandLink value="Read more" action="#{content.getFullArticle(news)}"
update=":dialog" oncomplete="dlg.show()" />
I had the same problem.
Updating the dialog makes it disappear and reappear (and forget its position).
To solve it, I created a wrapper tag around the dialog content.
<p:commandLink update=":playerViewDialogHeader,:playerViewDialogContent"
oncomplete='playerViewDialogJS.show()' value='#{item.name}' />
<p:dialog id='playerViewDialog' widgetVar='playerViewDialogJS'>
<f:facet name="header">
<h:outputText id="playerViewDialogHeader" value="#{playerController.objectView.name}" />
</f:facet>
<h:form id='playerViewDialogContent'>
<!-- CONTENT GOES HERE -->
</h:form>
</p:dialog>

Resources