You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by to...@apache.org on 2006/04/18 23:39:28 UTC

svn commit: r395050 - in /myfaces/tomahawk/trunk: core/src/main/java/org/apache/myfaces/component/html/ext/ core/src/main/java/org/apache/myfaces/custom/column/ core/src/main/java/org/apache/myfaces/renderkit/html/ext/ core/src/main/java/org/apache/myf...

Author: tomsp
Date: Tue Apr 18 14:39:26 2006
New Revision: 395050

URL: http://svn.apache.org/viewcvs?rev=395050&view=rev
Log:
groupBy feature for dataTable

Added:
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/ColumnInfo.java
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/RowInfo.java
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/TableContext.java
    myfaces/tomahawk/trunk/examples/simple/src/main/webapp/simpleGroupBy.jsp
Modified:
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlColumnTag.java
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlSimpleColumn.java
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlTableRenderer.java
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/taglib/html/ext/HtmlDataTableTag.java
    myfaces/tomahawk/trunk/core/src/main/tld/entities/extended_data_table_attributes.xml
    myfaces/tomahawk/trunk/examples/simple/src/main/webapp/home.jsp

Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java?rev=395050&r1=395049&r2=395050&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/component/html/ext/HtmlDataTable.java Tue Apr 18 14:39:26 2006
@@ -21,6 +21,7 @@
 import org.apache.myfaces.component.UserRoleUtils;
 import org.apache.myfaces.custom.crosstable.UIColumns;
 import org.apache.myfaces.renderkit.html.ext.HtmlTableRenderer;
+import org.apache.myfaces.renderkit.html.util.TableContext;
 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
 
 import javax.faces.component.NamingContainer;
@@ -66,6 +67,8 @@
     private String _rowOnKeyUp = null;
     private String _rowStyleClass = null;
     private String _rowStyle = null;
+    private String _rowGroupStyle = null;
+    private String _rowGroupStyleClass = null;
     private String _varDetailToggler = null;
 
     private boolean _isValidChildren = true;
@@ -74,6 +77,17 @@
 
     private Map _detailRowStates = new HashMap();
 
+    private TableContext _tableContext = null;
+
+    public TableContext getTableContext()
+    {
+        if ( _tableContext == null )
+        {
+            _tableContext = new TableContext();
+        }
+        return _tableContext;
+    }
+
     public String getClientId(FacesContext context)
     {
         String standardClientId = super.getClientId(context);
@@ -497,7 +511,7 @@
     public Object saveState(FacesContext context)
     {
         boolean preserveSort = isPreserveSort();
-        Object values[] = new Object[26];
+        Object values[] = new Object[28];
         values[0] = super.saveState(context);
         values[1] = _preserveDataModel;
         if (isPreserveDataModel())
@@ -535,6 +549,8 @@
 
         values[24] = _varDetailToggler;
         values[25] = _expandedNodes;
+        values[26] = _rowGroupStyle;
+        values[27] = _rowGroupStyleClass;
 
         return values;
     }
@@ -609,6 +625,8 @@
 
         _varDetailToggler = (String)values[24];
         _expandedNodes = (Set)values[25];
+        _rowGroupStyle = (String)values[26];
+        _rowGroupStyleClass = (String)values[27];
     }
 
     public _SerializableDataModel getSerializableDataModel()
@@ -939,6 +957,29 @@
 
     }
 
+    public String getRowGroupStyle()
+    {
+        if (_rowGroupStyle != null)
+      return _rowGroupStyle;
+    ValueBinding vb = getValueBinding("rowGroupStyle");
+    return vb != null ? (String) vb.getValue(getFacesContext()) : null;
+    }
+
+    public void setRowGroupStyle(String rowGroupStyle)
+    {
+        _rowGroupStyle = rowGroupStyle;
+    }
+
+    public String getRowGroupStyleClass()
+    {
+        return _rowGroupStyleClass;
+    }
+
+    public void setRowGroupStyleClass(String rowGroupStyleClass)
+    {
+        _rowGroupStyleClass = rowGroupStyleClass;
+    }
+
     public HtmlDataTable()
     {
         setRendererType(DEFAULT_RENDERER_TYPE);
@@ -1097,6 +1138,8 @@
         ValueBinding vb = getValueBinding("previousRowDataVar");
         return vb != null ? (String) vb.getValue(getFacesContext()) : null;
     }
