-
Available since OmniFaces 1.1
The <o:componentIdParam>
component allows to render just one or more components on a view via a GET parameter.
Components can be identified via both their client id or simple component id. Via the former it's possible to e.g. render only a specific row in a table. For specific cases, it's possible to render only the parent component and omit any children.
Among the use cases for this is creating simple mashups from various Faces based views, and scripts needing to obtain markup for specific components on an initial (non-faces) request.
Note that this is a rather specialized component and for many common use cases the user is advised to investigate if the existing AJAX and partial page requests in Faces don't already cover the requirements. For the moment this component only supports the direct output of the original markup and does not wrap it into any "partial response" envelope.
Output
Foo component
Bar Component
Render foo and bar components on new page
Form
Table
row1 |
row2 |
row3 |
Render only table component on new page
Render single table row on new page
Load table into below <div>
using jQuery
Expandable list
Selected item:
Remember to pass start index as <f:param>
along command links/buttons inside repeated item,
so that the model can properly be preinitialized to identify the repeated item on which the action is invoked.
See also the "select" command link source code of this example.
<f:metadata>
<o:componentIdParam componentIdName="component" clientIdName="client" />
</f:metadata>
<h3>Output</h3>
<p><h:outputText id="foo" value="Foo component" /></p>
<p><h:outputText id="bar" value="Bar Component" /></p>
<p>
<h:link target="_blank">
<f:param name="component" value="foo"/>
<f:param name="component" value="bar"/>
Render foo and bar components on new page
</h:link>
</p>
<hr/>
<h3>Form</h3>
<h:form id="form">
Submitted value: #{componentParamBean.input}
<h:inputText value="#{componentParamBean.input}" />
<h:commandButton value="submit" />
</h:form>
<p>
<h:link target="_blank">
<f:param name="component" value="form"/>
Render form on new page
</h:link>
</p>
<hr/>
<h3>Table</h3>
<h:dataTable id="table" value="#{componentParamBean.tableItems}" var="item">
<h:column>
<h:panelGroup id="pop">
<h:outputText id="row" value="#{item}" />
</h:panelGroup>
</h:column>
</h:dataTable>
<p>
<h:link target="_blank">
<f:param name="component" value="table"/>
Render only table component on new page
</h:link>
<br/>
<h:link target="_blank">
<f:param name="client" value="table:1:row"/>
Render single table row on new page
</h:link>
<br/>
<a href="#" onclick="$('#contentDiv').load('#{request.requestURI}?component=table'); return false;">
Load table into below <code><div></code> using jQuery
</a>
</p>
<div id="contentDiv"></div>
<hr/>
<h3>Expandable list</h3>
<ul id="list">
<ui:repeat id="listRepeater" value="#{componentParamBean.listItems}" var="item">
<li>
<h:form>
#{item}
<h:commandLink value="select" action="#{componentParamBean.setSelectedItem(item)}">
<f:param name="start" value="#{componentParamBean.start}" />
<f:ajax render=":selectedItem" />
</h:commandLink>
</h:form>
</li>
</ui:repeat>
</ul>
<p>
<input type="button" id="showMore" value="Show 3 more using jQuery" />
Selected item: <strong><h:outputText id="selectedItem" value="#{componentParamBean.selectedItem}" /></strong>
</p>
<p>
Remember to pass start index as <code><f:param></code> along command links/buttons inside repeated item,
so that the model can properly be preinitialized to identify the repeated item on which the action is invoked.
See also the "select" command link source code of this example.
</p>
<h:outputScript>
$("#showMore").click(function() {
$list = $("#list");
var params = { start: $list.find("li").length, component: "listRepeater" };
$.get(location, params, function(html) {
$list.append(html);
});
});
</h:outputScript>
package org.omnifaces.showcase.components;
import static org.omnifaces.util.Utils.coalesce;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.omnifaces.cdi.Param;
@Named
@RequestScoped
public class ComponentParamBean {
private String input;
private List<String> tableItems;
@Inject @Param
private Integer start;
private List<String> listItems;
private String selectedItem;
@PostConstruct
public void init() {
// Fill table items.
tableItems = Arrays.asList("row1", "row2", "row3");
// Fill list items.
listItems = new ArrayList<>();
// Liberty 8.5.5/MyFaces 2.0.5 calls setStart AFTER this @PostContruct method is called,
// causing a NPE.
int size = getStart() + 3;
for (int i = getStart(); i < size; i++) {
listItems.add("item " + (i + 1));
}
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public List<String> getTableItems() {
return tableItems;
}
// Those coalesce()s are necessary because they cannot be declared as int as MyFaces would throw NPE
// when the request parameter is absent (Mojarra auto-coerces it to 0).
public void setStart(Integer start) {
this.start = coalesce(start, 0);
}
public Integer getStart() {
return coalesce(start, 0);
}
public List<String> getListItems() {
return listItems;
}
public String getSelectedItem() {
return selectedItem;
}
public void setSelectedItem(String selectedItem) {
this.selectedItem = selectedItem;
}
}