0
votes

I have a tabview in which I want to refresh contents of one specific tab whenever user selects that tab. I also want modal dialog to pop up while tab is being refreshed.

Here is tabView with tabChange ajax event handler

<p:dialog widgetVar="statusDialog" modal="true" draggable="false" minimizable="false" appendToBody="true"   closable="false" header="Processing..." resizable="false" maximizable="false">  
     <p:graphicImage library="assets" name="ajax-loader.gif"></p:graphicImage> 
</p:dialog>

<p:tabView id="tabview" orientation="top" dynamic="false">
    <p:ajax event="tabChange" listener="#{bean.tabChangeListener}"></p:ajax>
    <p:tab title="tab1">
        <ui:include src="/WEB-INF/views/tab1.xhtml"/>
    </p:tab>
    <p:tab title="tab2">
        <p:remoteCommand actionListener="#{bean.refreshData}" update="someTab2ElementID" name="refresh" global="true" onstart="statusDialog.show()" oncomplete="statusDialog.hide()"/>
        <ui:include src="/WEB-INF/views/tab2.xhtml"/>
    </p:tab>
</p:tabView>

Here is tabChangeListener:

public void tabChangeListener(TabChangeEvent event) {
    if ( event.getTab().getId().equalsIgnoreCase("tab2") ) {
                RequestContext.getCurrentInstance().execute("refresh()");
    }
}

The refresh remoteCommand is being called as expected, but my statusDialog is never shown. If the same remoteCommand is triggered by a button click the statusDialog appears. There are no errors in JavaScript console.

Why is statusDialog not shown when remoteCommand is triggered by RequestContext.execute() and how can I make it appear? I even tried adding statusDialog.show() to execute() but it didnt help.

2
Could you try <p:ajax event="tabChange" listener="#{bean.tabChangeListener}" oncomplete="statusDialog.show();"></p:ajax>?Ömer Faruk Almalı
That will cause statusDialog to show on all tab changes. I only want it to show when one specific tab is selected.rootkit

2 Answers

1
votes

I figured it out. Here is the solution:

<h:outputScript>
var blockCount=0;
function showStatus() {
 if (blockCount==0) statusDialog.show();
 blockCount++;
};
function hideStatus() {
 blockCount--;
 if (blockCount==0) statusDialog.hide();
};
</h:outputScript>

<p:ajaxStatus onstart="showStatus();" onsuccess="hideStatus();" onerror="blockCount=0;statusDialog.hide();errorDialog.show();"/>  

<p:remoteCommand actionListener="#{bean.refreshData}" update="someTab2ElementID" name="refresh" global="true" onstart="showStatus()" oncomplete="hideStatus()"/>

Apparently the reason why my status dialog was not being shown is that another Ajax call finished and called statusDialog.hide() while my refresh() thing was going on. The JS code above maintains a counter of how many Ajax calls are in progress, and will only hide the status dialog when all calls have finished. Works as intended now!

0
votes

If you want to show dialog when a specific tab is changed, you can inform a js function about, the tab selected control that it is 2 or not by adding a callback parameter via ajax response:

public void tabChangeListener(TabChangeEvent event) {
    if ( event.getTab().getId().equalsIgnoreCase("tab2") ) {
                RequestContext.getCurrentInstance().addCallbackParam("index", 2);
    }
}

And use:

 <p:ajax event="tabChange" listener="#{bean.tabChangeListener}"
     oncomplete="showOrNot(xhr,status,args)"></p:ajax>

This will call the js function and it's going to control that the changed tab is 2 or not:

function showOrNot(xhr,status,args) {
    if(args.index==2) {
        statusDialog.show();
    } 
}

Or different approach is defining a value and using visible property of the p:dialog:

public void tabChangeListener(TabChangeEvent event) {
        if ( event.getTab().getId().equalsIgnoreCase("tab2") ) {
                    this.condition=true;
        }
    }

And <p:dialog visible="#{bean.condition}"/>. And maybe you need to focus on your first approach and you can give an ID to p:dialog and update it via p:remoteCommand:

<p:remoteCommand actionListener="#{bean.refreshData}" update="someTab2ElementID dialog" name="refresh" global="true" onstart="statusDialog.show()" oncomplete="statusDialog.hide()"/>

Don't forget to give the exact client ID of the dialog in the update property of p:remoteCommand.