1

我有一个自定义 JSF 组件渲染器,它为数据表渲染分页组件,但它没有 ajax 行为。我了解到可以通过插入 ajax 来编码方法或通过支持 f ajax 标签来完成。不幸的是,我对 ajax 不是很熟悉,所以你能告诉我应该如何修改这段代码以使其成为 ajaxable 吗?

@FacesRenderer(componentFamily="javax.faces.Command",
    rendererType="com.component.Pager")

公共类 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);
}
4

1 回答 1

3

f:ajax标签只能直接嵌套在实现 ClientBehaviorHolder 接口的 UIComponent 中。

我看到您尝试为您的表实现 onclick,如果您使用的是 Mojarra,那么它有 utils 方法可以帮助您呈现也适用于 f:ajax 的 onclick 行为 renderSelectOnclick

http://grepcode.com/file/repo1.maven.org/maven2/com.sun.faces/jsf-impl/2.1.19/com/sun/faces/renderkit/RenderKitUtils.java#RenderKitUtils.renderSelectOnclick%28com。 sun.faces.renderkit.FacesContext%2Cjavax.faces.component.UIComponent%2Cboolean%29

您可以在您的编码方法中使用它

于 2013-07-16T04:49:44.047 回答