I'm having a problem with an Openface TabbedPane in a JSF application so I created a new application to test the TabbedPane. I have the following code in my page:
<h:form>
<o:tabbedPane>
<o:subPanel caption="Tab 1">
<h:outputText value="Hello from tab 1"/>
</o:subPanel>
<o:subPanel caption="Tab 2">
<h:outputText value="Hello from tab 2"/>
</o:subPanel>
<o:subPanel caption="Tab 3">
<h:outputText value="Hello from tab 3"/>
</o:subPanel>
<o:subPanel caption="Tab 4">
<h:outputText value="Hello from tab 4"/>
</o:subPanel>
</o:tabbedPane>
</h:form>
Initially tab 1 is shown. The next tab I click works (no matter which is the next) but no other tab when clicked works. For example when I click tab 2 I can see its contents but when I then click tab 3 I its contents are not shown and I still see previous tab's contents. I checked Mojarra's version on my Glassfish and it is 2.1.6. When I force the loading mode to be "client" everything is working but when I force it to be "server" I get the following error when I try to click a third tab:
[Ljava.lang.Object; cannot be cast to com.sun.faces.application.view.StateHolderSaver
There are some state-related issues with Mojarra 2.1.6, which are known to prevent OpenFaces from working correctly.
Officially, only Mojarra 2.0.3 is currently supported, but according to the preliminary testing Mojarra 2.1.8 appears to work as well (it still has to undergo additional testing before we declare compatibility with this version officially, but you can try see if it's acceptable for you).
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.
I am experimenting with Open Liberty and wanted to try out JSF-2.3 support. I must be doing something silly because when trying implicit navigation I immediately get the exception:
javax.faces.application.ViewExpiredException: View "/view/index.xhtml" could not be restored.
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:181)
I can render an initial Facelets-page using the following server.xml features:
<featureManager>
<feature>servlet-4.0</feature>
<feature>jsf-2.3</feature>
<feature>el-3.0</feature>
<feature>cdi-2.0</feature>
<feature>jsp-2.3</feature>
</featureManager>
My page is really simple and looks like this:
<h:body>
<h:outputText value="It works!"/>
<br/>
<h:form>
<h:commandLink value="NAvigate" action="view/page2" />
<h:commandButton value="NAvigate 2" action="view/page2" />
</h:form>
</h:body>
I have a corresponding page2.xhtml.
When clicking on either the commandLink or commandButton I get the exception:
javax.faces.application.ViewExpiredException: View "/view/index.xhtml" could not be restored.
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:181)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:195)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:142)
Have I mis-configured something in Open Liberty or are my JSF-mojo just lacking severely?
Ugh.. after testing in another browser (Safari) it worked. Hard-resetting Chrome site storage then fixed the original problem.
This problem must have surfaced somewhere in between automatic restarts.
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.
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.
I am using PrimeFaces 4.0, JSF2, jBoss EAP 6.1, Bootsrtap 3. I've got two places in my project where I use <p:autocomplete>, one renders OK the other does not. Suggestion part of auto complete should appear inside a <div> container at the bottom of the page:
<div id="searchForm:j_id_8t_5k_panel" class="ui-autocomplete-panel ui-widget-content ui-corner-all ui-helper-hidden ui-shadow"></div>
but my buggy one renders in the same place where <p:autocomplete> tag should be, it actually replaces input with plain <ul> with suggestions that you can not click.
I am using proper JSF tags like <h:body> etc.
My autocomplete component:
<p:autoComplete value="#{search.item}" completeMethod="#{search.autocomplete}"
var="item" itemLabel="#{item.label}" itemValue="#{item}" converter="objectConverter"
forceSelection="true" minQueryLength="3" scrollHeight="200"
global="false" />
Anyone had a similar problem?
The cause of my problem was that I've put my <p:autocomplete> inside a <p:outputPanel autoUpdate="true">. After removing autoUpdate everything works fine! Don't really know why it should break an autocomplete element, but it does. Hope it helps someone.