将Ajax行为添加到JSF渲染器 [英] Add ajax behaviour to JSF renderer
问题描述
我有一个自定义的JSF组件渲染器,可为数据表渲染分页组件,但它没有ajax行为。我了解到可以通过插入ajax来编码方法或通过支持f ajax标签来完成。不幸的是,我对ajax不太熟悉,所以能否请您告诉我如何修改此代码以使其可ajax?
I have a custom JSF component renderer that renders pagination component for datatables, but it hasn't ajax behavior . I learned that it could be done by inserting ajax to encode method or by making support of f ajax tag. Unfortunately I'm not very familiar with ajax, so could you please tell me how I should modify this code to make it ajaxable?
@FacesRenderer(componentFamily="javax.faces.Command",
rendererType="com.component.Pager")
公共类PagerRenderer扩展了Renderer {
public class PagerRenderer extends 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);
}
推荐答案
f:ajax
标签只能直接嵌套在实现ClientBehaviorHolder接口的UIComponent中。
f:ajax
tag can only be directly nested in an UIComponent which implements the ClientBehaviorHolder interface.
我看到您尝试为表实现onclick,如果您使用的是Mojarra,则它具有utils方法,可帮助您呈现可与f一起使用的onclick行为:ajax以及
renderSelectOnclick
I saw that you try to implement onclick for your table, if you are using Mojarra, then it has utils method that you help you render onclick behavior that will work with f:ajax as well
renderSelectOnclick
您可以在编码方法中使用它
You can use it inside your encode method
这篇关于将Ajax行为添加到JSF渲染器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!