Package org.richfaces.renderkit.html

Source Code of org.richfaces.renderkit.html.ScrollableDataTableBaseRenderer

/**
* License Agreement.
*
* Rich Faces - Natural Ajax for Java Server Faces (JSF)
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
*/
package org.richfaces.renderkit.html;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.faces.FacesException;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import org.ajax4jsf.context.AjaxContext;
import org.ajax4jsf.javascript.JSFunction;
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.renderkit.AjaxRendererUtils;
import org.ajax4jsf.renderkit.ComponentVariables;
import org.ajax4jsf.renderkit.ComponentsVariableResolver;
import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
import org.ajax4jsf.renderkit.RendererBase;
import org.ajax4jsf.renderkit.RendererUtils.HTML;
import org.ajax4jsf.resource.InternetResource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.richfaces.component.UIScrollableDataTable;
import org.richfaces.component.util.ColumnUtil;
import org.richfaces.event.scroll.ScrollEvent;
import org.richfaces.event.sort.SortEvent;
import org.richfaces.model.SortField;
import org.richfaces.model.SortOrder;
import org.richfaces.renderkit.CompositeRenderer;
import org.richfaces.renderkit.RendererContributor;
import org.richfaces.renderkit.ScriptOptions;
import org.richfaces.utils.TemplateLoader;



/**
* @author Anton Belevich
*
*/

public abstract class ScrollableDataTableBaseRenderer extends HeaderResourcesRendererBase {
 
  private class CompositeRendererEnabler extends CompositeRenderer {
    public CompositeRendererEnabler() {
      addContributor(new SelectionRendererContributor());
    }
    @Override
    protected Class<? extends UIComponent> getComponentClass() {
      return ScrollableDataTableBaseRenderer.this.getComponentClass();
    }
   
    @Override
    public void mergeScriptOptions(ScriptOptions scriptOptions,
        FacesContext context, UIComponent component) {
      super.mergeScriptOptions(scriptOptions, context, component);
 
    }
   
    @Override
    public String getScriptContributions(String varString,
        FacesContext context, UIComponent component) {
      return super.getScriptContributions(varString, context, component);
    }
   
    @Override
    public RendererContributor[] getContributors() {
      return super.getContributors();
    }

    @Override
    public InternetResource[] getScripts() {
      return super.getScripts();
    }
   
    @Override
    public InternetResource[] getStyles() {
      return super.getStyles();
    }
  }
 
  public static final String PARTIAL_UPDATE = "partialUpdate";
  public static final String UPDATE_HEADER = "updateHeader";
 
  public static final String  FOOTER_PART = "footer";
 
  public static final String  HEADER_PART = "header";
 
  private static final String COLUMN_FROZEN_TYPE = "frozen";
 
  private static final String COLUMN_NORMAL_TYPE = "normal";
 
  private static final String PERSENTAGE_SUPPORT_ERROR_MSG = "columnsWidth property: Percentage values are not supported";
 
  private RendererBase cellTemplate = null;
 
  private RendererBase headerCellTemplate = null;
 
  private RendererBase footerCellTemplate = null;
 
  private RendererBase headerItselfTemplate = null;
 
  private CompositeRendererEnabler composite = new CompositeRendererEnabler();

  private final Log log = LogFactory.getLog(ScrollableDataTableBaseRenderer.class);
 
  private final ColumnVisitor columnsWidthCounter = new ColumnVisitor(){

    public int visit(FacesContext context, UIComponent column, ResponseWriter writer, ScrollableDataTableRendererState state) throws IOException {
     
      int prevWidth = 0;
      int width = 0;
           
     
      String widthPx = getColumnWidth(column);
      widthPx = getFormattedWidth(widthPx);
      prevWidth = state.getSumWidth();
      width = prevWidth + Integer.parseInt(widthPx);
      state.setSumWidth(width);
     
      return 1;
    }
  };
   