+
+
 
     //------------------ GENERATED CODE END ---------------------------------------
 

Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlColumnTag.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlColumnTag.java?rev=395050&r1=395049&r2=395050&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlColumnTag.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlColumnTag.java Tue Apr 18 14:39:26 2006
@@ -64,6 +64,7 @@
     private String _footeronmouseup;
 
     private String _width;
+    private String _groupBy;
 
     public String getComponentType()
     {
@@ -111,6 +112,7 @@
         _footeronmouseup = null;
 
         _width = null;
+        _groupBy = null;
     }
 
     protected void setProperties(UIComponent component)
@@ -149,6 +151,7 @@
         setStringProperty(component, "footeronkeyup", _footeronkeyup);
 
         setStringProperty(component, "width", _width);
+        setBooleanProperty(component,"groupBy",_groupBy);
     }
 
     public void setFooterdir(String footerdir)
@@ -304,5 +307,10 @@
     public void setWidth(String width)
     {
         _width = width;
+    }
+
+    public void setGroupBy(String groupBy)
+    {
+        _groupBy = groupBy;
     }
 }

Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlSimpleColumn.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlSimpleColumn.java?rev=395050&r1=395049&r2=395050&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlSimpleColumn.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/column/HtmlSimpleColumn.java Tue Apr 18 14:39:26 2006
@@ -83,13 +83,14 @@
     private String _onmouseup;
     
     private String _width;
+    private Boolean _groupBy;
     
     public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlColumn";
 
     /**
      * @param localValue
      * @param valueBindingName
-     * @return
+     * @return the value
      */
     private Object getLocalOrValueBindingValue(Object localValue,
                     String valueBindingName)
@@ -858,12 +859,25 @@
         _width = width;
     }
 
+    public boolean isGroupBy()
+    {
+        if (_groupBy != null) return _groupBy.booleanValue();
+        ValueBinding vb = getValueBinding("groupBy");
+        Boolean v = vb != null ? (Boolean)vb.getValue(getFacesContext()) : null;
+        return v != null && v.booleanValue();
+    }
+
+    public void setGroupBy(boolean groupBy)
+    {
+        _groupBy = groupBy ? Boolean.TRUE : Boolean.FALSE;
+    }
+
     /**
      * @see javax.faces.component.UIComponentBase#saveState(javax.faces.context.FacesContext)
      */
     public Object saveState(FacesContext context)
     {
-        Object[] values = new Object[47];
+        Object[] values = new Object[48];
         values[0] = super.saveState(context);
 
         values[1] = _headerdir;
@@ -915,6 +929,7 @@
         values[45] = _onmouseup;
         
         values[46] = _width;
+        values[47] = _groupBy;
 
         return values;
     }
@@ -976,5 +991,6 @@
         _onmouseup = (String) values[45];
         
         _width = (String) values[46];
+        _groupBy = (Boolean) values[47];
     }
 }

Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlTableRenderer.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlTableRenderer.java?rev=395050&r1=395049&r2=395050&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlTableRenderer.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlTableRenderer.java Tue Apr 18 14:39:26 2006
@@ -18,6 +18,9 @@
 
 import java.io.IOException;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Hashtable;
+import java.util.Enumeration;
 
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIData;
@@ -26,12 +29,16 @@
 
 import org.apache.myfaces.component.html.ext.HtmlDataTable;
 import org.apache.myfaces.custom.column.HtmlColumn;
+import org.apache.myfaces.custom.column.HtmlSimpleColumn;
 import org.apache.myfaces.custom.crosstable.UIColumns;
 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase;
+import org.apache.myfaces.renderkit.html.util.TableContext;
+import org.apache.myfaces.renderkit.html.util.RowInfo;
+import org.apache.myfaces.renderkit.html.util.ColumnInfo;
 
 /**
  * Renderer for the Tomahawk extended HtmlDataTable component.
@@ -43,43 +50,43 @@
 {
     //private static final Log log = LogFactory.getLog(HtmlTableRenderer.class);
 
-	/** DetailStamp facet name. */
+    /** DetailStamp facet name. */
     public static final String DETAIL_STAMP_FACET_NAME = "detailStamp";
