All tabs of tabpanel refreshed, when event happens in any one of the tab (Richface 3.3.4) - jsf

We have a tabPanel which has multiple tabs. When any event is performed in any of the tabs (e.g. click 'ajaxSubmit' button in tab1) all tabs are refreshed which is causing performance issues (e.g. getter of 'table' value is always invoked from tab3).
We tried to wrap the content of each tab in <a4j:region>, but the getters of components in tab3 are still invoked.
Please find the sample code snippet below:
<r:tabPanel id="tabWorkingPanel" styleClass="otTMcontainer" selectedTab="#{tabHandlerBean.activeTab}">
<rich:tab id="tab1">
<h:commandButton value="ajaxSubmit"/>
</rich:tab>
<rich:tab id="tab2" />
<rich:tab id="tab3">
<rich:dataTable id="table" value="#{bean.someValue}">...</rich:dataTable>
</rich:tab>
</r:tabPanel>

I think you should be using reRender so that only relevant tabs are refreshed. I think you should also wrap the contents of each tab in a form so that not everything is submitted on each submit, though perhaps that's what you were trying to do with region. I would carefully read the documentation to make sure you're using these correctly.
I have not used RichFaces, so I'm not positive this will work, but a similar approach works for PrimeFaces.
BalusC's description of process and update may be useful. He's discussing PrimeFaces, but I think the same concepts apply.

Related

defer loading of an output panel within a tab managed by primefaces tabview tag

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.

Equivalent of RichFaces 4 <rich:popupPanel> for RichFaces 3

I am looking for something like <rich:popupPanel> in RichFaces 4, but then for RichFaces 3. I haven't found anything like in documenation. There is only <rich:modalPanel> which doesn't suit my needs, because it has problems displaying my datamodel in table. The selection doesn't work, it always returns no rows selected. If I put my table component in <rich:panel> or <rich:togglePanel>, then it works fine.
Is there any popup window excluding <rich:modalPanel> in RichFaces 3?
I dont have 50 reputation to ask you more details in a comment, so i will answer directly hoping this is what you're asking about.
I think you mean that your problem is that the content of the ModalPanel is not rerendered dynamically. but for this you can wrap your table (or the components you want to update) in an <a4j:outputPanel> with ajaxRendered="true"
Setting ajaxRendered="true" will cause the <a4j:outputPanel> to be updated with each Ajax response for the page, even when not listed explicitly by the requesting component. This can in turn be overridden by specific attributes on any requesting components.
http://docs.jboss.org/richfaces/latest_4_0_X/Component_Reference/en-US/html/chap-Component_Reference-Containers.html#sect-Component_Reference-Containers-a4joutputPanel
In my code I have something like :
<a4j:commandLink id="timelineBtn" action="#{timelineBean.doGenerateLog}"
oncomplete="Richfaces.showModalPanel('timelinePnl');return false;"
value="#{labels['timeline.button.lbl']}"/>
that opens the modalPanel :
<rich:modalPanel style="width:800;height:600;" id="timelinePnl">
<a4j:outputPanel id="dataPanel" ajaxRendered="true">
<!-- your components to be updated go here -->
</a4j:outputPanel>
</rich:modalPanel>
So my content is updated with the results of my timelineBean.doGenerateLog method each time i open the modalPanel .

ui:repeat with a list sending right object to a p:dialog

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.

PrimeFaces Extensions: Why is <pe:resetInput> rendered?

I have a small problem with PrimeFaces Extensions.
I use the Tag inside a CommandButton.
The functionality is OK, but the "pe-Tag" is rendered and makes a gap between two buttons, which is bigger than without the tag. (you can see it on the picture)
Any idea how I have to configure my button, so that the "pe-Tag" is not rendered?
Picture:
Button-Code:
<p:commandButton value="#{labels.abort}"
icon="ui-icon-cancel"
process="#this"
update=":workflowContentPanel"
immediate="true"
actionListener="#{workflowHandler.abort}"
rendered="#{myBean.entity}">
<pe:resetInput target="workflowPG"/>
</p:commandButton>
OK, found out.
Sometimes Eclipse does make funny things.
There was an "invisible" blank inside my code. Don't know why, haven't used auto format or something similar ;-(
The blank was between the closing bracket from and the opening bracket from

JSF jumping to anchor right away

When a JSF commandLink is clicked, the scrollposition of the new page will be 0 - which is fine.
I noticed a strange behaviour with one of my jsf pages - but its acuallty quite hard to explain:
Clicking on a link in order to navigate "somewhere" usually freezes the page and when the new response is received, you'll end up on another page and the scrollposition gets reseted. This is fine.
In that particular case the "current" view is immediately scrolling to the top, once a commandlink is clicked, and THEN forwards to the desired navigation outcome.
Its like clicking on a plain link, that has just its anchor set to the top. <a href='#'>
What could be a possible reason for this? It feels very strange, if the page scrolls up the second you click on a link.
All pages have basically the same usage of commandlinks within datatables. No other page encounters that problems. The Controllers are different - but since the scrolling up is done within milliseconds, I dont think, that this is a server-side issue.
I noticed that jsf appends the # to all links, that are generated.
so, when I click on the link, I can see the url changing to .../page.xhtml# for a split second (the split second, the page scrolls up), and then getting re-jsft like .../page.xhtml?cid=4
edit:
for all my pages, the link looks like this:
SVA
However on that said page the return false; at the end is missing... which then makes the link behave like an anchor...
edit2:
The working-as-expected-links are generated, using <h:commandLink> - the ones that are making the page scroll up, are <p:commandLink>s (Primefaces). Indeed, replacing it, solves the issue, but still wonder what's different for the primefaces link.
edit3: Example
working as expected:
<h:form style="display:inline;">
<h:commandLink
action="#{processManagementController.unpinProcess(process)}">
<h:graphicImage
style="display:inline-block; height:16px; width:16px;"
value="/resources/img/pinned.png"
title="Click to unpin this process" />
</h:commandLink>
</h:form>
causes immediate scrolling:
<h:form style="display:inline;">
<p:commandLink ajax="false"
action="#{processManagementController.unpinProcess(process)}">
<h:graphicImage
style="display:inline-block; height:16px; width:16px;"
value="/resources/img/pinned.png"
title="Click to unpin this process" />
</p:commandLink>
</h:form>
It's not scrolled to top due to href="#", but because of the synchronous postback (which results in a complete reload of the page!). The both examples in your "edit3" still scrolls to top for me.
Nest <f:ajax> in the <h:commandLink>, or set ajax="true" on the <p:commandLink> to make it an asynchronous postback and thus get them to behave as intented.

Resources