I have issue with canceling Ajax Request. Our application interface is build in RF.
On the progress bar modal there should be cancel button - that interupt current operation,
for example cancel filling controls from database. How to make it?
I tried using reloading page, flags with "if" conditions on getters for controls and also using "bypassUpdates" with no positive effects.
Thanks in advance for your help
XHTML (Button):
<a4j:commandButton id="showData"
value="View" styleClass="hBtn"
disabled="#{events.isButtonsDisabled}"
oncomplete="if (#{facesContext.maximumSeverity==null})
{window.open('/seed/pages/data.jsf','DATA')};"
actionListener="#{events.actionShow}"/>
JAVA: (Button):
public void actionShow(ActionEvent evt) {
//Some logic, getting data from database
}
XHTML (Main Page - showing wait Popup)
<a4j:form>
<a4j:status id="ajaxStat"
onstart="Richfaces.showModalPanel('waitPanel');"
onstop="#{rich:component('waitPanel')}.hide()" />
</a4j:form>
XHTML (Popup):
<rich:modalPanel id="waitPanel" autosized="true" moveable="false"
minWidth="250" styleClass="popup">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Operation in progress"></h:outputText>
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:panelGroup>
<h:graphicImage value="../images/icons/action_close.gif" styleClass="hidelink" id="hidelink"/>
<rich:componentControl for="waitPanel" attachTo="hidelink" operation="hide" event="onclick"/>
</h:panelGroup>
</f:facet>
<a4j:form id="msgFrm" ajaxSubmit="true">
<h:outputText value="Please wait..."/>
<h:graphicImage styleClass="progressBar" value="../images/indicatorbar.gif"/>
<a4j:commandButton value="Cancel" type="button"
onclick="#{rich:component('waitPanel')}.hide()"
action="#{main.cancelAction}"
bypassUpdates="true"/>
</a4j:form>
</rich:modalPanel>
JAVA (Popup):
public void cancelAction(){
//there was setter for true/false flag for actionShow() here, now there is nothing here (it was not working)
}
Reloading the page stops all current ajax requests. It does not stop the java backing beans from finishing the requests but I assume that is not the question.
c:if and the ajax render do not mix very well. Possibly you could use 'rendered' to disable updating the controls? Then split the control in two parts. One is shown with valid data and for example bright blue. The other is rendered without any data and has a grey picture.
But... I'm not sure I understand the question correctly.
Edit 23-1-2012: Seeing the code I would say that the cancelAction must set a flag that then finishes the action running inside actionShow(). Then the ajax request finishes and the popup is closed. Can't see why this won't work.
Related
I've got a modalPanel with some components (for example, a tree). At fisrt my actions and actionListners work correclty. After some time (from 5 to 10 minutes) actions stop working completely. The post is fired, but the AjaxViewRoot actions are empty. I have no validation errors.
All the page component ids are fixed (not generated) to prevent conversion error.
My bean is Conversation scoped and its timeout is over 30 minutes.
<rich:modalPanel id="modalId" resizeable="false" autosized="true">
<a4j:include id="myPage" viewId="#{bean.viewId}"/>
</rich:modalPanel>
Here is myPage (included page) code:
<ui:composition>
<h:form id="frmPage">
<h:panelGrid columns="1">
<a4j:region id="treeRegion">
<rich:panel id="tbPanelTrees">
<h:panelGrid columns="2" >
<h:panelGroup layout="block" style="height:#{(height-150)/2}px; width:#{(width-20)/2}px; overflow:visible; overflow-y:auto; overflow-x:auto;">
<rich:tree id="subjectTree"
style=" height: 100%"
switchType="ajax"
var="item"
nodeFace="#{item.nodeType}"
value="#{bean.subjTree.rootSubjectsTree}"
adviseNodeOpened="#{bean.subjTree.adviseNodeOpened}"
changeExpandListener="#{bean.subjTree.changeExpandListener}"
nodeSelectListener="#{bean.subjTree.nodeSelectListener}"
ajaxSubmitSelection="true"
reRender="elements outside region"
ajaxSingle="true"
ignoreDupResponses="true">
<rich:treeNode type="root" icon="#{item.subjectsIcon}" iconLeaf="#{item.subjectsIcon}" id="subjectRootNode">
<a4j:commandLink value="#{item.nodeName}" id="subjectRootNodeLink"/>
</rich:treeNode>
<rich:treeNode type="user" icon="#{item.userIcon}" iconLeaf="#item.userIcon}" id="userNode">
<a4j:commandLink value="#{item.nodeName}" id="userNodeLink"/>
</rich:treeNode>
</rich:tree>
</h:panelGroup>
</a4j:region>
</h:panel:Grid>
</h:form>
</ui:composition>
Does anybody have an idea, what's the problem?
Finally found a solution. Some of my components didn't have a defined id and had a generated one (like myForm:j1456546).
Another part of the page send a polling request (to show some news), which send a DOM-tree to the server for validation. The generated ids where changed on server-side, but remained the same on client side (because the polling didn't rerender anything apart from news panel). So when user clicked the button (or fired any other ajax-action), the button ids on the client and server-side where different and action was not invoked.
Solution: manualy define all of your ids.
I have a menu with list items and a p:commandLink inside. While using this for different pages I realized that I have problems updating form with a p:dataTable and p:columns inside. After clicking on the link, form2 which actually has some panels and the table inside should be updated. Now my problem: Only most of the content in form2 is updated correctly, but the p:columns have the old value. If I click again on the link, the correct values are shown.
The bean method public void selectProject(Project myProject) is called correctly and the values are correctly processed.
Now the strange thing: If I add a h:graphicImage with a p:ajax everything works fine!!
<h:form id="form1">
...
<li>
<p:commandLink update=":form2" actionListener="#{bean.selectProject(p)}">
<h:outputText value="#{p.name}" />
</p:commandLink>
<!-- Code below is for testing only, but works fine! -->
<h:graphicImage value="#{iconBean.icon(12,'clock')}">
<p:ajax event="click" update=":form2" listener="#{bean.selectProject(p)}"/>
</h:graphicImage>
</li>
...
</h:form>
Update This does not seem to be related to p:columns, a simplified test case shows the expected behavior of p:commandLink. In the original (still failing) setting the menu is implemented as a composite component.
As a workaround I use
<h:commandLink>
<h:outputText value="#{p.name}"/>
<p:ajax event="click" update=":form2" listener="#{bean.selectProject(p)}"/>
</h:commandLink>
I'm using an extendedDataTable because I need multiselect. The table can get pretty large, so I'm using a dataScroller for paging.
What I want to achieve is, that the selection is cleared when switching to another page. The selection is stored in the backing bean and I have a method clearTableSelection to clear the selection.
Now my question is, how is it possible to call the method clearTableSelection when switching pages.
I found a simple solution:
...
<rich:extendedDataTable>
...
<f:facet name="footer">
<rich:dataScroller
onbegin="document.getElementById('form:hiddenButton').click()" />
</f:facet>
</rich:extendedDataTable>
<a4j:commandButton
id="hiddenButton" action="#{backingBean.clearTableSelection}"
value="HiddenButton" execute="#this" style="display: none;" />
...
I'm new to JSF2 and Primefaces and realized an issue to update components.
Lets' assume I have the following piece of code, I can directly update="counter"
<h:form id="f1">
<h:outputText id="counter" value="#{clientBean.counter}" />
<h:graphicImage url="/images/circle-ok.png">
<p:ajax event="click" update="counter" process="#this"
listener="#{clientBean.tag}"/>
</h:graphicImage>
</h:form>
In another h:form I have to use update="f1:counter". Only a update="counter" does not work here.
<h:form id="f2">
<p:dataTable var="var" value="#{clientBean.vf}">
<p:column>
<f:facet name="header">Tag</f:facet>
<h:graphicImage url="/images/circle-ok.png">
<p:ajax event="click" update="f1:counter" process="#this"
listener="#{clientBean.tag}" />
</h:graphicImage>
</p:column>
</p:dataTable>
</h:form>
I haven't faced this with JSF1.2 (and RichFaces), what are the rules to address the ids correctly?
In your first example JSF could lookup up the counter element in the same scope as ajax listener. Form implements NamingContainer which means it prefixes client ids (used in html) with its own id and creates a distinct name space for ids. Have a look at the page source under browser - there will be f1:counter id assigned to your counter. In your second example there is no counter element in the scope (inside form f2) so the lookup fails.
You can disable this form behaviour with prependId="false". This is useful if you are sure there won't be elements with identical ids across all forms.
Icefaces works differently - it automatically calculates the html delta and sends it to the browser as partial update. In most cases this is more convenient for the programmer but comes with considerable performance cost. I believe JSF2 adopted icefaces partial updates concept but requires ids to be passed explicitely.
EDIT
Cant seem to get rendered to work correctly with update attributes. Here is my codes
<ui:define name="left">
<h:form>
<p:commandLink value="Hey"
actionListener="#{bean.setRenderComment}"
update="comment"/>
</h:form>
</ui:define>
<ui:define name="right">
<h:panelGroup id="comment" rendered="#{bean.renderComment}">
hello
</h:panelGroup>
</ui:define>
renderComment is a boolean attributes inside bean. setRenderComment basically toggle the state of renderComment like this
this.renderComment = !this.renderComment;
Right, every time I click on the link Hey, I need to refresh to either render hello on or off. How can I fix it, so that I dont need to refresh
I am not using Primefaces but Richfaces on my projects. So I am not really aware on how the refresh process is done by Primefaces. However, I have an idea that can be tested easily.
Your problem may be due to the fact that the component to re-render (i.e. update) is not found on the HTML page. If your rendered attribute is equals to false, then the <SPAN> with comment id is not integrated in the HTML page generated. Thus, when the Ajax request is received on the client side, the Ajax engine is not able to refresh this <SPAN> as it is not found.
So what you can do is to always render your panelGroup and move your rendered attribute to a nested <h:outputText> that contains the Hello message.
Here is what I am suggesting:
<h:panelGroup id="comment">
<h:outputText value="Hello" rendered="#{bean.renderComment}"/>
</h:panelGroup>
This way, the panelGroup will always be refreshed after the Ajax call, and it will contain the Hello message or not, regarding the value of the renderComment attribute of your bean.
Since the component with the ID comment isn't one of the form's (an UINamingContainer component) children, you need to prefix the ID with : to instruct JSF to scan from the "upper level".
This should do:
<p:commandLink value="Hey"
actionListener="#{bean.setRenderComment}"
update=":comment" />