-  
-    
+
+
     protected void afterRow(FacesContext facesContext, UIData uiData) throws IOException {
-		super.afterRow(facesContext, uiData);
-		
-		renderDetailRow(facesContext, uiData);
-	}
-
-	/**
-	 *  
-	 * @param facesContext
-	 * @param uiData
-	 * @throws IOException
-	 */
-	private void renderDetailRow(FacesContext facesContext, UIData uiData) throws IOException {
-		UIComponent detailStampFacet = uiData.getFacet(DETAIL_STAMP_FACET_NAME);
-		
-		if(uiData instanceof HtmlDataTable ){
-			HtmlDataTable htmlDataTable = (HtmlDataTable)uiData;
-			
-			if(htmlDataTable.isCurrentDetailExpanded()){
-				ResponseWriter writer = facesContext.getResponseWriter();
-				writer.startElement(HTML.TR_ELEM,uiData);
-				writer.startElement(HTML.TD_ELEM,uiData);
-				writer.writeAttribute(HTML.COLSPAN_ATTR,new Integer(uiData.getChildren().size()) ,null);
-				
-				if(detailStampFacet!=null){
-					RendererUtils.renderChild(facesContext, detailStampFacet);
-				}
-				
-				writer.endElement(HTML.TD_ELEM);
-				writer.endElement(HTML.TR_ELEM);
-			}
-		}
-	}
+        super.afterRow(facesContext, uiData);
+
+        renderDetailRow(facesContext, uiData);
+    }
+
+    /**
+     *
+     * @param facesContext
+     * @param uiData
+     * @throws IOException
+     */
+    private void renderDetailRow(FacesContext facesContext, UIData uiData) throws IOException {
+        UIComponent detailStampFacet = uiData.getFacet(DETAIL_STAMP_FACET_NAME);
+
+        if(uiData instanceof HtmlDataTable ){
+            HtmlDataTable htmlDataTable = (HtmlDataTable)uiData;
+
+            if(htmlDataTable.isCurrentDetailExpanded()){
+                ResponseWriter writer = facesContext.getResponseWriter();
+                writer.startElement(HTML.TR_ELEM,uiData);
+                writer.startElement(HTML.TD_ELEM,uiData);
+                writer.writeAttribute(HTML.COLSPAN_ATTR,new Integer(uiData.getChildren().size()) ,null);
+
+                if(detailStampFacet!=null){
+                    RendererUtils.renderChild(facesContext, detailStampFacet);
+                }
+
+                writer.endElement(HTML.TD_ELEM);
+                writer.endElement(HTML.TR_ELEM);
+            }
+        }
+    }
 
     /**
      * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
@@ -119,6 +126,202 @@
         }
     }
 
+
+
+    private boolean isGroupedTable(UIData uiData)
+    {
+        if(uiData instanceof HtmlDataTable)
+        {
+            List children = getChildren(uiData);
+            for (int j = 0, size = getChildCount(uiData); j < size; j++)
+            {
+                UIComponent child = (UIComponent) children.get(j);
+                if(child instanceof HtmlSimpleColumn)
+                {
+                    HtmlSimpleColumn column = (HtmlSimpleColumn) child;
+                    if(column.isGroupBy())return true;
+                }
+            }
+        }
+
+        return false;  //To change body of created methods use File | Settings | File Templates.
+    }
+
+    protected void beforeBody(FacesContext facesContext, UIData uiData) throws IOException
+    {
+
+        if(isGroupedTable(uiData))
+        {
+            createColumnInfos((HtmlDataTable) uiData, facesContext);
+        }
+        super.beforeBody(facesContext,uiData);
+    }
+
+    private void createColumnInfos(HtmlDataTable htmlDataTable, FacesContext facesContext)
+                throws IOException
+        {
+            int first = htmlDataTable.getFirst();
+            int rows = htmlDataTable.getRows();
+            int last;
+            int currentRowSpan=-1;
+            int currentRowInfoIndex=-1;
+
+            TableContext tableContext=htmlDataTable.getTableContext();
+            RowInfo rowInfo=null;
+            ColumnInfo columnInfo=null;
+            HtmlSimpleColumn currentColumn=null;
+            Hashtable groupHashTable = new Hashtable();
+            String currentColumnContent = null;
+
+            if (rows <= 0)
+            {
+               last = htmlDataTable.getRowCount();
+            }
+            else
+            {
+               last = first + rows;
+            }
+
+
+            //Loop over the Children Columns to find the Columns with groupBy Attribute true
+            List children = getChildren(htmlDataTable);
+            int nChildren = getChildCount(htmlDataTable);
+
+            for (int j = 0, size = nChildren; j < size; j++)
+            {
+                UIComponent child = (UIComponent) children.get(j);
+                if(child instanceof HtmlSimpleColumn)
+                {
+                    currentColumn = (HtmlSimpleColumn) child;
+                    if(currentColumn.isGroupBy())
+                    {
+                        groupHashTable.put(new Integer(j),"");
+                    }
+                }
+            }
+
+            boolean groupEndReached = false;
+
+            for (int rowIndex = first; last==-1 || rowIndex < last; rowIndex++)
+            {
+               htmlDataTable.setRowIndex(rowIndex);
+               rowInfo = new RowInfo();
+               //scrolled past the last row
+               if (!htmlDataTable.isRowAvailable())
+                   break;
+
+               Enumeration groupIndexList = groupHashTable.keys();
+               while(groupIndexList.hasMoreElements())
+               {
+                   currentColumnContent = "";
+                   Integer currentIndex=(Integer) groupIndexList.nextElement();
+                   currentColumn = (HtmlSimpleColumn) children.get(currentIndex.intValue());
+                   List currentColumnChildren = currentColumn.getChildren();
+                   for (int j = 0, size = currentColumnChildren.size(); j < size; j++)
+                    {
+                        UIComponent currentColumnChild = (UIComponent) currentColumnChildren.get(j);
+                        if(currentColumnChild.isRendered())
+                        {
+                            currentColumnContent += currentColumnChild.getValueBinding("value").getValue(facesContext);
+                        }
+                    }
+                    if(currentColumnContent.compareTo((String)groupHashTable.get(currentIndex))!=0 && currentRowInfoIndex > -1)
+                    {
+                        groupEndReached = true;
+                        groupHashTable.put(currentIndex,currentColumnContent);
+                    }
+                   else if(currentRowInfoIndex == -1)
+                    {
+                        groupHashTable.put(currentIndex,currentColumnContent);   
+                    }
+               }
+               currentRowSpan++;
+
+
+               for (int j = 0, size = nChildren; j < size; j++)
+                    {
+                        columnInfo = new ColumnInfo();
+                        if(groupHashTable.containsKey(new Integer(j)))  // Column is groupBy
+                        {
+                            if(currentRowSpan > 0)
+                            {
+                                if(groupEndReached)
+                                {
+                                    ((ColumnInfo)
+                                    ((RowInfo)
+                                        tableContext.getRowInfos().get(currentRowInfoIndex-currentRowSpan+1)).
+                                        getColumnInfos().get(j)).
+                                        setRowSpan(currentRowSpan);
+                                        columnInfo.setStyle(htmlDataTable.getRowGroupStyle());
+                                        columnInfo.setStyleClass(htmlDataTable.getRowGroupStyleClass());
+                                }
+                                else
+                                {
+                                    columnInfo.setRendered(false);
+                                }
+                            }
+                            else
+                            {
+                                columnInfo.setStyle(htmlDataTable.getRowGroupStyle());
+                                columnInfo.setStyleClass(htmlDataTable.getRowGroupStyleClass());
+                            }
+
+                        }
+                        else    // Column  is not group by
+                        {
+                            if(groupEndReached)
+                            {
+                                ((ColumnInfo)
+                                    ((RowInfo)
+                                        tableContext.getRowInfos().get(currentRowInfoIndex)).
+                                        getColumnInfos().get(j)).
+                                        setStyle(htmlDataTable.getRowGroupStyle());
+                                ((ColumnInfo)
+                                    ((RowInfo)
+                                        tableContext.getRowInfos().get(currentRowInfoIndex)).
+                                        getColumnInfos().get(j)).
+                                        setStyleClass(htmlDataTable.getRowGroupStyleClass());
+                            }
+                        }
+                        rowInfo.getColumnInfos().add(columnInfo);
+                    }
+                if(groupEndReached)
+                {
+                    currentRowSpan=0;
+                    groupEndReached = false;
+                }
+                tableContext.getRowInfos().add(rowInfo);
+                currentRowInfoIndex++;
+            }
+            for (int j = 0, size = nChildren; j < size; j++)
+                    {
+                        if(groupHashTable.containsKey(new Integer(j)))  // Column is groupBy
+                        {
+                                    ((ColumnInfo)
+                                    ((RowInfo)
+                                        tableContext.getRowInfos().get(currentRowInfoIndex-currentRowSpan)).
+                                        getColumnInfos().get(j)).
+                                        setRowSpan(currentRowSpan+1);
+                        }
+                        else    // Column  is not group by
+                        {
+                                ((ColumnInfo)
+                                    ((RowInfo)
+                                        tableContext.getRowInfos().get(currentRowInfoIndex)).
+                                        getColumnInfos().get(j)).
+                                        setStyle(htmlDataTable.getRowGroupStyle());
+                                ((ColumnInfo)
+                                    ((RowInfo)
+                                        tableContext.getRowInfos().get(currentRowInfoIndex)).
+                                        getColumnInfos().get(j)).
+                                        setStyleClass(htmlDataTable.getRowGroupStyleClass());
+                        }
+                    }
+
+            htmlDataTable.setRowIndex(-1);
+        }
+
+
     /**
      * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
      */
