2013-07-15 50 views
0

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

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

公共类PagerRenderer延伸渲染{

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); 
} 

回答

1

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

我看到你尝试的onclick实施你的表,如果您使用的钻嘴鱼科,那么它有utils的方法,你帮助你渲染的onclick行为,将使用F工作:AJAX以及 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

你可以使用它你的编码方法内部

+0

我的编码方法编码这类的onclick值:'document.forms [ 'tableformpaginator'] [ 'tableformpaginator-分页程序'] =值 '3'。 。document.forms [ 'tableformpaginator']提交();返回false;' 它传递给响应参数tableformpaginator-paginator,它的值为3并提交表单。 renderSelectOnclick方法以ui组件作为参数,但是我需要渲染,它无法传递给此方法作为参数。而我应该如何修改这个方法来将我的参数添加到响应中? – kalym4ik