How to display "Loading.." while loading div - jsf

I have a JSF page with charts without AJAX support. I noticed that the time of loading of the charts is very slow. Is it possible for example to load the body of the JSF page and to display "Loading..." inside the DIVs where the charts are positioned while the chart is being loaded? I use Primefaces for charts generation.

You could experiment with BlockUI and the preRenderComponent event for the chart. Refer this link How to display 'loading' while loading PF chart

you can use this prime-faces ajax code while you are trying to load
<p:ajax event="page" update=":statusbar" onstart="statusDialog.show();" oncomplete="statusDialog.hide();" onerror="statusDialog.hide();"/>
from ajax you are calling to this dialog box
<p:dialog widgetVar="statusDialog" id="statusbar" modal="true" showHeader="false" closable="false" width="250" resizable="false">
<h:form>
//You can also give loading image here
<div class="ft-row ft-center"><img src="#{request.contextPath}/resources/images/loding.gif" /></div>
<h5>Please wait..</h5>
</h:form>
</p:dialog>

Related

PrimeFaces wizard - how can I use onstart/oncomplete for tab change ajax loading

I'm using PrimeFaces 4.
I don't want to use p:ajaxStatus because I only want to show loading for a few components.
So I have a p:blockUI component that I usually show during ajax events by doing this:
onstart="loading.show();" oncomplete="loading.hide();"
But for p:wizard component I don't know how can I do that when the user change tabs (clicking next/back buttons or clicking in the tab title). I tried the following inside the wizard:
<p:wizard id="wizard" flowListener="#{myBean.onFlowProcess}" style="display: inline-block;" backLabel="Prev" nextLabel="Next" showNavBar="true" widgetVar="wizardWV">
<p:ajax event="tabChange" onstart="loading.show();" oncomplete="loading.hide();" />
<p:tab id="tab1" title="My tab 1">
<p:panel>
<h:outputLabel value="test" />
</p:panel>
</p:tab>
<p:tab id="tab2" title="My tab 2">
<p:panel>
<h:outputLabel value="test2" />
</p:panel>
</p:tab>
</p:wizard>
Then I got the error:
<p:ajax> Unable to attach <p:ajax> to non-ClientBehaviorHolder parent
Is there any way I could achieve this?
Thanks
That's is because the wizard isn't a client behavior container.
The standard flow of a wizard is the tabs are just for display purposes in the heading. You should be using the Next/Back triggers for the wizard flow.
Refer to : http://www.primefaces.org/showcase/ui/panel/wizard.xhtml
Has the basic features/flow, but some more links
http://www.primefaces.org/docs/vdl/3.5/primefaces-p/wizard.html
If you're trying to make your tabs clickable then that's a different story, you'll need to setup your flow listener, have them all select the same method/action as the next - but pass a param to the backing bean and manually determine the flow. You could setup a remote call in PF with an onclick attached to access your intent of the waiting on load.
I would look at use case scenarios, maybe Wizard is the wrong component you're looking for?
Looking at the code provided, you're tabs currently are not clickable, and I cannot see your back/next action buttons.

How to show a .gif or message during image loading?

I have a jsf page that loads an image dynamically. The image generation may take a few seconds, so I would like to display a message or a gif so the user knows something is loading (at the moment there is just an empty space during loading).
I have tried to use primeface's deferred loading, but it made no difference at all.
I have a ajaxStatus in my page, but it is not activated during loading.
Here is the code containing the graphicImage:
<p:outputPanel deferred="true">
<h:graphicImage
value="/wfDiagram?processId=#{workflowAction.processId}"/>
</p:outputPanel>
the value is pointing to a servlet that handles image generation.
You should try the primefaces p:blockUI component.
Here is some example:
<p:blockUI widgetVar="loading" trigger="btnFilterProgram" block=":layout">
<h:panelGrid styleClass="custom-painelgrid-center">
<h:outputText value="Loading" />
<p:graphicImage value="resources/img/loading.gif" />
</h:panelGrid>
</p:blockUI>
In this case, a kind of "popup dialog" opens when the user clicks the button with the id btnFilterProgram and the component closes itself after the AJAX request is finished.

Primefaces blockUI to block a DataTable doesn't work when the DataTable is updated via AJAX [duplicate]