@@ -139,14 +342,14 @@
     }
 
     protected void renderRowStart(FacesContext facesContext,
-                    ResponseWriter writer, UIData uiData, Iterator rowStyleClassIterator)
+                                  ResponseWriter writer, UIData uiData, Iterator rowStyleClassIterator)
                     throws IOException
     {
         super.renderRowStart(facesContext, writer, uiData, rowStyleClassIterator);
 
         // get event handlers from component
         HtmlDataTable table = (HtmlDataTable) uiData;
-        
+
         renderRowAttribute(writer, HTML.ONCLICK_ATTR, table.getRowOnClick());
         renderRowAttribute(writer, HTML.ONDBLCLICK_ATTR, table.getRowOnDblClick());
         renderRowAttribute(writer, HTML.ONKEYDOWN_ATTR, table.getRowOnKeyDown());
@@ -158,7 +361,7 @@
         renderRowAttribute(writer, HTML.ONMOUSEOVER_ATTR, table.getRowOnMouseOver());
         renderRowAttribute(writer, HTML.ONMOUSEUP_ATTR, table.getRowOnMouseUp());
     }
-    
+
     /**
      * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderRowStyle(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIData, java.util.Iterator)
      */
@@ -195,9 +398,9 @@
         writer.writeAttribute(HTML.STYLE_ATTR, rowStyle, null);
       }
     }
