We are using JSF and Primefaces to control a SparkStream inside a Web-Application running on Tomcat. When we start or stop this Stream this takes about 15seconds in which the Web-GUI keeps loading.
Now we wanted to use deferred loading for long-loading content to make sure the Web-GUI is still accessible even if the Bean needs some time for responding. Anyway if we do so, our p:inputSwitch does not work correctly anymore. Everytime we load or refresh the page, the value in the Bean is set to false.
<h:form>
<p:panel id="control" header="Streaming-Control" collapsed="false" toggleable="true">
<p:outputPanel deferred="true">
<p:inputSwitch id="test" value="#{SomeBean.someBoolean}">
<p:ajax update="test"/>
</p:inputSwitch>
</p:outputPanel>
</p:panel>
</h:form>
We need to put the inputSwitch inside the deferred outputPanel because it should not be accessible until the whole page is rendered completely (which means the Stream is running or stopped, but not starting or being stopped atm).
PrimeFaces Version is 6.0.
Always try the newest version ;)
It could be fixed already: https://github.com/primefaces/primefaces/issues/2912
Related
Presentation
I am facing an issue to get an output panel load in deferred mode when the panel is included in a tab managed by Primefaces.
Here is a code sample:
<p:tabview value="#{b.tabs}" var="tab" dynamic="true" cache="false">
<p:tab title="#{tab.name}">
<p:outputpanel id="reportsDisplayId" >
<p:outputPanel id="reportsPanel" deferred="true" >
<h:outputText id="reports" escape="false" value="#{tab.report}" />
</p:outputPanel>
</p:outputpanel>
</p:tab>
</p:tabView>
"tab.report" is generated by Jasper. Generating this report takes time in most cases. This is the reason for using the deferred mode.
Tabs are managed using p:tabView in dynamic mode and no caching, so that tabs are refetched from the server at each tab change.
This works fine for the first tab: the display of the panel is effectively deferred without preventing the context from being displayed. Upon switching between tabs, the whole content of the tab is displayed only when the report is ready.
I have tried using deferredMode="visible", but this feature seems to intended for scroll visibility. I have tried enclosing the h:form into a p:outputPanel and updating the panel instead of the form.
Without success so far.
Working with p:RemoteCommand
I have progressed using p:RemoteCommand and found that others have been following that path, however with some difficulties. I will post my progress.
Here are related posts:
p:remote command not working in asynchronous mode
The bug reported here seems to have disappeared
JSF 2.1
Wildfly 8.2.1.Final
Primefaces 8.0.3
Omnifaces 2.7.7
Java 8
Here is a solution which relies on p:remoteCommand and not on the deferred attribute of output panel.
<h:form id="boardForm">
<p:tabview id="boardTabs" value="#{b.tabs}" var="tab" dynamic="true" cache="false">
<p:ajax event="tabChange" listener="#{board.onTabChange}"/>
<p:tab title="#{tab.name}">
<!-- First rendering: display a loading gif -->
<p:graphicImage value="/resources/img/loading.gif"
rendered="#{!board.loading}" alt="loading" />
<!-- Second rendering: display the report itself -->
<p:outputPanel id="reportsPanel" rendered="#{board.loading}" >
<h:outputText id="reports" escape="false" value="#{board.getJasper(tab)}"/>
</p:outputPanel>
<p:remoteCommand name="deferredLoader_#{board.tabIdx}" async="true" autoRun="true"
actionListener="#{board.setLoading(true)}" rendered="#{!board.loading}"
update=":boardForm:boardTabs:#{board.tabIdx}:jspReportDisplay" />
</p:tab>
</p:tabView>
</h:form>
The rendering goes in two phases:
A simple gif is displayed.
The whole report is displayed. However, the gif
is displayed as long as the report is not ready.
Detailed comments:
Upon tab switch, the event "tabChange" invokes the bean method "onTabChange", which sets "loading" to false and records the active tab index.
As "loading" is false, the gif is displayed, the report is not displayed, and the remote command is run.
The remote command is async so that it is possible to switch to another tab before the active tab is fully displayed.
The remote command sets back "loading" to false before updating the tab for the second phase, so that: (1) the gif is not displayed again; (2) the report is now generated; (3) the auto-run remoteCommand is not run infinitely many times.
the name of remoteCommand is indexed to the active tab to ensure unicity of names for each remoteCommand in various tabs.
Well, I guess there are more elegant solutions than this one. This is the one I found.
In the JSF Application there is this problem:
The application contains some elements inside a t:dataTable that are f:ajax enabled as following:
<h:form id="form" enctype="multipart/form-data">
<t:dataTable id="someTable" ...>
...
<f:facet name="header">
<t:commandLink action="#{someBean.someAction()}">
<t:outputText value="Some command"/>
<f:ajax execute="#this" render="someTable"/>
</t:commandLink>
</f:facet>
...
</t:dataTable>
</h:form>
The "Some command" should do something and refresh the "someTable" only.
Now the problem is: this scenario is WORKING under GlassFish 3.1.2, but under GlassFish 4.1 it is problematic as following:
The "Some command" works perfectly, and updates the someTable without any problem, but no other non-ajax action elements outside the someTable (or inside the Table) works.
They work, but do not show what they do, so that when we refresh the page, the changes appear.
Now, I tried to make the AJAX as following:
<f:ajax execute="#this" render="form"/>
And everything seems to be working just fine.
I need to update only the table, not the whole form.
Does anyone have a solution (web.xml config) or some tip?
There is no PrimeFaces/ICEFaces/RichFaces used in this project.
Thanks
EDIT: The names are correct (without : as prefixes, or anything else). The exact same scenario works perfectly under GlassFish 3.1.
Do we need to look into some security settings, or other configurations?
EDIT2: as #Tiny said in his comment, without multipart/form-data it worked, but then we can't make any Upload. The Upload doesn't work anymore.
Primefaces 3.5 JSF 2.1
I´m using p:remoteCommand to execute async commands and update my view after page loading but looks that in the ends of each iteration it execute again and so on...
Is this behaviour correct?
How to execute only once the p:remoteCommand?
update
I have checked that my remoteCommand was out of the update panel, so thank you for the answers but it was already OK. How I solve my problem:
I dont know why but using the onloadScript from Omnifaces (http://showcase.omnifaces.org/components/onloadScript) to call the remoteCommand function it is called many times, but using $(document).ready ... just once. So, I change it and got it working right now.
If you end up in an infinite loop like behaviour, you are likely updating a parent component to your <p:remoteCommand>.
<h:form id="myform">
<p:remoteCommand update="myform" actionListener="#{remoteCommandView.execute}" />
...
</h:form>
Put it outside/next to the component you wish to update and things should be fine.
<h:form id="newform">
<p:remoteCommand update="myform" actionListener="#{remoteCommandView.execute}" />
</h:form>
<h:form id="myform">
...
</h:form>
Use p:remoteCommand in separate form.
Use process="#this" and partialSubmit="true", just to be on safer side.
I currently have a giant ui:repeat. Within this ui:repeat, some of the repeated objects have a url to a popup image associated with them. When someone clicks display under that particular object, I need the url to popup in a p:dialog.
<ui:repeat var="thing" value="#{bean.thingList}">
<p:commandLink value="details" onclick="miniImage.show();"
update=":#{p:component('chart')}"
action="#{bean.setCurrentImg(thing.imageUrl)}"
rendered="#{thing.includeImage}">
</p:commandLink>
</ui:repeat>
and at the bottom of the page:
<p:dialog id="chart" widgetVar="miniImage" >
<h:graphicImage value="#{bean.currentImg}"/>
</p:dialog>
And in the backing bean I tried using a simple setter and getter for currentImg.
I am a bit confused on this now and would like to accomplish this without having to submit the entire form as well. Any help is greatly appreciated.
If you're using PrimeFaces 3.3 or newer, you could just add partialSubmit="true" to the command component. You can then control the to-be-processed components in process attribute. In this particular case, just the current component (the command component itself) is sufficient, thus so process="#this":
<p:commandLink ... process="#this" partialSubmit="true" />
This way only the request parameters which are really necessary for the process will be sent.
Unrelated to the concrete problem, I suggest to use oncomplete instead of onclick to open the dialog. Otherwise the dialog is opened before update takes place and may cause poor user experience as the enduser would see the image instantly changing.
I work with primefaces 3.4.1 and myfaces 2.1.9.
I need to show a component within a tab conditionally.
For the moment my code looks like that :
<p:tab id="tab" title="tabTitle">
<h:panelGroup id="tabContent">
<componentX:component id="component1" rendered="#{not condition}" />
<componentY:component id="component2" rendered="#{condition}" />
</h:panelGroup>
</p:tab>
I voluntarily changed the name of the components and arguments
My problem is with this solution component1 and component2 are both created. So the server will be working to generate the two components event if one is never shown.
My question is, is there a (clean) way to have this rendering result without creating both components?
I had the same results with c:if and c:choose, I am running out of ideas.
You can use c:if here without problems...