- All Implemented Interfaces:
PartialStateHolder,StateHolder,TransientStateHolder,ComponentSystemEventListener,FacesListener,SystemEventListenerHolder,EventListener
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.
Usage
<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.
Listener
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 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.
Request parameters
Nested <f:param> or <o:param> children are sent along with the lazy panel ajax request and can be retrieved by the
listener via 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 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.
Layout
By default the wrapper is rendered as a <div>. Set layout="inline" to render a <span> instead:
<o:lazyPanel layout="inline">
...
</o:lazyPanel>
Placeholder
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>
- Since:
- 5.3
- Author:
- Bauke Scholtz
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringThe component type, which is "org.omnifaces.component.output.LazyPanel".static final StringThe omnifaces event value, which is "loadLazyPanel".static final StringThe name of the facet used to render a placeholder while the children are not yet loaded.Fields inherited from class org.omnifaces.component.output.OutputFamily
COMPONENT_FAMILYFields inherited from class jakarta.faces.component.UIComponent
ATTRS_WITH_DECLARED_DEFAULT_VALUES, BEANINFO_KEY, bindings, COMPOSITE_COMPONENT_TYPE_KEY, COMPOSITE_FACET_NAME, FACETS_KEY, VIEW_LOCATION_KEY -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoiddecode(FacesContext context) If this is a lazy panel request targeting this component, then invoke the listener, if any, flip the loaded flag, and jump straight to the render response phase.voidencodeChildren(FacesContext context) Always writes the wrapper element with the component client id so that the ajax partial update can replace it, then renders either the placeholder (when not yet loaded) or the actual children.Returns the layout of the wrapper element.Returns the method expression to invoke when the lazy panel is triggered.Returns the CSS style class to render on the wrapper element.static booleanisLazyPanelRequest(FacesContext context) Returnstrueif the current request is triggered by a lazy panel ajax request.booleanisLoaded()Returns whether the children have been loaded.voidSets the layout of the wrapper element.voidsetListener(MethodExpression listener) Sets the method expression to invoke when the lazy panel is triggered.voidsetLoaded(boolean loaded) Sets whether the children are considered loaded and should be rendered immediately.voidsetStyleClass(String styleClass) Sets the CSS style class to render on the wrapper element.Methods inherited from class org.omnifaces.component.output.OutputFamily
getFamily, getRendersChildrenMethods inherited from class jakarta.faces.component.UIComponentBase
addClientBehavior, addFacesListener, broadcast, clearInitialState, encodeAll, encodeBegin, encodeEnd, findComponent, getAttributes, getChildCount, getChildren, getClientBehaviors, getClientId, getDefaultEventName, getEventNames, getFacesContext, getFacesListeners, getFacet, getFacetCount, getFacets, getFacetsAndChildren, getId, getParent, getPassThroughAttributes, getRenderer, getRendererType, invokeOnComponent, isRendered, isTransient, markInitialState, processDecodes, processRestoreState, processSaveState, processUpdates, processValidators, queueEvent, removeFacesListener, restoreAttachedState, restoreState, saveAttachedState, saveState, setId, setParent, setRendered, setRendererType, setTransient, visitTreeMethods inherited from class jakarta.faces.component.UIComponent
getClientId, getCompositeComponentParent, getContainerClientId, getCurrentComponent, getCurrentCompositeComponent, getListenersForEventClass, getNamingContainer, getPassThroughAttributes, getResourceBundleMap, getStateHelper, getStateHelper, getTransientStateHelper, getTransientStateHelper, getValueExpression, initialStateMarked, isCompositeComponent, isInView, isVisitable, popComponentFromEL, processEvent, pushComponentToEL, restoreTransientState, saveTransientState, setInView, setValueExpression, subscribeToEvent, unsubscribeFromEvent
-
Field Details
-
COMPONENT_TYPE
The component type, which is "org.omnifaces.component.output.LazyPanel".- See Also:
-
EVENT_VALUE
The omnifaces event value, which is "loadLazyPanel".- See Also:
-
PLACEHOLDER_FACET_NAME
The name of the facet used to render a placeholder while the children are not yet loaded.- See Also:
-
-
Constructor Details
-
LazyPanel
public LazyPanel()
-
-
Method Details
-
decode
If this is a lazy panel request targeting this component, then invoke the listener, if any, flip the loaded flag, and jump straight to the render response phase.- Overrides:
decodein classUIComponentBase
-
encodeChildren
Always writes the wrapper element with the component client id so that the ajax partial update can replace it, then renders either the placeholder (when not yet loaded) or the actual children.- Overrides:
encodeChildrenin classUIComponentBase- Throws:
IOException
-
getLayout
Returns the layout of the wrapper element. Supported values are"block"(renders a<div>) and"inline"(renders a<span>). Default is"block".- Returns:
- The layout of the wrapper element.
-
setLayout
Sets the layout of the wrapper element. Supported values are"block"(renders a<div>) and"inline"(renders a<span>).- Parameters:
layout- The layout of the wrapper element.
-
getListener
Returns the method expression to invoke when the lazy panel is triggered. The method may optionally accept aLazyPanelEventargument.- Returns:
- The listener method expression, or
nullif none was specified.
-
setListener
Sets the method expression to invoke when the lazy panel is triggered.- Parameters:
listener- The listener method expression.
-
isLoaded
public boolean isLoaded()Returns whether the children have been loaded. This istruewhen the component has been triggered by an intersection, or when theloadedattribute has been explicitly set totrueby the user (server-side escape hatch). Default isfalse.- Returns:
- Whether the children have been loaded.
-
setLoaded
public void setLoaded(boolean loaded) Sets 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.- Parameters:
loaded- Whether the children have been loaded.
-
getStyleClass
Returns the CSS style class to render on the wrapper element.- Returns:
- The CSS style class to render on the wrapper element.
-
setStyleClass
Sets the CSS style class to render on the wrapper element.- Parameters:
styleClass- The CSS style class to render on the wrapper element.
-
isLazyPanelRequest
Returnstrueif the current request is triggered by a lazy panel ajax request.- Parameters:
context- The involved faces context.- Returns:
trueif the current request is triggered by a lazy panel ajax request.
-