I am trying to create a datatable that displays a blockUI whenever it is busy, and I have been mostly successful. It now grays out and shows "Loading..." whenever I click either of two commandButtons, sort the datatable by clicking on a header, or page through the datatable. You can see the code for it below.
The problem is that after I have used one of the commandButtons (which runs an ajax update on the blocked element), subsequent actions do not trigger the blockUI (until I refresh the page). For example:
Load page
Click a datatable header - blockUI appears until table is finished sorting
Click one of the datatable page navigation buttons - blockUI appears until the page is loaded
Click one of the commandButtons - blockUI appears until the button's actionListener has finished
Click a datatable header - table sorts, but blockUI does not appear.
Click one of the datatable page navigation buttons - page loads, but blockUI does not appear
Click one of the commandButtons - actionListener runs and table updates, but blockUI does not appear
Reload the page - everything works properly again
Changing the commandButtons' update="" attribute to ajax="false" causes the sorting/paging to always display the blockUI, but the commandButtons to never display the blockUI.
Any ideas?
<div class="buttonDiv">
<p:commandButton ... update="resultsPanel" id="submitButton" ... />
...
<p:commandButton ... update="resultsPanel" id="resetScenarioButton" ... />
</div>
<p:panel header="Results Grid" id="resultsPanel">
...
<p:dataTable ... id="VAResults" ... >
...
</p:dataTable>
....
</p:panel>
<p:blockUI block="resultsPanel" trigger="submitButton, resetScenarioButton, VAResults">
Loading...
</p:blockUI>
The trigger attribute binds jQuery listeners on the specified elements. However if you update an element the binding gets lost. I don't know if it works, but you could try moving the <p:blockUI inside the resultsPanel. I suspect that when you update the panel the blockUI gets updated too and thus re-binding the listener to the data table.
<p:panel header="Results Grid" id="resultsPanel">
...
<p:dataTable ... id="VAResults" ... >
...
</p:dataTable>
....
<p:blockUI block="resultsPanel" trigger="submitButton, resetScenarioButton, VAResults">
Loading...
</p:blockUI>
</p:panel>
I've had the same problem and kind of simillar scenario:
<p:dataTable>
....
<p:ajax event="rowSelect" update="buttons" global="false" onstart="blockMessageButtons.show();" oncomplete="blockMessageButtons.hide();"/>
</p:dataTable>
<p:outputPanel layout="block" id="buttons">
<!-- content to be blocked -->
</p:outputPanel>
<p:blockUI block="buttons" widgetVar="blockMessageButtons"/>
The problem was that panel buttons was both updated by ajax, and blocked by blockUI. I had to divide it in two:
<p:dataTable>
....
<p:ajax event="rowSelect" update="buttons-content" global="false" onstart="blockMessageButtons.show();" oncomplete="blockMessageButtons.hide();"/>
</p:dataTable>
<p:outputPanel layout="block" id="buttons-container">
<p:outputPanel layout="block" id="buttons-content">
<!-- content to be blocked -->
</p:outputPanel>
</p:outputPanel>
<p:blockUI block="buttons-container" widgetVar="blockMessageButtons"/>
#siebz0r already provided the explanation why blockUI stops working when a component is updated.
I am using a one blockUI element in the template for all other pages and thus don't want to include more blockUI elements.
If the blockUI element is updated as well one does not need to move the blockUI inside the component that will be updated.
Here is an example:
<p:panel id="surroundingPanel">
...
<p:commandButton value="ButtonName" styleClass="blockUi"
action="actionToBeExecuted" update=":surroundingPanel :blockUiBinding" />
</p:panel>
<p:outputPanel id="blockUiBinding">
<p:blockUI block=":elementToBeBlocked" trigger="#(.blockUi)">
Loading ...
</p:blockUI>
</p:outputPanel>
The element blockUiBinding can be located anywhere, as long as it can be updated. It is wrapping the blockUI element, because blockUI generates at least two different divs. So when the wrapping element is updated also the blockUI will be updated.

interactive pieChart and rendered attribute

In my web application, I'm trying to make a simple page where there is a input, a command button, and one panel and a pieChart (inside panel). The panel starts not rendered (there is a MB and a boolean att "canShowPanel" that starts false). When the user clicks the commandButton, a method is called (actionListener) and canShowPanel is set to true, and the panel is updated. All works (the panel and the pieChart are rendered) BUT, the event (itemSelect) is not fired when the user clicks at pieChart slice. I tested start canShowPanel with true value (i.e. all is showed at begin), and all works including the event.
Summarizing: If the pieChart is not rendered at begin and after is rendered the events are not triggered. That is normal behavior? My code is below, but it can be tested with primefaces demos. Only put pieChart inside a panel (outputPanel, panel...) and make it be rendered after. Useful information: the piechart is populate in MB
PS. Running on PrimeFaces 3.6-SNAPSHOT and Mojarra 2.1.7 (SNAPSHOT 20120206) (well... apache tomcat 7...)
MY XHTML (a fragment)
<h:form>
<h:inputText value="#{logosUserViewMB.question}" tabindex="0" />
<p:commandButton icon="ui-icon-search" ajax="true" global="true"
actionListener="#{logosUserViewMB.doSearch()}"
update=":resultContainer">
</p:commandButton>
</h:form>
<p:outputPanel id="resultContainer">
<h:form prependId="false">
<p:outputPanel id="chartContainer" rendered="#{logosUserViewMB.canShowPanel}">
<p:pieChart id="pieChart" lazy="true"
value="#{logosUserViewMB.questionResultView.pieModel}"
legendPosition="w" title="No tit yet"
style="width:400px;height:300px;border:none">
<p:ajax event="itemSelect" listener="#{logosUserViewMB.itemSelect}" global="true"/>
</p:pieChart>
</p:outputPanel>
</h:form>

Primefaces lightBox problem

I have created a page with primefaces where I use the Lightbox component.
I use it in a dynamic matter as I create tumbnails on the fly with a servlet call.
The first page shows up nice and the lightbox works as expected but when I load a new set of pictures for the next page the pictures are shown but when you click on it, it just shows the original picture in a new page, when I then return with the previous button and click on a a thumbnail it works as expected.
This is the jsf code:
<h:outputLabel id="curpage" value="#{pictureBean.currentPage}" />
<h:commandButton value="next" action="#{pictureBean.nextPage}" id="next">
<f:ajax render="lightBox curpage" />
</h:commandButton>
<br/>
<p:lightBox height="500px" id="lightBox">
<ui:repeat value="#{pictureBean.pictures}" var="pic">
<h:outputLink value="#{pic.url}" title="#{pic.description}">
<h:graphicImage value="#{pic.urlThumb}" style="width:100px;height:75px;"/>
</h:outputLink>
</ui:repeat>
</p:lightBox>
I fixed it myself :-) I was forgotten to add the tags between form tags.

Resources