-    
+
     protected void renderRowAttribute(ResponseWriter writer,
-                    String htmlAttribute, Object value) throws IOException
+                                      String htmlAttribute, Object value) throws IOException
     {
         if (value != null)
         {
@@ -234,8 +437,8 @@
      * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#encodeColumnChild(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIData, javax.faces.component.UIComponent, java.util.Iterator)
      */
     protected void encodeColumnChild(FacesContext facesContext,
-                    ResponseWriter writer, UIData uiData,
-                    UIComponent component, Iterator columnStyleIterator)
+                                     ResponseWriter writer, UIData uiData,
+                                     UIComponent component, Iterator columnStyleIterator)
                     throws IOException
     {
         super.encodeColumnChild(facesContext, writer, uiData, component,
@@ -257,11 +460,68 @@
      * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderColumnBody(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIData, javax.faces.component.UIComponent, java.util.Iterator)
      */
     protected void renderColumnBody(FacesContext facesContext,
-                    ResponseWriter writer, UIData uiData,
-                    UIComponent component, Iterator columnStyleIterator)
+                                    ResponseWriter writer, UIData uiData,
+                                    UIComponent component, Iterator columnStyleIterator)
                     throws IOException
     {
-        if (component instanceof HtmlColumn)
+        if (isGroupedTable(uiData)){
+
+            HtmlDataTable htmlDataTable = (HtmlDataTable) uiData;
+            List tableChildren = htmlDataTable.getChildren();
+
+            int first = htmlDataTable.getFirst();
+            int rowInfoIndex= htmlDataTable.getRowIndex()-first;
+            int columnInfoIndex = tableChildren.indexOf(component);
+
+            RowInfo rowInfo = (RowInfo) htmlDataTable.getTableContext().getRowInfos().get(rowInfoIndex);
+            ColumnInfo columnInfo= (ColumnInfo) rowInfo.getColumnInfos().get(columnInfoIndex);
+
+            if(!columnInfo.isRendered()) return;
+
+            writer.startElement(HTML.TD_ELEM, uiData);
+            String styleClass = ((HtmlColumn) component).getStyleClass();
+            if(columnInfo.getStyleClass()!= null)
+            {
+                styleClass = columnInfo.getStyleClass();
+            }
+
+            if(columnStyleIterator.hasNext())
+            {
+              if (styleClass == null)
+              {
+                  styleClass = (String) columnStyleIterator.next();
+              }
+              else
+              {
+                // skip the column style class
+                columnStyleIterator.next();
+              }
+            }
+            if (styleClass != null)
+            {
+                writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
+            }
+
+            if (columnInfo.getStyle() != null)
+            {
+                writer.writeAttribute(HTML.STYLE_ATTR, columnInfo.getStyle(), null);
+            }
+
+            if (columnInfo.getRowSpan() > 1)
+            {
+                writer.writeAttribute("rowspan", new Integer(columnInfo.getRowSpan()).toString(), null);
+                if (columnInfo.getStyle() == null)
+                {
+                    writer.writeAttribute(HTML.STYLE_ATTR, "vertical-align:top", null);
+                }
+            }
+
+            renderHtmlColumnAttributes(writer, component, null);
+
+            RendererUtils.renderChild(facesContext, component);
+            writer.endElement(HTML.TD_ELEM);
+        }
+        else if (component instanceof HtmlColumn)
         {
             writer.startElement(HTML.TD_ELEM, uiData);
             String styleClass = ((HtmlColumn) component).getStyleClass();
@@ -346,8 +606,8 @@
      * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderColumnHeaderCell(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIComponent, javax.faces.component.UIComponent, java.lang.String, int)
      */
     protected void renderColumnHeaderCell(FacesContext facesContext,
-                    ResponseWriter writer, UIComponent uiComponent,
-                    UIComponent facet, String headerStyleClass, int colspan)
+                                          ResponseWriter writer, UIComponent uiComponent,
+                                          UIComponent facet, String headerStyleClass, int colspan)
                     throws IOException
     {
         if (uiComponent instanceof HtmlColumn)
@@ -386,8 +646,8 @@
      * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderColumnFooterCell(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIComponent, javax.faces.component.UIComponent, java.lang.String, int)
      */
     protected void renderColumnFooterCell(FacesContext facesContext,
-                    ResponseWriter writer, UIComponent uiComponent,
-                    UIComponent facet, String footerStyleClass, int colspan)
+                                          ResponseWriter writer, UIComponent uiComponent,
+                                          UIComponent facet, String footerStyleClass, int colspan)
                     throws IOException
     {
         if (uiComponent instanceof HtmlColumn)
@@ -423,7 +683,7 @@
     }
 
     protected void renderHtmlColumnAttributes(ResponseWriter writer,
-                    UIComponent uiComponent, String prefix) throws IOException
+                                              UIComponent uiComponent, String prefix) throws IOException
     {
         String[] attrs = HTML.COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_STYLE;
         for (int i = 0, size = attrs.length; i < size; i++)
@@ -484,46 +744,46 @@
      * Renders the column footer.
      * Rendering will be supressed if all of the facets have rendered="false"   
      */
-	protected void renderColumnFooterRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, String footerStyleClass) throws IOException
-	{
+    protected void renderColumnFooterRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, String footerStyleClass) throws IOException
+    {
         if (determineRenderFacet(component, false))
         {
-        	super.renderColumnFooterRow(facesContext, writer, component, footerStyleClass);
+            super.renderColumnFooterRow(facesContext, writer, component, footerStyleClass);
         }
-	}
+    }
 
     /**
      * Renders the column header.
      * Rendering will be supressed if all of the facets have rendered="false"   
      */
-	protected void renderColumnHeaderRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, String headerStyleClass) throws IOException
-	{
+    protected void renderColumnHeaderRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, String headerStyleClass) throws IOException
+    {
         if (determineRenderFacet(component, true))
         {
-        	super.renderColumnHeaderRow(facesContext, writer, component, headerStyleClass);
+            super.renderColumnHeaderRow(facesContext, writer, component, headerStyleClass);
         }
-	}
+    }
 
