The <o:lazyPanel> is a component that defers rendering of its children until the panel has scrolled into view. This is useful for
expensive regions below the fold, where building the children would otherwise happen on every page load even though the user may never scroll far enough to
see them.
On initial render, the component writes a wrapper element with a placeholder (optional, see "Placeholder" below) and schedules a viewport intersection
listener on it via OmniFaces.js, which uses IntersectionObserver when available and falls back to
scroll/resize/orientationChange listeners otherwise. As soon as the wrapper intersects the viewport, a single
faces.ajax.request targeting its own client id is fired. During that request, the component detects the trigger, invokes the optional listener
with a LazyPanelEvent argument, flips its loaded flag, and renders its children in place of the placeholder.
<o:lazyPanel>
<h:dataTable value="#{bean.expensiveList}" var="row">
...
</h:dataTable>
</o:lazyPanel>
The loaded attribute is a server-side escape hatch: when true, the children are rendered immediately without any client side
observer. This is useful for print views, SEO crawlers, or tests.
The listener attribute can be used to invoke a bean method with an optional LazyPanelEvent argument. It is invoked exactly once, when
the component is triggered by the client side intersection.
<o:lazyPanel listener="#{bean.load}">
...
</o:lazyPanel>
The listener is invoked from #decode(FacesContext), which then jumps straight to the render response phase. The component therefore effectively
behaves like a jakarta.faces.component.UICommand with immediate="true": the process validations, update model values and invoke
application phases are skipped for the lazy panel ajax request, so any concurrently submitted input values in the enclosing form are not processed,
validated, or applied. If you need those values on the server, submit them through a separate ajax request before the lazy panel triggers.
Nested <f:param> or <o:param> children are sent along with the lazy panel ajax request and can be retrieved by the
listener via org.omnifaces.util.Faces#getRequestParameter(String). This is useful to pass context (like an entity id, filter key, or page number) so
that a single listener can serve multiple panels.
<o:lazyPanel listener="#{bean.load}">
<f:param name="productId" value="#{product.id}" />
...
</o:lazyPanel>
Parameter values are evaluated at initial render (snapshot semantics), consistent with jakarta.faces.component.UIParameter usage elsewhere
in Faces. For values that must be fresh at trigger time, read them from the surrounding bean state in the listener itself.
By default the wrapper is rendered as a <div>. Set layout="inline" to render a <span> instead:
<o:lazyPanel layout="inline">
...
</o:lazyPanel>
To show a skeleton or spinner while the lazy region is still off-screen, put it in a facet named placeholder:
<o:lazyPanel>
<f:facet name="placeholder">
<div class="skeleton">Loading...</div>
</f:facet>
...
</o:lazyPanel>
| Info | Value |
|---|---|
| Component Type | org.omnifaces.component.output.LazyPanel |
| Handler Class | org.omnifaces.component.output.LazyPanelHandler |
| Renderer Type | None |
| Description | None |
| Name | Required | Type | Description |
|---|---|---|---|
binding | false | jakarta.el.ValueExpression
(must evaluate to jakarta.faces.component.UIComponent)
| The ValueExpression linking this component to a property in a backing bean. |
id | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| The component identifier for this component. This value must be unique within the closest parent component that is a naming container. |
layout | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| The layout of the wrapper element. Supported values are "block" (renders a <div>) and "inline" (renders
a <span>). |
listener | false | jakarta.el.ValueExpression
(must evaluate to jakarta.el.MethodExpression)
| The method expression to invoke when the lazy panel is triggered. |
loaded | false | jakarta.el.ValueExpression
(must evaluate to boolean)
| Whether the children are considered loaded and should be rendered immediately. This can be used as a server-side escape hatch for print views, SEO crawlers, or tests. |
rendered | false | jakarta.el.ValueExpression
(must evaluate to boolean)
| Flag indicating whether or not this component should be rendered (during Render Response Phase), or processed on any subsequent form submit. The default value for this property is true. |
styleClass | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| The CSS style class to render on the wrapper element. |
Output generated by Vdldoc View Declaration Language Documentation Generator.