JSF Primefaces load ResultSet directly to <p:dataTable> [duplicate] - jsf

Is there a way to decrease the load time of the page in IE just by using Data tables.
If we use server side pagination and sorting, can we also do a quick search on server side and also render only that particular tab instead of the whole page.
<h:panelGroup id="transactionsPanel">
<h:dataTable>
</h:dataTable>
<ui:repeat value="#{backing.pages}" var="page" varStatus="current">
<h:commandLink value="#{page}" actionListener="#{backing.page}"
rendered="#{page != backing.currentPage}" >
<f:ajax render="transactionsPanel"/>
</h:commandLink>
<ui:repeat>
</h:panelGroup>
The listener is called but the page is not updated to display the next page clicked.

Is there a way to decrease the load time of the page in IE just by using Data tables.
No.
At least, not without replacing IE by a more sane webbrowser. IE is known to have a poor HTML <table> renderer. This is a client problem, not a server (JSF) problem. You can confirm this by measuring the network traffic speed and browser HTML rendering speed.
If we use server side pagination and sorting, can we also do a quick search on server side and also render only that particular tab instead of the whole page.
Just perform the search (by ajax) in server side as well.
I recommend to look at JSF component libraries instead of grabbing to loose jQuery plugins and cobbling loose scripts together. PrimeFaces for example has a lazily loadable <p:dataTable> which solves all your problems with just clean XHTML and JPA. See also the lazy <p:dataTable> showcase example and Efficient JSF Pagination.

Related

Is there a way to make a graphicimage in Primefaces execute the "value" method only on demand?

I want to show a custom gallery with several thumbnails. When clicking on one of these, an overlaypanel is shown, containing a graphicimage with the image in higher quality. Since the high quality images are aroung 5MB each, I just want to load them on demand.
I already tried using the "rendered" attribute, but that did not seem to do the trick either. I also tried the "onclick" with a javascript function, but that also did not yield the expected result.
<p:graphicImage value="#{dataHolderBean.imageHolderBean.loadFullSizeImage()}"
class="centeredImageOverlay" cache="false">
<f:param name="currentImageId" value="#{images.imageId}" />
</p:graphicImage>
I would like to just call value="#{dataHolderBean.imageHolderBean.loadFullSizeImage()}" this method, when clicking on another image.
Why did you not look for a solution that loads the content of the overlay panel lazy? That to me sounds like a much more generic solution (anything inside it would be loaded lazy then) you stand and a higher chance of something already being implemented.
From the PrimeFaces showcase of the p:overlayPanel(emphasis mine)
Overlay Panel
OverlayPanel is a generic container component that can overlay other
components on page. Notable features are custom positioning,
configurable events and effects. Lazy content loading to reduce page
load time is also supported via dynamic option, when enabled
overlayPanel will load the contents just before being shown.
From the PrimeFaces documentation
Dynamic Mode
Dynamic mode enables lazy loading of the content, in this
mode content of the panel is not rendered on page load and loaded just
before panel is shown. Also content is cached so consecutive displays
do not load the content again. This feature is useful to reduce the
page size and reduce page load time.
So the lazy loading is done via the dynamic attribute which has an example even in the showcase
<p:commandButton id="movieBtn" value="Dynamic" type="button" />
<p:overlayPanel id="moviePanel" for="movieBtn" hideEffect="fade" dynamic="true" style="width:600px" modal="true">
...
</p:overlayPanel>
You can use the built-in LazyDefaultStreamedContent in your bean, to lazy initialize the stream:
streamedContent = new LazyDefaultStreamedContent("application/vnd.ms-excel", "myExcel") {
#Override
protected InputStream initStream()
{
return new FileInputStream(...);
}
};

Render a jsf element on mouseover

I have a <h:panelGrid> and a h:commandLink(link is basically a image).Now I want that on mouseover event , Then link should be render(render='true') and on mouseout event, it gets removed render='false'.But I am unable to create the logic that How can I do this with these events as the approach I am using is To set the values of bean true and false on this event.
Here is my code
<h:form>
<h:panelGrid mouseover='** we cannot call a bean method here which changes the bean value **'>
This is the Div On which I want to apply mouseover event
</h:panelGrid>
<h:commandLink id="btn" render={renderBean.renderLink}>
<h:graphicImage url="image.jpg"/>
</h:commandLink>
</h:form>
The default value of renderLink attribute of renderBean is false. Now I want to know the way that How can I change its value to true on mouseover event? Is it possible? OR Anyother solution in JSF w.r.t this requirement
You have to remember in JSF that the page will first be processed server-side by the JSF engine in the web server. At that time all JSF tags will be converted into their HTML equivalent. The render attribute tells the server-side engine whether or not to output an HTML a (anchor) link in the place of the <h:commandLink> element.
The behavior you're looking for, namely responding to mouse events, is client-side functionality. It happens in the browser, not at the web server, so no JSF is involved. The solution is to handle the mouse events in JavaScript, not JSF. You will typically set (or remove) the CSS attribute display:none on the id called btn (unfortunately it's slightly more complex as JSF will mangle the element id a bit). There are lots of posts here on StackOverflow that deal with how to handle client-side events in JavaScript. Using jQuery for example is a really common approach.
I recommend to get started you take a look at the blog of one of our best JSF resources and long-time StackOverflow user BalusC: http://balusc.blogspot.com.
There's a lot to learn and you'll get a good start by going there first (and searching for his posts on SO).
Good luck.