-	/**
-	 * determine if the header or footer should be rendered.
-	 */
-	protected boolean determineRenderFacet(UIComponent component, boolean header)
-	{
-		for (Iterator it = getChildren(component).iterator(); it.hasNext();)
+    /**
+     * determine if the header or footer should be rendered.
+     */
+    protected boolean determineRenderFacet(UIComponent component, boolean header)
+    {
+        for (Iterator it = getChildren(component).iterator(); it.hasNext();)
         {
             UIComponent uiComponent = (UIComponent) it.next();
             if(uiComponent.isRendered() && determineChildColSpan(uiComponent) > 0)
             {
                 UIComponent facet = header ? (UIComponent) uiComponent.getFacets().get(HEADER_FACET_NAME)
                         : (UIComponent) uiComponent.getFacets().get(FOOTER_FACET_NAME);
-                
+
                 if (facet != null && facet.isRendered())
                 {
-               		return true;
+                       return true;
                 }
             }
         }
-		
-		return false;
-	}
+
+        return false;
+    }
 }

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/ColumnInfo.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/ColumnInfo.java?rev=395050&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/ColumnInfo.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/ColumnInfo.java Tue Apr 18 14:39:26 2006
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.myfaces.renderkit.html.util;
+
+/**
+ * @author Ernst Fastl
+ */
+public class ColumnInfo
+{
+    private boolean _rendered = true;
+    private int _rowSpan=0;
+    private String _style;
+    private String _styleClass;
+
+    public boolean isRendered()
+    {
+        return _rendered;
+    }
+
+    public void setRendered(boolean rendered)
+    {
+        this._rendered = rendered;
+    }
+
+    public int getRowSpan()
+    {
+        return _rowSpan;
+    }
+
+    public void setRowSpan(int rowSpan)
+    {
+        this._rowSpan = rowSpan;
+    }
+
+    public String getStyle()
+    {
+        return _style;
+    }
+
+    public void setStyle(String style)
+    {
+        this._style = style;
+    }
+
+    public String getStyleClass()
+    {
+        return _styleClass;
+    }
+
+    public void setStyleClass(String styleClass)
+    {
+        this._styleClass = styleClass;
+    }
+}

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/RowInfo.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/RowInfo.java?rev=395050&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/RowInfo.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/RowInfo.java Tue Apr 18 14:39:26 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.myfaces.renderkit.html.util;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author Ernst Fastl
+ */
+public class RowInfo
+{
+    private List _columnInfos;
+
+    public List getColumnInfos()
+    {
+        if ( _columnInfos == null )
+        {
+            _columnInfos = new ArrayList();
+        }
+        return _columnInfos;
+    }
+}

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/TableContext.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/TableContext.java?rev=395050&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/TableContext.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/TableContext.java Tue Apr 18 14:39:26 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.myfaces.renderkit.html.util;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author Ernst Fastl
+ */
+public class TableContext
+{
+    private List _rowInfos;
+
+    public List getRowInfos()
+    {
+        if ( _rowInfos == null )
+        {
+            _rowInfos = new ArrayList();
+        }
+        return _rowInfos;
+    }
+}

Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/taglib/html/ext/HtmlDataTableTag.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/taglib/html/ext/HtmlDataTableTag.java?rev=395050&r1=395049&r2=395050&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/taglib/html/ext/HtmlDataTableTag.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/taglib/html/ext/HtmlDataTableTag.java Tue Apr 18 14:39:26 2006
@@ -68,7 +68,9 @@
     
     private String _rowStyleClass;
     private String _rowStyle;
