RichPaces tabPanel with switchType ajax and a4j: status parameter

What am i trying to achieve

I have rich:tabPanel with switchType="client" , and one of the tabs set its switchType to ajax , because loading its data is an expensive operation. When I click on this Ajax tab, I want its name to be changed to "Loading ..." to indicate that the click was recognized. When it finishes loading, the title should return to the Ajax tab.

 [Client Tab] [Ajax Tab] <click on 'Ajax Tab'> [Client Tab] [Loading...] <wait...> [Client Tab] [Ajax Tab] <click on 'Client Tab'> [Client Tab] [Ajax Tab] 

Description of the problem

In fact, most of the above works as expected, the only problem I am facing is that when I navigate from the Ajax tab to any other tab, the title of the Ajax tab switches back to β€œLoading ...”:

 [Client Tab] [Ajax Tab] <click on 'Ajax Tab'> [Client Tab] [Loading...] <wait...> [Client Tab] [Ajax Tab] <click on 'Client Tab'> [Client Tab] [Loading...] 

Research

I found the problem in JIRA RichFaces , but this problem has been fixed since version 3.2.1. In addition, I searched Google several times, but could not find such problems.

Environment

  • Tomcat 7.0.30
  • Mojarra 2.1.12
  • RichFaces 4.2.2.Final

Code (abbreviated)

Jsf

 <ui:composition template="WEB-INF/templates/default.xhtml"> <ui:define name="content"> <h:form id="form"> <rich:tabPanel id="tabPanel" switchType="client"> <rich:tab id="clientTab"> <f:facet name="header"> <h:outputText value="Client Tab" /> </f:facet> <h:outputText value="Foo" /> </rich:tab> <rich:tab id="ajaxTab" switchType="ajax" status="ajaxTabStatus"> <f:facet name="header"> <a4j:status id="ajaxTabStatus"> <f:facet name="start"> <h:outputText value="Loading..." /> </f:facet> <f:facet name="stop"> <h:outputText value="Ajax Tab" /> </f:facet> </a4j:status> </f:facet> <h:outputText value="#{bean.value}" /> </rich:tab> </rich:tabPanel> </h:form> </ui:define> </ui:composition> 

Backup Bean Ajax Tabs

 @ManagedBean @ViewScoped public class Bean implements Serializable { private static final long serialVersionUID = -8405248908693334970L; private String value = "noValue"; private static final Logger log = LoggerFactory.getLogger(Bean.class); @PostConstruct public void init() { log.info("Init bean."); value = getDummyValueWithFakeDelay(); } public String getValue() { log.info("Get value."); return value; } private String getDummyValueWithFakeDelay() { try { Thread.sleep(1000); } catch (InterruptedException ex) { } return DateFormat.getTimeInstance().format(new Date()); } } 

Update 1:

I found out that the identifier (I mean the one you specify as <rich:someTag ... status="someStatus" /> ) a4j:status not its id , but its name attribute. So my a4j:status is only for every Ajax request on this page. Giving him a name and using this named status does not work, because now nothing happens.

 <rich:tab id="ajaxTab" switchType="ajax" status="ajaxTabStatus"> <f:facet name="header"> <a4j:status id="ajaxTabStatus" name="ajaxTabStatus"> <f:facet name="start"> <h:outputText value="Loading..." /> </f:facet> <f:facet name="stop"> <h:outputText value="Ajax Tab" /> </f:facet> </a4j:status> </f:facet> <h:outputText value="#{bean.value}" /> </rich:tab> 

Update 2:

I also found another approach using the onbegin and oncomplete with some code like:

 <rich:tab id="ajaxTab" switchType="ajax" onbegin="#{rich:component('ajaxTab')}.?" oncomplete="#{rich:component('ajaxTab')}.?"> 

Well, as you can see, I have not yet found a way to manipulate the tab title (and I have not found any useful documentation on what I can do with a rich component).

+7
source share
2 answers

I am not very familiar with RichFaces 4.x However, this is how to do it in RichFaces 3 .
Suppose this is how you tabPanel .

 <h:form> <rich:tabPanel> <rich:tab label="Client Tab" switchType="client"> Tab - client </rich:tab> <rich:tab label="Ajax Tab" id="ajaxTab" switchType="ajax" ontabenter="changeLabel(event)"> <h:outputText value="#{bean.value}" /> </rich:tab> </rich:tabPanel> </h:form> 

Notice the ontabenter event on the ajax tab.

Now your scripts will be like that.

 <script> function changeLabel(tabId) { var tabLabel = event.target || event.srcElement; tabLabel.innerHTML = 'Loading...'; } </script> 

I don't know much about RF4 . However, in RF3 do not need to add the oncomplete event to the tab.

+1
source

I am making the code below with richfaces 4.3.7. It seems to work. (I display the download bar instead of the tab title.)

 <a4j:status oncomplete="#{rich:component('busy')}.hide()" onerror="#{rich:component('busy')}.hide()" onbegin="#{rich:component('busy')}.show()"> <rich:popupPanel id="busy" modal="true" moveable="false" resizeable="false" autosized="true"> <h:panelGrid styleClass="alignCenter" width="100%" id="busyPanel" columns="1" border="0" cellpadding="0" cellspacing="2"> <h:outputLabel value="Loading..." /> </h:panelGrid> </rich:popupPanel> </a4j:status> <h:form> <rich:tabPanel switchType="ajax" oncomplete="#{rich:component('busy')}.hide()" onerror="#{rich:component('busy')}.hide()" onbegin="#{rich:component('busy')}.show()" > <rich:tab label="Client Tab" switchType="client"> Tab - client </rich:tab> <rich:tab label="Ajax Tab" id="ajaxTab" > <h:outputText value="#{bean.value}" /> </rich:tab> </rich:tabPanel> </h:form> 
+1
source

All Articles