I've got a rich:tabPanel
with switchType="client"
and one of the tabs has set its switchType
to ajax
because loading its data is an expensive operation. When I click on this Ajax Tab I want its title to be changed to Loading... to indicate that the click has been recognized. When it has finished loading, the title should switch back to 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]
Actually, most of the described above works as expected, the only problem I have 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...]
I've found an issue in RichFaces' JIRA but this issue is fixed since version 3.2.1. Furthermore I've googled for a few hours but wasn't able to find any similar problems.
<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>
@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());
}
}
I've found out that the identifier (i mean that one you specify like <rich:someTag ... status="someStatus" />
) of an a4j:status
is not its id
but its name
attribute. So my a4j:status
is just for every Ajax request on that page. Giving it a name and using this named status does not work though, because nothing at all happens now.
<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>
I've also found another approach, using onbegin
and oncomplete
attributes with some code like:
<rich:tab id="ajaxTab" switchType="ajax"
onbegin="#{rich:component('ajaxTab')}.?"
oncomplete="#{rich:component('ajaxTab')}.?">
Well, as you see, I haven't found a way to manipulate the tab title yet (and I didn't find any useful documentation of what I can do with a rich:component).
I am not very much familiar with RichFaces 4.x
. However this is how to do it in RichFaces 3
.
Assume this as 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>
Note the ontabenter
event in the ajax tab.
Now your scripts would be like this.
<script>
function changeLabel(tabId) {
var tabLabel = event.target || event.srcElement;
tabLabel.innerHTML = 'Loading...';
}
</script>
I don't know much about RF4
. However in RF3
it is not needed to add an oncomplete
event to the tab.
I do the code below with richfaces 4.3.7. It seem to work. (I display loading panel instead of modify tab header.)
<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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With