Composite component in ui:repeat vs c:forEach using ajax calls

I have a composite component, which represents an item that will be stored in a list. I would like to display these items using <ui:repeat>, but I have problems making ajax calls. The thing is that for <f:ajax> render attribute, I want to give the id of my component through
#{cc.clientId}
However this raises error when I use it with <ui:repeat>, because of the reasons that are explained in this document https://rogerkeays.com/jsf-c-foreach-vs-ui-repeat.
<cc:implementation>
<div id="#{cc.clientId}">
<h:form>
<h:commandLink styleClass="btn btn-info" value="Click me">
<f:ajax execute="#form"
render=":#{cc.clientId}"/>
</h:commandLink>
</h:form>
</div>
</cc:implementation>
Is there a way to make the above component work using <ui:repeat> (for example is there a component which can replace the <f:ajax> tag handler, or are we stuck to <c:forEach> construct)?
<ui:repeat id="myComponent" value="#{backingBean.myComponentItem}" var="item" varStatus="itemIndex">
<components:exampleComponent id="myComponent"/>
</ui:repeat>
So I start using <c:forEach> instead of <ui:repeat>, and I was able to use the id of my component in the render attribute of <f:ajax>. But this time when I make pagination, if the size of the list decreases I start having empty components in my page. For solving this I started doing pagination through ajax calls and this solved the empty component problem.
Just I thought everything was solved I encountered another problem: lets say I have a page listing 10 components, and I went to another page, and from that page I came to the component displaying page again, but for some reason lets say this time I retrieved only 3 items from database, and I just want to display these 3 items through my components but nothing else.. Unfortunately in this scenario, 3 items are displayed correctly, but the page also contains 7 empty components too. For overcoming this I need to redirect to this page one-more time. So I just gave up at this point. Apart from this I also eventually get the exception below, when the number of the components on the page changes.
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.sun.faces.application.view.StateHolderSaver
I tried using the suggestion explained in the post Jsf Error : java.lang.ClassCastException, but it didn't work for me, I started getting another error which is similar to above exception.
<context-param>
<param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
<param-value>/pagename.xhtml</param-value>
</context-param>
So after these long explanations I would just like to learn what is the best approach for creating composite components which are ajax-enabled, who are fully responsible of their own-states and independent of other components, and that can be displayed in the page more than once and the number of components may vary during the page life-cycle (through pagination, navigation etc).
So far the best solution I came up with is, to check number of components in the page and when that number changes through an ajax call or because of a navigation from another page, redirect to the destination page one more time, this refreshes the empty components in the page without creating much disturbance to users. If you come up with any better solution please let us know.

How to retain form data in a multi form page

I am working on JSF. I have an xhtml page with multiple forms. when i am submitting one form, and if i had made some changes on other form i am loosing it, as on submit the page is getting refreshed. I cannot use a single form. is there any way to do.
any solution will be highly appreciated.
thanks !
If you're already using JSF 2.x (your statement that you're using XHTML (Facelets) confirms this less or more), just submit the form by ajax.
It's a matter of adding the following tag to the command links/buttons of the form:
<f:ajax execute="#form" render="#form" />
This way the current <h:form> will be submitted by ajax and the current <h:form> only will be rendered (updated/refreshed). You can if necessary specify other to-be-updated components in the render attribute by adding other client ID(s).
If you're still on the old JSF 1.x, you may want to look at Ajax4jsf sublibrary of RichFaces which supports basically the same.

How to Refresh only components in certain 'box'

Say I have a websites with 3 panel grid (just for example..) and I would like to have buttons inside each grid that only cause the contents of that grid to refresh so the rest of the page doesn't necessarily have to refresh.
How do I do that?
I tried to have a form sorround that grid but it seems like the rest of the page still gets refreshed.
A Note - I'm trying to achieve something like what happens when you work with a picklist. when you move the objects between the lists there doesn't seem to be any page refresh...
Thanks!
If you are using RichFaces, you should definitivly check the Ajax chapter of the RichFaces manual. I think you will find everything you need to know there.
Here a small example for partial page rendering:
<a4j:commandButton value="update" reRender="infoBlock"/>
<h:panelGrid id="infoBlock">
<!-- Some content-->
</h:panelGrid>

Resources