-    
+    private String _rowGroupStyle;
+    private String _rowGroupStyleClass;
+
     public void release() 
     {
         super.release();
@@ -100,6 +102,8 @@
 
         _rowStyleClass = null;
         _rowStyle = null;
+        _rowGroupStyle = null;
+        _rowGroupStyleClass = null;
     }
 
     protected void setProperties(UIComponent component)
@@ -133,6 +137,8 @@
         
         setStringProperty(component, JSFAttr.ROW_STYLECLASS_ATTR, _rowStyleClass);
         setStringProperty(component, JSFAttr.ROW_STYLE_ATTR, _rowStyle);
+        setStringProperty(component, "rowGroupStyle", _rowGroupStyle);
+        setStringProperty(component, "rowGroupStyleClasses", _rowGroupStyleClass);
     }
 
     public void setPreserveDataModel(String preserveDataModel)
@@ -260,8 +266,17 @@
       _rowStyle = rowStyle;
     }
 
-		
-	public String getVarDetailToggler() {
+    public void setRowGroupStyle(String rowGroupStyle)
+    {
+        _rowGroupStyle = rowGroupStyle;
+    }
+
+    public void setRowGroupStyleClass(String rowGroupStyleClass)
+    {
+        _rowGroupStyleClass = rowGroupStyleClass;
+    }
+
+    public String getVarDetailToggler() {
 		return _varDetailToggler;
 	}
 

Modified: myfaces/tomahawk/trunk/core/src/main/tld/entities/extended_data_table_attributes.xml
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/tld/entities/extended_data_table_attributes.xml?rev=395050&r1=395049&r2=395050&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/tld/entities/extended_data_table_attributes.xml (original)
+++ myfaces/tomahawk/trunk/core/src/main/tld/entities/extended_data_table_attributes.xml Tue Apr 18 14:39:26 2006
@@ -223,7 +223,19 @@
             <required>false</required>
             <rtexprvalue>false</rtexprvalue>
             <description>Corresponds to the HTML style attribute for the row tr tag.</description>
-        </attribute>        
+        </attribute>
+        <attribute>
+            <name>rowGroupStyle</name>
+            <required>false</required>
+            <rtexprvalue>false</rtexprvalue>
+            <description>Corresponds to the HTML style attribute for grouped rows.</description>
+        </attribute>
+        <attribute>
+            <name>rowGroupStyleClass</name>
+            <required>false</required>
+            <rtexprvalue>false</rtexprvalue>
+            <description>StyleClass for grouped rows.</description>
+        </attribute>
         <attribute>
          <name>varDetailToggler</name>
          <required>false</required>

Modified: myfaces/tomahawk/trunk/examples/simple/src/main/webapp/home.jsp
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/examples/simple/src/main/webapp/home.jsp?rev=395050&r1=395049&r2=395050&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/examples/simple/src/main/webapp/home.jsp (original)
+++ myfaces/tomahawk/trunk/examples/simple/src/main/webapp/home.jsp Tue Apr 18 14:39:26 2006
@@ -38,7 +38,7 @@
                     <h:outputLink value="openDataTable.jsf" ><f:verbatim>Paged and Sortable (dynamic number of columns; mouseover)</f:verbatim></h:outputLink>
                     <h:outputLink value="crossDataTable.jsf" ><f:verbatim>Dynamic number of columns, add a column</f:verbatim></h:outputLink>
                     <h:outputLink value="optDataTable.jsf" ><f:verbatim>Optional Header/Footer</f:verbatim></h:outputLink>
-                    <h:outputLink value="simpleGroupBy.jsf" ><f:verbatim>Group by columes</f:verbatim></h:outputLink>
+                    <h:outputLink value="simpleGroupBy.jsf" ><f:verbatim>Group by columns</f:verbatim></h:outputLink>
                 </h:panelGrid>
                 <h:outputLink value="selectbox.jsf" ><f:verbatim>Select boxes</f:verbatim></h:outputLink>
                 <h:outputLink value="fileupload.jsf" ><f:verbatim>File upload</f:verbatim></h:outputLink>

Added: myfaces/tomahawk/trunk/examples/simple/src/main/webapp/simpleGroupBy.jsp
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/examples/simple/src/main/webapp/simpleGroupBy.jsp?rev=395050&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/examples/simple/src/main/webapp/simpleGroupBy.jsp (added)
+++ myfaces/tomahawk/trunk/examples/simple/src/main/webapp/simpleGroupBy.jsp Tue Apr 18 14:39:26 2006
@@ -0,0 +1,67 @@
+<%@ page session="false" contentType="text/html;charset=utf-8"%>
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
+<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
+<html>
+
+<!--
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//-->
+
+<%@include file="inc/head.inc" %>
+
+<body>
+
+<f:view>
+
+    <f:loadBundle basename="org.apache.myfaces.examples.resource.example_messages" var="example_messages"/>
+
+        <t:dataTable id="data"
+                style="border-collapse:collapse;"
+                styleClass="standardTable"
+                headerClass="standardTable_Header"
+                footerClass="standardTable_Header"
+                rowClasses="standardTable_Row1,standardTable_Row2"
+
+                var="demo"
+                value="#{simpleGroupBy.demoList}"
+                preserveDataModel="true"
+                rowGroupStyle="border-bottom:blue;border-bottom-style:solid;border-bottom-width:2px;vertical-align:top">
+           <t:column groupBy="true">
+               <f:facet name="header">
+                  <h:outputText value="Groups" />
+               </f:facet>
+                    <h:outputText value="#{demo.value1}" />
+           </t:column>
+
+           <t:column>
+               <f:facet name="header">
+                  <h:outputText value="Items" />
+               </f:facet>
+               <h:outputText value="#{demo.value2}" />
+           </t:column>
+
+
+        </t:dataTable>
+
+</f:view>
+
+<%@include file="inc/page_footer.jsp" %>
+
+</body>
+
+</html>