  private final ColumnVisitor headerCellRenderer = new ExtendedColumnVisitor(){

    public void renderContent(FacesContext context, UIComponent column, ResponseWriter writer, ScrollableDataTableRendererState state) throws IOException {
     
     
      int cell_index = state.getCellIndex();
      String client_id = state.getClientId();
      state.addId(column.getId());     
      headerCellTemplate = getHeaderCellTemplate();
     
      ComponentVariables variables =
        ComponentsVariableResolver.getVariables(headerCellTemplate, column);
      String widthPx = getColumnWidth(column);
     
      widthPx = getFormattedWidth(widthPx);
      int width = Integer.parseInt(widthPx);
     
      int sepOffset = 0;
     
      if(state.isFrozenColumn()){
        sepOffset = state.getSepOffset().intValue() + width;
      }else{
        sepOffset = state.getSepOffset().intValue() + width + 1;
        state.setSepOffset(new Integer(sepOffset));
     
     
     
     
      variables.setVariable("client_id", client_id);
      variables.setVariable("cell_index", new Integer(cell_index));
      variables.setVariable("sepOffset", new Integer(sepOffset));
      variables.setVariable("headerColumnClass", state.getColumnClass());
      Boolean sorting = getColumnSorting(state.getGrid(), column.getId());
      if (sorting != null) {
        if (sorting.booleanValue()) {
          variables.setVariable("headerColumnSortClass", "rich-sdt-header-sort-up");
        } else {
          variables.setVariable("headerColumnSortClass", "rich-sdt-header-sort-down");
        }
      }
      //variables.setVariable("headerCellClass", state.get);
     
      headerCellTemplate.encodeBegin(context, column);
      headerRenderer.visit(context, column, writer, state);
      headerCellTemplate.encodeEnd(context, column);
    }
  };

  private final ColumnVisitor styleRenderer = new ColumnVisitor(){

    public int visit(FacesContext context, UIComponent column, ResponseWriter writer, ScrollableDataTableRendererState state) throws IOException {
     
      int cell_index = state.getCellIndex();
      String widthPx = getColumnWidth(column);
      widthPx = getFormattedWidth(widthPx);
      int width = Integer.parseInt(widthPx);
     
      writer.writeText("#" + getNormalizedId(context, state.getGrid())+ " .dr-sdt-c-" + cell_index + " {", "width");
      writer.writeText("width: " + width + "px;", "width");
      writer.writeText("}", "width");     
      return 0;
    }
  };
 
  private final ColumnVisitor headerRenderer = new ColumnVisitor() {
   
    public int visit(FacesContext context, UIComponent column,
        ResponseWriter writer, ScrollableDataTableRendererState state)
        throws IOException {
     
      ComponentVariables variables =
        ComponentsVariableResolver.getVariables(getHeaderItselfTemplate(), column);
     
      int cell_index = state.getCellIndex();
      String client_id = state.getClientId();
      Boolean sorting = getColumnSorting(state.getGrid(), column.getId());
     
      if (sorting != null) {
        if (sorting.booleanValue()) {
          variables.setVariable("sortAscending", Boolean.TRUE);
        } else {
          variables.setVariable("sortDescending", Boolean.TRUE);
        }
      }
      variables.setVariable("client_id", client_id);
      variables.setVariable("cell_index", new Integer(cell_index));
     
      getHeaderItselfTemplate().encodeBegin(context, column);
     
      UIComponent header = column.getFacet(HEADER_PART);
     
      if(header != null){
        renderChild(context, header);
      }
      getHeaderItselfTemplate().encodeEnd(context, column);
     
      return 0;
    }
   
   
   
  };
 
  private final ColumnVisitor footerCellRenderer = new ExtendedColumnVisitor(){

    public void renderContent(FacesContext context, UIComponent column, ResponseWriter writer, ScrollableDataTableRendererState state) throws IOException {
     
      int cell_index = state.getCellIndex();
      String client_id = state.getClientId();
     
      footerCellTemplate = getFooterCellTemplate();
     
      ComponentVariables variables = ComponentsVariableResolver.getVariables(footerCellTemplate, column);
      variables.setVariable("client_id", client_id);
      variables.setVariable("cell_index", new Integer(cell_index));
      variables.setVariable("footerColumnClass", state.getColumnClass());
     
      Boolean sorting = getColumnSorting(state.getGrid(), column.getId());
      if (sorting != null) {
        if (sorting.booleanValue()) {
          variables.setVariable("footerColumnSortClass", "rich-sdt-footer-sort-up");
        } else {
          variables.setVariable("footerColumnSortClass", "rich-sdt-footer-sort-down");
        }
      }
     
      UIComponent component = column.getFacet(FOOTER_PART);
      if(component != null){
        footerCellTemplate.encodeBegin(context, column);
        renderChild(context, component);
        footerCellTemplate.encodeEnd(context, column);
      }  
    }
  };
 
  private final ColumnVisitor cellRenderer = new ExtendedColumnVisitor(){

    public void renderContent(FacesContext context, UIComponent column, ResponseWriter writer, ScrollableDataTableRendererState state) throws IOException {
     
      String cell_id = state.getRowIndex()+ "_" + state.getCellIndex();
      if (log.isTraceEnabled()) {
        log.trace("cell_index: "  + cell_id);
      }
     
      String client_id = state.getClientId();
      int cell_index =  state.getCellIndex();
      cellTemplate = getCellTemplate();
     
      ComponentVariables variables = ComponentsVariableResolver.getVariables(cellTemplate, column);
      variables.setVariable("cell_id",cell_id);
      variables.setVariable("client_id", client_id);
      variables.setVariable("cell_index", new Integer(cell_index));
      variables.setVariable("columnClass", state.getColumnClass());
      Boolean sorting = getColumnSorting(state.getGrid(), column.getId());
      if (sorting != null) {
        if (sorting.booleanValue()) {
          variables.setVariable("columnSortClass", "rich-sdt-column-sort-up");
        } else {
          variables.setVariable("columnSortClass", "rich-sdt-column-sort-down");
        }
      }
         
      cellTemplate.encodeBegin(context, column);
      if(!state.isFake()) {
        renderChildren(context, column);
      }
      cellTemplate.encodeEnd(context, column);
    }
   
  };
 
 
  private final DataVisitor rowsRenderer = new DataVisitor(){

    public void process(FacesContext context, Object rowKey, Object argument) throws IOException {
     
      ScrollableDataTableRendererState state = (ScrollableDataTableRendererState)argument;
      UIScrollableDataTable  grid = state.getGrid();
     
      grid.setRowKey(rowKey);
           
      if(grid.isRowAvailable() || state.isFake()){
        String row_id;
       
        int index = state.getRowIndex();
       
        //state.setRowIndex(index);
       
        String baseClientId = grid.getBaseClientId(context);
       
        if(state.isFrozenPart()){
          row_id = baseClientId + ":f:" + index;
        }else{
          row_id = baseClientId + ":n:" + index;
        }
       
        ResponseWriter writer = context.getResponseWriter();
        writer.startElement(HTML.TR_ELEMENT, grid);
        state.setFrozenColumnCount(ScrollableDataTableUtils.getFrozenColumnsCount(grid));
        getUtils().writeAttribute(writer, "id",row_id);
        getUtils().writeAttribute(writer, "class","dr-sdt-rb rich-sdt-row " + state.getRowClass());
        addRowJavascriptEvents(writer, grid);
        if (log.isDebugEnabled()) {
          log.debug("rowIndex : " + index);
        }
       
        ColumnWalker.iterateOverColumns(context, grid, cellRenderer, writer, state);
        if(!state.isFrozenPart()){
          writer.startElement("td", grid);
          getUtils().writeAttribute(writer, "class","dr-sdt-bc dr-sdt-c-f rich-sdt-column-cell " + state.getColumnClass(state.getCellIndex()));
          writer.startElement(HTML.DIV_ELEM, grid);
          getUtils().writeAttribute(writer, "class","dr-sdt-cbody");
          writer.endElement(HTML.DIV_ELEM);
          writer.endElement("td");
        }
        writer.endElement(HTML.TR_ELEMENT);
        state.nextRow();
        state.setCellIndex(0);
       
     
    }
  };
   
  private final DataVisitor ajaxRowsRenderer = new DataVisitor(){

   
    public void process(FacesContext context, Object rowKey, Object argument) throws IOException {
     
      int columnsCount = 0;
     
      boolean frozenTRRendered = false;
     
      boolean normalTRRendered = false;
     
      ScrollableDataTableRendererState state = (ScrollableDataTableRendererState)argument;
      AjaxContext ajaxContext = state.getAjaxContext();
      ajaxContext.getResponseData();
     
      UIScrollableDataTable  grid = state.getGrid();
      Collection<String> collection = grid.getResponseData();

      grid.setRowKey(rowKey);
      ResponseWriter writer = context.getResponseWriter();
      state.setFrozenColumnCount(ScrollableDataTableUtils.getFrozenColumnsCount(grid));
     
      String row_id = null;
     
      String baseClientId = grid.getBaseClientId(context);
     
      for (Iterator<UIComponent> iter = grid.getChildren().iterator(); iter.hasNext(); ) {
        UIComponent kid = (UIComponent) iter.next();
       
        if (kid.isRendered()) {
         
          if (kid instanceof UIColumn){           
            if(state.isFrozenColumn() && !frozenTRRendered && state.getFrozenColumnCount() > 0){
             
              state.setFrozenPart(true);
              frozenTRRendered = true;
             
              row_id = baseClientId + ":f:" +  state.getRowIndex();
              writer.startElement("tr", grid);
              getUtils().writeAttribute(writer, "class","dr-sdt-rb rich-sdt-row " + state.getRowClass());
              getUtils().writeAttribute(writer,"id",row_id);
              addRowJavascriptEvents(writer, grid);
              collection.add(row_id);
                                             
            }else if(!state.isFrozenColumn() && !normalTRRendered){
             
              writeNormalTr(frozenTRRendered, state, grid, collection,
                  writer, baseClientId);
              normalTRRendered = true;
                 
            }

            columnsCount += cellRenderer.visit(context, kid, writer, state);
//            columnsCount += cellRenderer.visit(context, column, writer, state);


           
           
            state.nextCell();
         
          }
       
        }
     
      }
      if(!normalTRRendered){
        writeNormalTr(frozenTRRendered, state, grid, collection,
            writer, baseClientId);       
      }
      writer.startElement("td", grid);
      getUtils().writeAttribute(writer, "class","dr-sdt-bc dr-sdt-c-f rich-sdt-column-cell " + state.getColumnClass(state.getCellIndex()));
      writer.startElement(HTML.DIV_ELEM, grid);
      getUtils().writeAttribute(writer, "class","dr-sdt-cbody");
      writer.endElement(HTML.DIV_ELEM);
      writer.endElement("td");
      writer.endElement("tr");
      state.setCellIndex(0);
      state.nextRow()
    }

    private void writeNormalTr(boolean frozenTRRendered,
        ScrollableDataTableRendererState state,
        UIScrollableDataTable grid, Collection<String> collection,
        ResponseWriter writer, String baseClientId) throws IOException {
      String row_id;
      if(frozenTRRendered){
        writer.endElement("tr");
      }
     
      state.setFrozenPart(false);
      row_id = baseClientId + ":n:" +  state.getRowIndex();
     
      writer.startElement("tr", grid);
      getUtils().writeAttribute(writer,"id",row_id);
      getUtils().writeAttribute(writer, "class","dr-sdt-rb rich-sdt-row " + state.getRowClass());
      addRowJavascriptEvents(writer, grid);
      collection.add(row_id);
    }
  };

  @Override
  protected InternetResource[] getScripts() {
    return composite.getScripts();
  }
 
  @Override
  protected InternetResource[] getStyles() {
    return composite.getStyles();
  }
 
  // temporary solution RF-957
  public String getFormattedWidth(String receivedWidth ) throws IOException{
   
    String formattedWidth = receivedWidth;
       
    if(formattedWidth.endsWith("%")){
      throw new FacesException(PERSENTAGE_SUPPORT_ERROR_MSG);
    }else if(formattedWidth.endsWith("px")){
      formattedWidth = formattedWidth.substring(0,formattedWidth.indexOf("px"));
    }
 
    return  formattedWidth;
  }
   
  @Override
  protected Class<? extends UIComponent> getComponentClass() {
    return UIScrollableDataTable.class;
  }
 
  public static String getJavaScriptVarName(FacesContext context, UIScrollableDataTable grid) {
   
    String name = grid.getScriptVar();
    if (name == null) {
      String id = grid.getBaseClientId(context);
      name = "Richfaces_ScrollableGrid_" + id.replaceAll("[^A-Za-z0-9_]", "_");
    }
   
    return "window." + name;
  }
 
  public static String getNormalizedId(FacesContext context, UIScrollableDataTable grid) {
    return grid.getBaseClientId(context).replaceAll("[^A-Za-z0-9_]", "_");
  }
 
  public String createClientScrollableGrid(FacesContext context, UIScrollableDataTable grid) {
   
    ScrollableDataTableOptions  options = new ScrollableDataTableOptions(grid);
   
    options.addOption("normalizedId", getNormalizedId(context, grid));
   
    composite.mergeScriptOptions(options, context, grid);
   
    JSFunction function = new JSFunction("new ClientUI.controls.grid.ScrollableGrid");
    function.addParameter(options);
    return function.toScript();
  }
 
  protected String getScriptContributions(FacesContext context, UIScrollableDataTable grid) {
    return composite.getScriptContributions(getJavaScriptVarName(context, grid), context, grid);
  }
 
  public boolean getRendersChildren() {
    return true;
  }
 
  public void renderGridBody(FacesContext context, UIScrollableDataTable grid, boolean isFrozen) throws IOException{
   
    final ScrollableDataTableRendererState state = ScrollableDataTableRendererState.getRendererState(context);
   
    if(isFrozen){
      state.setColumType(COLUMN_FROZEN_TYPE);
    }else{
      state.setColumType(COLUMN_NORMAL_TYPE);
    }
   
    if (log.isTraceEnabled()) {
      log.trace("ScrollableDataTableBaseRenderer.renderGridBody(context, grid, isFrozen)");
    }
   
    state.setFrozenColumnCount(ScrollableDataTableUtils.getFrozenColumnsCount(grid));
    state.setFrozenPart(isFrozen);
    state.setClientId(grid.getClientId(context));
   
    if (!isFrozen || state.getFrozenColumnCount() > 0) {
      grid.walk(context, rowsRenderer, state);
      int fakeRowsCount = grid.getRows() - grid.getRowCount();
      state.setFake(true);
      for (int i = 0; i < fakeRowsCount; i++) {
        rowsRenderer.process(context, null, state);
      }
      state.setFake(false);
    }
    state.setRowIndex(ScrollableDataTableUtils.getClientRowIndex(grid));
    grid.setRowKey(null);
  }
 
  public void renderHeaders(FacesContext context, UIScrollableDataTable grid, boolean isFrozen)throws IOException{

    ResponseWriter writer = context.getResponseWriter();
    final ScrollableDataTableRendererState state = ScrollableDataTableRendererState.getRendererState(context);
   
    if(isFrozen){
      state.setColumType(COLUMN_FROZEN_TYPE);
    }else{
      state.setColumType(COLUMN_NORMAL_TYPE);
    }
   
    state.setClientId(grid.getClientId(context));
    state.setPart(HEADER_PART);
    state.setFrozenColumnCount(ScrollableDataTableUtils.getFrozenColumnsCount(grid));
    state.setFrozenPart(isFrozen);
    state.setClientId(grid.getClientId(context));
    state.setSepOffset(new Integer(0));
    ColumnWalker.iterateOverColumns(context, grid, headerCellRenderer, writer, state);
  }
 
  public void renderStyle(FacesContext context, UIScrollableDataTable grid) throws IOException {
    ScrollableDataTableRendererState state = ScrollableDataTableRendererState.getRendererState(context);
    ColumnWalker.iterateOverColumns(context, grid, styleRenderer, context.getResponseWriter(), state);
    ResponseWriter writer = context.getResponseWriter();
    writer.writeText("#" + getNormalizedId(context, state.getGrid()) + " .dr-sdt-c-f {", "width");
    writer.writeText("width: 0px;", "width");
    writer.writeText("}", "width");     
  }
 
  public void renderFooters(FacesContext context, UIScrollableDataTable grid, boolean isFrozen) throws IOException{
     
    ResponseWriter writer = context.getResponseWriter();
    final ScrollableDataTableRendererState state = ScrollableDataTableRendererState.getRendererState(context);
   
    if(isFrozen){
      state.setColumType(COLUMN_FROZEN_TYPE);
    }else{
      state.setColumType(COLUMN_NORMAL_TYPE);
    }

    state.setClientId(grid.getClientId(context));
    state.setFrozenColumnCount(ScrollableDataTableUtils.getFrozenColumnsCount(grid));
    state.setFrozenPart(isFrozen);
    int colsCount = ColumnWalker.iterateOverColumns(context, grid, footerCellRenderer, writer, state);
    int rowsCount = grid.getRowCount();
   
    ComponentVariables variables = ComponentsVariableResolver.getVariables(this, grid);
    variables.setVariable("rows_count", new Integer(rowsCount));
    variables.setVariable("columns_count", new Integer(colsCount));
   
  }
 
  public void setUpState(FacesContext context, UIScrollableDataTable grid) {
    ScrollableDataTableRendererState state = ScrollableDataTableRendererState.createState(context, grid);
    state.setRowIndex(ScrollableDataTableUtils.getClientRowIndex(grid));
  }
     
  public void tearDownState(FacesContext context, UIScrollableDataTable grid){
    ScrollableDataTableRendererState.restoreState(context);
  }
 
  public String getRowsAjaxUpdate(FacesContext context, UIScrollableDataTable grid){
   
    JSFunction function = AjaxRendererUtils.buildAjaxFunction(grid, context);
    Map<String, Object> options = AjaxRendererUtils.buildEventOptions(context, grid);
    options.put("oncomplete", AjaxFunctionBuilder.getOnComplete(context, grid, AjaxFunctionBuilder.SCROLL));

    @SuppressWarnings("unchecked")
    Map<String, Object> parametersMap = (Map<String, Object>) options.get("parameters");
   
    parametersMap.put(grid.getBaseClientId(context) + ":scroll", "");
    function.addParameter(options);
    String completeFunction = function.toScript()+"; return false;";
   
    return completeFunction;
   
  }

  @Override
  protected void doDecode(FacesContext context, UIComponent component) {
   
    super.doDecode(context, component);
   

    AjaxContext ajaxContext = AjaxContext.getCurrentInstance(context);
   
    if(component instanceof UIScrollableDataTable){
   
      UIScrollableDataTable grid = (UIScrollableDataTable)component;
      ExternalContext externalContext = context.getExternalContext();
      String clientId = grid.getClientId(context);
      boolean sorted = false
      Map<String, String> parameters = externalContext.getRequestParameterMap();
     
      String s_id = clientId + ":si";
      grid.resetReqRowsCount();
      String firstString = null;
      if(parameters.containsKey(s_id)){
        String options = (String)parameters.get(s_id);
        grid.setScrollPos(options);
        if(options.length() > 0){
          String[] si = options.split(",");
          firstString = si[1];
          if (si.length >= 5) {
            grid.setFirst(Integer.parseInt(si[4]));
          } else {
            grid.setFirst(Integer.parseInt(firstString));
          }
          component.getAttributes().put(ScrollableDataTableUtils.CLIENT_ROW_KEY, Integer.parseInt(si[3]));     
        }
      }
         
      composite.decode(context, component);
     
      if (firstString != null) {
        grid.setFirst(Integer.parseInt(firstString));
      }
     
      if(parameters.containsKey(clientId + ":sortColumn") &&
         parameters.containsKey(clientId + ":sortStartRow") &&
         parameters.containsKey(clientId + ":sortIndex")){
       
        String sortColumn = (String)parameters.get(clientId + ":sortColumn");
        int sortDataIndex = Integer.parseInt((String)parameters.get(clientId + ":sortIndex"));
        Integer sortStartRow = Integer.valueOf((String)parameters.get(clientId + ":sortStartRow"));
       
        String sortOrderString =
          (String) parameters.get(clientId + ":sortOrder");
       
        Boolean so = null;
       
        if (sortOrderString != null && sortOrderString.length() > 0 ) {
          sortOrderString = sortOrderString.toLowerCase();
         
          if (sortOrderString.startsWith("a")) {
            so = Boolean.TRUE;
          } else if (sortOrderString.startsWith("d")){
            so = Boolean.FALSE;
          }
        }
       
       
        UIComponent column = grid.findComponent(sortColumn);
       
        if(ColumnUtil.isSortable(column)){
     
          sorted = true;
          SortEvent sortEvent = new SortEvent(grid,sortColumn, grid.getRows(), sortDataIndex);
         
          sortEvent.setProposedOrder(so);
         
          sortEvent.setAttribute(ScrollableDataTableUtils.CLIENT_ROW_KEY,sortStartRow);
         
          if (ajaxContext.isAjaxRequest()) {
            sortEvent.setAttribute(PARTIAL_UPDATE, Boolean.TRUE);
            sortEvent.setAttribute(UPDATE_HEADER, Boolean.TRUE);
          }
         
         
          sortEvent.queue();
       
      }
     
     
      if(parameters.containsKey(clientId + ":scroll") && !sorted){
         
        String submitedState = (String)parameters.get(clientId + "_state_input");
        if (submitedState != null) {
          boolean isEmpty = true;
         
         
          String [] values = submitedState.split(",");
          for (int i = 0; i < values.length; i++) {
            isEmpty = isEmpty && values[i].equals("");
          }
         
          int rows = 0;
          int first = 0;
         
          if(!isEmpty){
            rows = Integer.parseInt(values[0]);
            first = Integer.parseInt(values[1]);
            ScrollEvent scrollEvent = new ScrollEvent(grid,rows,first);

            scrollEvent.setAttribute(ScrollableDataTableUtils.CLIENT_ROW_KEY,Integer.valueOf(values[2]));           
           
            if (ajaxContext.isAjaxRequest()) {
              scrollEvent.setAttribute(PARTIAL_UPDATE, Boolean.TRUE);
            }

            scrollEvent.queue();
           
          }
        }
      }
     
     
    }
   
   
  }
 
  public void renderAjaxChildren(FacesContext context, UIComponent component)throws IOException{
   
    UIScrollableDataTable grid = (UIScrollableDataTable)component;
   
   
   
    ScrollableDataTableRendererState state = ScrollableDataTableRendererState.createState(context, grid);
       
    AjaxContext ajaxContext = AjaxContext.getCurrentInstance(context);
    String client_id = grid.getClientId(context);
   
    state.setClientId(client_id);
    state.setAjaxContext(ajaxContext);
    state.setRowIndex(ScrollableDataTableUtils.getClientRowIndex(grid));
   
    if (log.isDebugEnabled()) {
      log.debug("ScrollableDataTableBaseRenderer.renderAjaxChildren()");
    }
   
    grid.getResponseData().clear();
   
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement("table", grid);
    writer.startElement("tbody", grid);
   
    grid.walk(context, ajaxRowsRenderer, state);
    int fakeRowsCount = grid.getRows() - grid.getRowCount();
    ScrollableDataTableRendererState.restoreState(context);
    grid.setRowKey(null);
    state.setFake(true);
    for (int i = 0; i < fakeRowsCount; i++) {
      ajaxRowsRenderer.process(context, null, state)
    }
   
    state.setFake(false);
   
    writer.endElement("tbody");
    writer.endElement("table");
    String id = client_id+"_rows_input";
    writer.startElement(HTML.INPUT_ELEM, grid);
    writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
    writer.writeAttribute(HTML.id_ATTRIBUTE, id, null);
    writer.writeAttribute(HTML.NAME_ATTRIBUTE, id, null);
    writer.writeAttribute(HTML.value_ATTRIBUTE, grid.getRowCount(), null);
    writer.endElement(HTML.INPUT_ELEM);
    ajaxContext.addRenderedArea(id);

    renderHiddenScrollInput(context, grid);
    ajaxContext.addRenderedArea(client_id+":si");
   
    ajaxContext.setResponseData(grid.getResponseData());
   
    ajaxContext.getAjaxRenderedAreas().remove(grid.getClientId(context));
    ScrollableDataTableScrollData options = createOptions(grid);
    ajaxContext.getResponseDataMap().put("options", options);
   
    //Then call contributors to write additional HTML content
    contributorsEncodeHere(context, grid);
 
    if (shouldUpdateHeader(component)) {
      ColumnWalker.iterateOverColumns(context, component, headerRenderer, writer, new ScrollableDataTableRendererState(context, null, grid));
    }
  }
 
  private ScrollableDataTableScrollData createOptions(UIScrollableDataTable grid){
   
    int index = grid.getFirst();
    int startRow = ScrollableDataTableUtils.getClientRowIndex(grid);
    int count = grid.getRows( )== 0 ? grid.getRowCount() : grid.getRows();
   
    ScrollableDataTableScrollData options = new ScrollableDataTableScrollData(index, startRow, count);
       
    return options;
  }
 
  private boolean onlyPartialUpdateNeeded(UIComponent grid) {
    Boolean b = (Boolean) grid.getAttributes().get(PARTIAL_UPDATE);
    return b != null && b.booleanValue() && AjaxContext.getCurrentInstance().isAjaxRequest();
  }

  private boolean shouldUpdateHeader(UIComponent grid) {
    Boolean b = (Boolean) grid.getAttributes().get(UPDATE_HEADER);
    return b != null && b.booleanValue() && AjaxContext.getCurrentInstance().isAjaxRequest();
  }
 
  @Override
  public void encodeChildren(FacesContext context, UIComponent component
                 throws IOException {
   
    if(onlyPartialUpdateNeeded(component)){
      renderAjaxChildren(context, component);
    }else{
      super.encodeChildren(context, component);
    }
   
  }
 
  @Override
  public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
   
    if(component instanceof UIScrollableDataTable){
      UIScrollableDataTable grid = (UIScrollableDataTable)component;
      setUpState(context, grid);
    }
   
    if(!onlyPartialUpdateNeeded(component)){
      super.encodeBegin(context, component);
    }
  }
 
  @Override
  public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
   
    if(component instanceof UIScrollableDataTable){
      UIScrollableDataTable table = (UIScrollableDataTable)component;
      if(!onlyPartialUpdateNeeded(table)){
        Object rowKey = table.getRowKey();
        table.setRowKey(context, null);
        super.encodeEnd(context, table);
        table.setRowKey(context, rowKey);
     
     
      component.getAttributes().remove(PARTIAL_UPDATE);
      component.getAttributes().remove(UPDATE_HEADER);
    }
  }
 
  public void setUpColumnsWidth(FacesContext context, UIScrollableDataTable grid) throws IOException{
    ScrollableDataTableRendererState state = ScrollableDataTableRendererState.getRendererState(context);
    state.setFrozenColumnCount(ScrollableDataTableUtils.getFrozenColumnsCount(grid));
    ColumnWalker.iterateOverColumns(context, grid, columnsWidthCounter, null, state);   
    ComponentVariables variables = ComponentsVariableResolver.getVariables(this, grid);
    int sumWidth = state.getSumWidth() + 200;
    variables.setVariable("sumWidth", new Integer(sumWidth));
  }

  private  RendererBase getCellTemplate() {
    if (cellTemplate == null) {
      cellTemplate = TemplateLoader.loadTemplate("org.richfaces.renderkit.html.ScrollableDataTableCellRenderer");
    }
    return cellTemplate;
  }
 
  private  RendererBase getHeaderCellTemplate() {
   
    if (headerCellTemplate == null) {
      headerCellTemplate = TemplateLoader.loadTemplate("org.richfaces.renderkit.html.ScrollableDataTableHeaderCellRenderer");
    }
    return headerCellTemplate;
  }
 
  private  RendererBase getFooterCellTemplate() {
   
    if (footerCellTemplate == null) {
      footerCellTemplate = TemplateLoader.loadTemplate("org.richfaces.renderkit.html.ScrollableDataTableFooterCellRenderer");
    }
    return footerCellTemplate;
  }
 
 
 
  private RendererBase getHeaderItselfTemplate() {
   
    if (headerItselfTemplate == null) {
      headerItselfTemplate = TemplateLoader.loadTemplate("org.richfaces.renderkit.html.ScrollableDataTableHeaderItselfRenderer");
    }
   
    return headerItselfTemplate;
  }


  public void renderHiddenScrollInput(FacesContext context, UIScrollableDataTable grid) throws IOException{
   
    ResponseWriter writer = context.getResponseWriter();
    String id = grid.getClientId(context) + ":si";
    writer.startElement("input", grid);

    getUtils().writeAttribute(writer, "type", "hidden");
    getUtils().writeAttribute(writer, "name", id);
    getUtils().writeAttribute(writer, "id", id);
    getUtils().writeAttribute(writer, "value", grid.getScrollPos());
   
    writer.endElement("input");
   
  }
 
  public void contributorsEncodeHere(FacesContext context, UIScrollableDataTable grid) throws IOException {
    RendererContributor [] contribs = composite.getContributors();
   
    if (contribs != null) {
      for (int i = 0; i < contribs.length; i++) {
        RendererContributor rendererContributor = contribs[i];
       
        if (rendererContributor instanceof HTMLEncodingContributor) {
          ((HTMLEncodingContributor) rendererContributor).encode(context, grid);
        }
      }
    }
  }
 
  private void addRowJavascriptEvents(ResponseWriter writer, UIComponent component) {
    String attribute = (String)component.getAttributes().get("onRowClick");
    if (attribute != null) {
      try {
        getUtils().writeAttribute(writer, "onclick", attribute);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    attribute = (String)component.getAttributes().get("onRowMouseDown");
    if (attribute != null) {
      try {
        getUtils().writeAttribute(writer, "onmousedown", attribute);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    attribute = (String)component.getAttributes().get("onRowMouseUp");
    if (attribute != null) {
      try {
        getUtils().writeAttribute(writer, "onmouseup", attribute);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    attribute = (String)component.getAttributes().get("onRowDblClick");
    if (attribute != null) {
      try {
        getUtils().writeAttribute(writer, "ondblclick", attribute);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
 
  private Boolean getColumnSorting(UIScrollableDataTable grid, String sortColumn) {

    Boolean sorting = null;

    UIComponent column = grid.findComponent(sortColumn);
   
    String name = ColumnUtil.getColumnSorting(column);
   
    SortOrder sortOrder = grid.getSortOrder();
   
    if (sortOrder != null) {
      SortField[] sortFields = sortOrder.getFields();
     
      if (sortFields != null) {
        for (int i = 0; i < sortFields.length && sorting == null; i++) {
          SortField sortField = sortFields[i];
         
          if (name != null && name.equals(sortField.getName())) {
            sorting = sortField.getAscending();
          }
        }
      }
    }
   
    return sorting;
  }

  private String getColumnWidth(UIComponent column) {
    String width = (String) column.getAttributes().get("width");
    if (width == null) {
      width = "100px";
    }
    return width;
  }
}
TOP

Related Classes of org.richfaces.renderkit.html.ScrollableDataTableBaseRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.