我有一个自定义JSF组件渲染器,它为数据表呈现分页组件,但它没有ajax行为。我了解到可以通过将ajax插入到编码方法或支持f ajax标记来完成。不幸的是,我对ajax不是很熟悉,所以你能不能告诉我应该如何修改这段代码以使它变得可用?
@FacesRenderer(componentFamily="javax.faces.Command",
rendererType="com.component.Pager")
public class PagerRenderer扩展了Renderer {
private static final int SHOW_PAGES = 3;
private static final String HIDDEN_FIELD_ID ="tableFormPaginatorInput";
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
ClientBehaviorContext behaviorContext =
ClientBehaviorContext.createClientBehaviorContext(context,
component, "click", component.getClientId(context), null);
String id = component.getClientId(context);
UIComponent parent = component;
while (!(parent instanceof UIForm)) parent = parent.getParent();
String formId = parent.getClientId(context);
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", component);
writer.writeAttribute("class", "paginator-section", null);
String styleClass = (String) component.getAttributes().get("styleClass");
String selectedStyleClass
= (String) component.getAttributes().get("selectedStyleClass");
String dataTableId = (String) component.getAttributes().get("dataTableId");
// find the component with the given ID
UIData data = (UIData) component.findComponent(dataTableId);
int first = data.getFirst();
int itemcount = data.getRowCount();
int pagesize = data.getRows();
if (pagesize <= 0) pagesize = itemcount;
int pages = itemcount / pagesize;
if (itemcount % pagesize != 0) pages++;
int currentPage = first / pagesize;
if (first >= itemcount - pagesize) currentPage = pages - 1;
int startPage = 0;
int endPage = pages;
if (SHOW_PAGES > 0) {
startPage = (currentPage / SHOW_PAGES ) * SHOW_PAGES ;
endPage = Math.min(startPage + SHOW_PAGES , pages);
}
if (currentPage > 0)
writeLink(writer, component, formId, id, "<", styleClass);
if (startPage > 0)
writeLink(writer, component, formId, id, "..", styleClass);
for (int i = startPage; i < endPage; i++) {
writeLink(writer, component, formId, id, "" + (i + 1),
i == currentPage ? selectedStyleClass : styleClass);
}
if (endPage < pages)
writeLink(writer, component, formId, id, "...", styleClass);
if (first < itemcount - pagesize)
writeLink(writer, component, formId, id, ">", styleClass);
/* CommandButton commandButton = new CommandButton();
commandButton.setValue(currentPage);
commandButton.setUpdate("");
commandButton.setAjax(true);
commandButton.addActionListener(new MyActionListener());
commandButton.encodeAll(context);*/
writer.endElement("div");
// hidden field to hold result
writeHiddenField(writer, component, id);
}
private void writeLink(ResponseWriter writer, UIComponent component,
String formId, String id, String value, String styleClass)
throws IOException {
writer.writeText(" ", null);
writer.startElement("a", component);
writer.writeAttribute("href", "#", null);
writer.writeAttribute("onclick", onclickCode(formId, id, value) , null);
if (styleClass != null)
writer.writeAttribute("class", styleClass, "styleClass");
writer.writeText(value, null);
writer.endElement("a");
}
private void writeLink1(ResponseWriter writer, UIComponent component,
String formId, String id, String value, String styleClass)
throws IOException {
writer.writeText(" ", null);
writer.startElement("a", component);
writer.writeAttribute("href", "#", null);
writer.writeAttribute("data-tableFormPaginator", value, null);
if (styleClass != null)
writer.writeAttribute("class", styleClass, "styleClass");
writer.writeText(value, null);
writer.endElement("a");
}
private String onclickCode(String formId, String id, String value) {
return new StringBuilder().append("document.forms['")
.append(formId).append("']['")
.append(id).append("'].value='").append(value).append("'; document.forms['")
.append(formId).append("'].submit(); return false;").toString();
}
private String onclickCodewithout(String formId, String id, String value,UIComponent component) {
return "jsf.ajax.request('" + component.getClientId() +
"', null, {'render': '" +
component.getParent().getClientId() + "',"+id+":"+value+" })";
}
private void writeHiddenField(ResponseWriter writer, UIComponent component,
String id) throws IOException {
writer.startElement("input", component);
writer.writeAttribute("id", HIDDEN_FIELD_ID, null);
writer.writeAttribute("class", "paginator-input-value", null);
writer.writeAttribute("type", "hidden", null);
writer.writeAttribute("name", id, null);
writer.endElement("input");
}
public void decode(FacesContext context, UIComponent component) {
String id = component.getClientId(context);
Map<String, String> parameters
= context.getExternalContext().getRequestParameterMap();
String response = (String) parameters.get(id);
if (response == null || response.equals("")) return;
String dataTableId = (String) component.getAttributes().get("dataTableId");
int showpages = SHOW_PAGES ;//toInt(component.getAttributes().get("showpages"));
UIData data = (UIData) component.findComponent(dataTableId);
int first = data.getFirst();
int itemcount = data.getRowCount();
int pagesize = data.getRows();
if (pagesize <= 0) pagesize = itemcount;
if (response.equals("<")) first -= pagesize;
else if (response.equals(">")) first += pagesize;
else if (response.equals("..")) first -= pagesize * showpages;
else if (response.equals("...")) first += pagesize * showpages;
else {
int page = Integer.parseInt(response);
first = (page - 1) * pagesize;
}
if (first + pagesize > itemcount) first = itemcount - pagesize;
if (first < 0) first = 0;
data.setFirst(first);
}
private static int toInt(Object value) {
if (value == null) return 0;
if (value instanceof Number) return ((Number) value).intValue();
if (value instanceof String) return Integer.parseInt((String) value);
throw new IllegalArgumentException("Cannot convert " + value);
}
答案 0 :(得分:1)
f:ajax
标记只能直接嵌套在实现ClientBehaviorHolder接口的UIComponent中。
我看到你试图为你的表实现onclick,如果你正在使用Mojarra,那么它有utils方法,你可以帮助你渲染onclick行为,它将与f:ajax一起使用
renderSelectOnclick
您可以在编码方法中使用它