[richfaces-svn-commits] JBoss Rich Faces SVN: r4931 - in branches/3.1.x: docs/faq/en and 18 other directories.

richfaces-svn-commits at lists.jboss.org richfaces-svn-commits at lists.jboss.org
Wed Dec 19 13:12:29 EST 2007


Author: maksimkaszynski
Date: 2007-12-19 13:12:29 -0500 (Wed, 19 Dec 2007)
New Revision: 4931

Added:
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/AbstractSortListener.java
Modified:
   branches/3.1.x/cdk/maven-javascript-plugin/
   branches/3.1.x/docs/faq/en/
   branches/3.1.x/extensions/portletbridge/portletbridge-impl/
   branches/3.1.x/framework/api/src/main/java/org/richfaces/event/sort/SortEvent.java
   branches/3.1.x/samples/contextMenuDemo/src/main/webapp/pages/index.jsp
   branches/3.1.x/ui/scrollableDataTable/generatescript.xml
   branches/3.1.x/ui/scrollableDataTable/src/main/config/component/scrollable-data-table.xml
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/component/UIScrollableDataTable.java
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/convert/selection/ClientSelectionConverter.java
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/MultiColumnSortListener.java
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/SingleColumnSortListener.java
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/model/internal/ComponentSortableDataModel.java
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/model/selection/ClientSelection.java
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/ScrollableDataTableBaseRenderer.java
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/ScrollableDataTableRendererState.java
   branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/SelectionRendererContributor.java
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/common/box/ScrollableBox.js
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/common/utils/Utils.js
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/DataModel.js
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/Grid.js
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/GridBody.js
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/GridHeader.js
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/ScrollableGrid.js
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/Selection.js
   branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/layouts/LayoutManager.js
   branches/3.1.x/ui/scrollableDataTable/src/main/resources/org/richfaces/renderkit/html/css/scrollable-data-table.xcss
   branches/3.1.x/ui/scrollableDataTable/src/main/templates/org/richfaces/scrollable-data-table-footer-cell.jspx
   branches/3.1.x/ui/scrollableDataTable/src/main/templates/org/richfaces/scrollable-data-table.jspx
   branches/3.1.x/ui/scrollableDataTable/src/test/java/org/richfaces/renderkit/html/ScrollableDataTableRendererTest.java
Log:
merged scrollable-data-table into 3/1/x branch


Property changes on: branches/3.1.x/cdk/maven-javascript-plugin
___________________________________________________________________
Name: svn:ignore
   + .classpath
.project
.settings
target



Property changes on: branches/3.1.x/docs/faq/en
___________________________________________________________________
Name: svn:ignore
   - target

   + target
.project
.settings



Property changes on: branches/3.1.x/extensions/portletbridge/portletbridge-impl
___________________________________________________________________
Name: svn:ignore
   + .classpath
.project
.settings
target


Modified: branches/3.1.x/framework/api/src/main/java/org/richfaces/event/sort/SortEvent.java
===================================================================
--- branches/3.1.x/framework/api/src/main/java/org/richfaces/event/sort/SortEvent.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/framework/api/src/main/java/org/richfaces/event/sort/SortEvent.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -13,7 +13,6 @@
 import javax.faces.component.UIComponent;
 import javax.faces.event.FacesListener;
 
-import org.richfaces.event.AttributedEvent;
 import org.richfaces.event.ScrollableGridViewEvent;
 
 /**
@@ -27,6 +26,8 @@
 	
 	private int sortColumn;
 	
+	private Boolean suggestedOrder = null;
+	
 	public SortEvent(UIComponent component, int sortColumn, int rows, int first) {
 		
 		super(component, rows, first);
@@ -59,4 +60,12 @@
 	public void setSortColumn(int sortColumn) {
 		this.sortColumn = sortColumn;
 	}
+
+	public Boolean getSuggestedOrder() {
+		return suggestedOrder;
+	}
+
+	public void setProposedOrder(Boolean proposedOrder) {
+		this.suggestedOrder = proposedOrder;
+	}
 }

Modified: branches/3.1.x/samples/contextMenuDemo/src/main/webapp/pages/index.jsp
===================================================================
--- branches/3.1.x/samples/contextMenuDemo/src/main/webapp/pages/index.jsp	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/samples/contextMenuDemo/src/main/webapp/pages/index.jsp	2007-12-19 18:12:29 UTC (rev 4931)
@@ -1,3 +1,5 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<%@ page contentType="application/xhtml+xml; charset=ISO-8859-1" %>
 <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
 <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
 <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
@@ -10,8 +12,7 @@
 	prefix="cc"%>
 <%@ taglib uri="http://labs.jboss.com/jbossrichfaces/ui/menu-components"
 	prefix="mc"%>
-<html>
-<head>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
 <title></title>
 <style>
 <!--
@@ -36,14 +37,37 @@
         			<h:commandLink action="#{skinBean.change}" value="Set Skin"/>
 				<h:outputText value=" Current skin: #{skinBean.skin}" />
 			</h:form>
+
+
 	<div id="sgs" style="height: 50px"><a4j:outputPanel
 		ajaxRendered="true">
-		<h:messages></h:messages>
+		<h:outputText value="#{param['param']}"></h:outputText>
 	</a4j:outputPanel></div>
 	<h:form id="f">
-		<cm:contextMenu submitMode="server" id="m" attached="false">
+
+		<div style="border: dotted">div 
+		<cm:contextMenu
+			id="ccContextMenuID" submitMode="ajax" attached="true" >
+			<mc:menuItem icon="/icons/ico1.gif" value="tab1">
+				<f:param name="cmdParam" value="menu" />
+			</mc:menuItem>
+			<mc:menuSeparator />
+			<mc:menuItem icon="/icons/ico1.gif" value="a" reRender="cmInfoID">
+				<f:param name="cmdParam" value="a" />
+			</mc:menuItem>
+			<mc:menuItem id="zz" icon="/icons/ico1.gif" value="b" reRender="cmInfoID">
+				<cc:componentControl event="onmouseover" for="ccContextMenuID"
+					attachTo="zz"
+					disableDefault="true" operation="hide" />
+			</mc:menuItem>
+			<mc:menuItem icon="/icons/ico1.gif" value="c" reRender="cmInfoID">
+				<f:param name="cmdParam" value="c" />
+			</mc:menuItem>
+		</cm:contextMenu></div>
+
+		<cm:contextMenu submitMode="ajax" id="m" attached="false">
 			<mc:menuItem action="#{bean.edit}"
-				value="Edit package : {param}" submitMode="ajax"
+				value="Edit package : {param}"
 				actionListener="#{bean.actionListener}" icon="/icons/ico1.gif">
 				<a4j:actionparam assignTo="#{bean.param}" name="param"
 					value="{param}"></a4j:actionparam>
@@ -52,7 +76,7 @@
 			<mc:menuSeparator id="menuSeparator11" />
 			
 			<mc:menuItem action="#{bean.delete}"
-				value="Delete package {param}" submitMode="ajax"
+				value="Delete package {param}" 
 				actionListener="#{bean.actionListener}" icon="/icons/ico2.gif">
 				<a4j:actionparam assignTo="#{bean.param}" name="param"
 					value="{param}"></a4j:actionparam>

Modified: branches/3.1.x/ui/scrollableDataTable/generatescript.xml
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/generatescript.xml	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/generatescript.xml	2007-12-19 18:12:29 UTC (rev 4931)
@@ -27,7 +27,6 @@
 						<file name="${resources-dir}/ClientUI/common/utils/Validators.js"/>
 						<file name="${resources-dir}/ClientUI/common/box/Box.js"/>
 						<file name="${resources-dir}/ClientUI/common/box/InlineBox.js"/>
-						<file name="${resources-dir}/ClientUI/common/utils/CustomEvent.js"/>
 						<file name="${resources-dir}/ClientUI/common/box/ScrollableBox.js"/>
 						<file name="${resources-dir}/ClientUI/controls/grid/DataModel.js"/>
 						<file name="${resources-dir}/ClientUI/controls/grid/ArrayDataModel.js"/>
@@ -61,7 +60,6 @@
 					<file name="/ClientUI/common/utils/Validators.js"/>
 					<file name="/ClientUI/common/box/Box.js"/>
 					<file name="/ClientUI/common/box/InlineBox.js"/>
-					<file name="/ClientUI/common/utils/CustomEvent.js"/>
 					<file name="/ClientUI/common/box/ScrollableBox.js"/>
 					<file name="/ClientUI/controls/grid/DataModel.js"/>
 					<file name="/ClientUI/controls/grid/ArrayDataModel.js"/>

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/config/component/scrollable-data-table.xml
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/config/component/scrollable-data-table.xml	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/config/component/scrollable-data-table.xml	2007-12-19 18:12:29 UTC (rev 4931)
@@ -60,7 +60,7 @@
 
 		<property>
 			<name>componentState</name>
-			<classname>java.lang.String</classname>
+			<classname>org.ajax4jsf.model.DataComponentState</classname>
 			<description>It defines EL-binding  for a component state for saving or redefinition</description>
 		</property>
 		
@@ -185,7 +185,7 @@
 		
 		<property>
 			<name>rowKey</name>
-			<classname>java.lang.String</classname>
+			<classname>java.lang.Object</classname>
 			<description>The attribute is a representation of an identifier for a specific data row</description>
 		</property>
 		
@@ -234,7 +234,7 @@
 
 		<property>
 			<name>ajaxKeys</name>
-			<classname>java.lang.String</classname>
+			<classname>java.util.Set</classname>
 			<description>This attribute defines rows that are updated after an AJAX request</description>
 		</property>
 

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/component/UIScrollableDataTable.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/component/UIScrollableDataTable.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/component/UIScrollableDataTable.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -129,6 +129,7 @@
 		if (log.isTraceEnabled()) {
 			log.trace("UIScrollableDataTable.processDecodes(faces)");
 		}
+		checkRange();
 		super.processDecodes(faces);
 	}
 	
@@ -158,6 +159,7 @@
 		}
 		
 		useSavedRanges = false;
+		checkRange();
 		super.encodeBegin(context);
 	}
 	
@@ -370,6 +372,8 @@
 	public abstract String getSortMode();
 	public abstract void setSortMode(String mode);
 	
+	public abstract Object getActiveRowKey();
+	public abstract void setActiveRowKey(Object activeRowKey);
 	
 	/* (non-Javadoc)
 	 * @see org.ajax4jsf.component.UIDataAdaptor#setRowIndex(int)
@@ -380,4 +384,16 @@
 		}
 		//super.setRowIndex(index);
 	}
+
+	public void resetReqRowsCount() {
+		this.reqRowsCount = -1;
+	}
+	
+	private void checkRange() {
+		int rows = getRows();
+		if (getRowCount() <= getFirst() + getRows()) {
+			setFirst(0);
+			setScrollPos("0,0," + rows);
+		}
+	}
 }

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/convert/selection/ClientSelectionConverter.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/convert/selection/ClientSelectionConverter.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/convert/selection/ClientSelectionConverter.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -62,13 +62,18 @@
 		}
 		
 		final ClientSelection clientSelection = new ClientSelection();
+		if(stringSelection == null || stringSelection.length() == 0) {
+			return clientSelection;
+		}
 		
 		String [] selections = stringSelection.split(";");
 		int length = selections.length;
-		if (selections[length-1].length() == 1) {
+		if (selections[length-1].charAt(0) > '9') {
 			clientSelection.setSelectionFlag(selections[length-1]);
 			length--;
 		}
+		clientSelection.setActiveRowIndex(Integer.parseInt(selections[length-1]));
+		length--;
 		for (int i = 0; i < length; i++) {
 			
 			String range = selections[i];

Added: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/AbstractSortListener.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/AbstractSortListener.java	                        (rev 0)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/AbstractSortListener.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -0,0 +1,46 @@
+/**
+ * License Agreement.
+ *
+ *  JBoss RichFaces 3.0 - Ajax4jsf Component Library
+ *
+ * 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.event.sort;
+
+/**
+ * @author Maksim Kaszynski
+ *
+ */
+public abstract class AbstractSortListener implements SortListener {
+	
+	/**
+	 * Encapsulate sorting toggle here
+	 * @param current
+	 * @param suggested
+	 * @return
+	 */
+	protected Boolean nextSortOrder(Boolean current, Boolean suggested) {
+		
+		if (suggested != null) {
+			return suggested;
+		} else {
+			return (current == null) ? Boolean.TRUE : (current.booleanValue() ? Boolean.FALSE : Boolean.TRUE);
+		}
+		
+	}
+
+}

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/MultiColumnSortListener.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/MultiColumnSortListener.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/MultiColumnSortListener.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -21,7 +21,7 @@
  * @author Maksim Kaszynski
  *
  */
-public class MultiColumnSortListener implements SortListener {
+public class MultiColumnSortListener extends AbstractSortListener {
 
 	public static final MultiColumnSortListener INSTANCE = new MultiColumnSortListener();
 	
@@ -51,11 +51,13 @@
 			
 		}
 		
+		Boolean suggested = e.getSuggestedOrder();
+		
 		SortField[] fields = sortOrder.getFields();
 		
 		if (fields == null) {
 			//If no sorting was applied at all, set sorting to current
-			fields = new SortField[] {new SortField(name, columnIndex, Boolean.TRUE)};
+			fields = new SortField[] {new SortField(name, columnIndex, nextSortOrder(null, suggested))};
 		} else {
 			
 			List newFields = new LinkedList(Arrays.asList(fields));
@@ -69,16 +71,16 @@
 								name.equals(sortField.getName()))) {
 					
 					Boolean asc = sortField.getAscending();
-					asc = Boolean.TRUE.equals(asc) ? Boolean.FALSE : Boolean.TRUE;
 					
-					newField = new SortField(name, columnIndex, asc);
+					newField = new SortField(name, columnIndex, nextSortOrder(asc, suggested));
 					iterator.remove();
 					
 				}				
 			}
 			
 			if (newField == null) {
-				newField = new SortField(name, columnIndex, Boolean.TRUE);
+				
+				newField = new SortField(name, columnIndex, nextSortOrder(null, suggested));
 			}
 			
 			newFields.add(newField);

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/SingleColumnSortListener.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/SingleColumnSortListener.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/event/sort/SingleColumnSortListener.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -15,7 +15,7 @@
  * @author Maksim Kaszynski
  *
  */
-public class SingleColumnSortListener implements SortListener {
+public class SingleColumnSortListener extends AbstractSortListener {
 
 	public static final SingleColumnSortListener INSTANCE = new SingleColumnSortListener();
 	
@@ -46,7 +46,7 @@
 		
 		SortField[] fields = sortOrder.getFields();
 		
-		SortField newField = new SortField(name, columnIndex, Boolean.TRUE);
+		SortField newField = new SortField(name, columnIndex, nextSortOrder(null, e.getSuggestedOrder()));
 		
 		if (fields != null) {
 			for (int i = 0; i < fields.length; i++) {
@@ -56,8 +56,7 @@
 								name != null && 
 								name.equals(sortField.getName()))) {
 					
-					Boolean asc = sortField.getAscending();
-					asc = Boolean.TRUE.equals(asc) ? Boolean.FALSE : Boolean.TRUE;
+					Boolean asc = nextSortOrder(sortField.getAscending(), e.getSuggestedOrder()) ;
 					
 					newField = new SortField(name, columnIndex, asc);
 					break;

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/model/internal/ComponentSortableDataModel.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/model/internal/ComponentSortableDataModel.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/model/internal/ComponentSortableDataModel.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -27,6 +27,7 @@
 import java.util.List;
 
 import javax.faces.context.FacesContext;
+import javax.faces.model.DataModel;
 
 import org.richfaces.model.ScrollableTableDataModel;
 import org.richfaces.model.SortField;
@@ -65,6 +66,7 @@
 	
 	
 	private List wrappedList;
+	DataModel model;
 	private String var;
 	
 	public ComponentSortableDataModel(String var, Object value) {
@@ -76,12 +78,7 @@
 	 * @see org.richfaces.model.ScrollableTableDataModel#loadData(int, int, org.richfaces.model.SortOrder)
 	 */
 	public List loadData(int startRow, int endRow, SortOrder sortOrder) {
-		
-		
-		List sortedCollection = sortOrder != null ?
-			prepareCollection(FacesContext.getCurrentInstance(), new ArrayList(wrappedList), sortOrder) : wrappedList;
-		
-			
+		List list = null;
 		int rc = getRowCount();
 		if (startRow < 0) {
 			startRow = 0;
@@ -90,24 +87,51 @@
 		if (endRow > rc) {
 			endRow = rc;
 		}
-			
-		return sortedCollection.subList(startRow, endRow);
+		if (sortOrder == null) {
+			if(model != null) {
+				list = new ArrayList(rc);
+				for (int i = startRow; i < endRow; i++) {
+					model.setRowIndex(i);
+					list.add(model.getRowData());
+				}
+			} else {
+				list = wrappedList.subList(startRow, endRow);
+			}
+		} else {
+			if(model != null) {
+				list = new ArrayList(rc);
+				for (int i = 0; i < rc; i++) {
+					model.setRowIndex(i);
+					list.add(model.getRowData());
+				}
+			} else {
+				list = new ArrayList(wrappedList);
+			}
+			list = prepareCollection(FacesContext.getCurrentInstance(), list, sortOrder).subList(startRow, endRow);
+		}
+		return list;
 	}
 
 	/* (non-Javadoc)
 	 * @see javax.faces.model.DataModel#getRowCount()
 	 */
 	public int getRowCount() {
-		// TODO Auto-generated method stub
-		return wrappedList.size();
+		if (model != null) {
+			return model.getRowCount();
+		} else {
+			return wrappedList.size();
+		}
 	}
 
 	/* (non-Javadoc)
 	 * @see javax.faces.model.DataModel#getWrappedData()
 	 */
 	public Object getWrappedData() {
-		// TODO Auto-generated method stub
-		return wrappedList;
+		if (model != null) {
+			return model;
+		} else {
+			return wrappedList;
+		}
 	}
 
 	/* (non-Javadoc)
@@ -132,6 +156,8 @@
 			
 			wrappedList = new ArrayList((Collection) value);
 			
+		} else if (value instanceof DataModel) {
+			model = (DataModel)value;
 		} else {
 			wrappedList = new ArrayList(1);
 			wrappedList.add(value);

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/model/selection/ClientSelection.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/model/selection/ClientSelection.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/model/selection/ClientSelection.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -24,6 +24,8 @@
 	
 	private String selectionFlag;
 	
+	private int activeRowIndex = -1;
+	
 	private List ranges = new ArrayList();
 	
 	public ClientSelection() {
@@ -57,8 +59,8 @@
 		int s = ranges.size();
 		
 		int insertPosition = 0;
-		
-		for(int i = 0; i < s && insertPosition >= 0 ; i++) {
+		int i;
+		for(i = 0; i < s && insertPosition >= 0 ; i++) {
 			
 			firstRange = (SelectionRange) ranges.get(i);
 			
@@ -86,6 +88,8 @@
 			
 			} else if (firstRange.getStartIndex() > j) {
 				insertPosition = i;
+			} else if (insertPosition == 0 && i == s - 1) {
+				insertPosition = s;				
 			}
 			
 		}
@@ -128,4 +132,14 @@
 			reset = true;
 		}
 	}
+
+
+	public int getActiveRowIndex() {
+		return activeRowIndex;
+	}
+
+
+	public void setActiveRowIndex(int activeRowIndex) {
+		this.activeRowIndex = activeRowIndex;
+	}
 }

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/ScrollableDataTableBaseRenderer.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/ScrollableDataTableBaseRenderer.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/ScrollableDataTableBaseRenderer.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -41,18 +41,18 @@
 
 public abstract class ScrollableDataTableBaseRenderer extends CompositeRenderer {
 	
-	public final String PARTIAL_UPDATE= "partialUpdate";
-	public final String UPDATE_HEADER = "updateHeader";
+	public static final String PARTIAL_UPDATE = "partialUpdate";
+	public static final String UPDATE_HEADER = "updateHeader";
 	
-	public final String  FOOTER_PART = "footer";
+	public static final String  FOOTER_PART = "footer";
 	
-	public final String  HEADER_PART = "header";
+	public static final String  HEADER_PART = "header";
 	
-	private final String COLUMN_FROZEN_TYPE = "frozen"; 
+	private static final String COLUMN_FROZEN_TYPE = "frozen"; 
 	
-	private final String COLUMN_NORMAL_TYPE = "normal";
+	private static final String COLUMN_NORMAL_TYPE = "normal";
 	
-	private final String PERSENTAGE_SUPPORT_ERROR_MSG = "columnsWidth property: Percentage values are not supported";
+	private static final String PERSENTAGE_SUPPORT_ERROR_MSG = "columnsWidth property: Percentage values are not supported";
 	
 	private RendererBase cellTemplate = null;
 	
@@ -289,7 +289,10 @@
 				ColumnWalker.iterateOverColumns(context, grid, cellRenderer, writer, state);
 				if(!state.isFrozenPart()){
 					writer.startElement("td", grid);
-					getUtils().writeAttribute(writer, "class","dr-sdt-bc rich-sdt-row " + state.getColumnClass(state.getCellIndex()));
+					getUtils().writeAttribute(writer, "class","dr-sdt-bc rich-sdt-column-cell " + state.getColumnClass(state.getCellIndex()));
+					writer.startElement(HTML.DIV_ELEM, grid);
+					getUtils().writeAttribute(writer, "class","dr-sdt-bcbody");
+					writer.endElement(HTML.DIV_ELEM);
 					writer.endElement("td");
 				}
 				writer.endElement(HTML.TR_ELEMENT);
@@ -324,15 +327,14 @@
 			
 			String row_id = null;
 			
+			String baseClientId = grid.getBaseClientId(context);
 			
 			for (Iterator iter = grid.getChildren().iterator(); iter.hasNext(); ) {
 				UIComponent kid = (UIComponent) iter.next();
 				
 				if (kid.isRendered()) {
 					
-					if (kid instanceof Column){
-						String baseClientId = grid.getBaseClientId(context);
-						
+					if (kid instanceof Column){						
 						if(state.isFrozenColumn() && !frozenTRRendered){
 							
 							state.setFrozenPart(true);
@@ -347,19 +349,9 @@
 																							
 						}else if(!state.isFrozenColumn() && !normalTRRendered){
 							
-							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(state.getRowIndex()));
-							addRowJavascriptEvents(writer, grid);
+							writeNormalTr(frozenTRRendered, state, grid, collection,
+									writer, baseClientId);
 							normalTRRendered = true;
-							collection.add(row_id);
 									
 						}
 
@@ -376,17 +368,39 @@
 				}
 			
 			}
-			
-//			if(!state.isFrozenPart()){
-//				writer.startElement("td", grid);
-//				getUtils().writeAttribute(writer, "class","dr-sdt-bc " + state.getColumnClass(state.getCellIndex()));
-//				writer.endElement("td");
-//			}
-
+			if(!normalTRRendered){
+				writeNormalTr(frozenTRRendered, state, grid, collection,
+						writer, baseClientId);				
+			}
+			writer.startElement("td", grid);
+			getUtils().writeAttribute(writer, "class","dr-sdt-bc rich-sdt-column-cell " + state.getColumnClass(state.getCellIndex()));
+			writer.startElement(HTML.DIV_ELEM, grid);
+			getUtils().writeAttribute(writer, "class","dr-sdt-bcbody");
+			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 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(state.getRowIndex()));
+			addRowJavascriptEvents(writer, grid);
+			collection.add(row_id);
+		}
 	};
 
 	// temporary solution RF-957
@@ -574,21 +588,40 @@
 			Map parameters = externalContext.getRequestParameterMap();
 			
 			String s_id = clientId + ":si";
+			grid.resetReqRowsCount();
 			if(parameters.containsKey(s_id)){
 				String options = (String)parameters.get(s_id);
 				grid.setScrollPos(options);
+				if(options.length() > 0){
+					grid.setFirst(Integer.parseInt(options.split(",")[1]));
+				}
 			}
 					
 			
 			if(parameters.containsKey(clientId + ":sortColumn") &&
 			   parameters.containsKey(clientId + ":sortStartRow") && 
-			   parameters.containsKey(clientId + ":sortIndex") && 
-			   parameters.containsKey(clientId + ":sortOrder")){ 
+			   parameters.containsKey(clientId + ":sortIndex")){ 
 				
 				int sortColumn = Integer.parseInt((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;
+					}
+				}
+				
+				
 				Column column = (Column)grid.getChildren().get(sortColumn);
 				
 				if(column.isSortable()){
@@ -596,6 +629,8 @@
 					sorted = true;
 					SortEvent sortEvent = new SortEvent(grid,sortColumn, grid.getRows(), sortDataIndex);
 					
+					sortEvent.setProposedOrder(so);
+					
 					sortEvent.setAttribute(ScrollableDataTableUtils.CLIENT_ROW_KEY,sortStartRow);
 					
 					if (ajaxContext.isAjaxRequest()) {
@@ -671,10 +706,29 @@
 		writer.startElement("tbody", grid);
 		
 		grid.walk(context, ajaxRowsRenderer, state);
+		int fakeRowsCount = grid.getRows() - grid.getRowCount();
+		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, new Integer(grid.getRowCount()), null);
+		writer.endElement(HTML.INPUT_ELEM);
+		ajaxContext.addRenderedArea(id);
+
+		renderHiddenScrollInput(context, grid);
+		ajaxContext.addRenderedArea(client_id+":si");
+
 		ScrollableDataTableRendererState.restoreState(context);
 		grid.setRowKey(null);
 		

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/ScrollableDataTableRendererState.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/ScrollableDataTableRendererState.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/ScrollableDataTableRendererState.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -3,7 +3,6 @@
  */
 package org.richfaces.renderkit.html;
 
-import java.io.Serializable;
 import java.util.Collection;
 import java.util.HashSet;
 
@@ -12,11 +11,12 @@
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 
+import org.ajax4jsf.component.UIDataAdaptor;
 import org.ajax4jsf.context.AjaxContext;
 import org.richfaces.component.UIScrollableDataTable;
 
 /**
- * bean to store current {@link com.exadel.vcp.components.datagrid.UIDataGrid } information
+ * bean to store current {@link UIDataAdaptor } information
  * in request map. For nested grids, it support push/pop state saving.
  * In {@link javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)} method
  * must be created instance of this bean , or, if it already exist in request map - push information.
@@ -24,7 +24,7 @@
  * @author shura
  *
  */
-public class ScrollableDataTableRendererState implements Serializable {
+public class ScrollableDataTableRendererState{
 	
 	public static final String DATA_GRID_RENDERER_STATE = ScrollableDataTableRendererState.class.getName();
 	
@@ -78,6 +78,8 @@
 	
 	private Object rowKey;
 
+	private int rows;
+
 	private static final long serialVersionUID = 2129605586975025578L;
 
 	
@@ -146,6 +148,7 @@
 		_cachedClientId = grid.getClientId(context);
 		clientId = _cachedClientId;
 		_previousState = previsiosState;
+		rows = grid.getRows();
 	}
 
 	public  String getCurrentCellId(FacesContext context){
@@ -223,7 +226,7 @@
 	 * @return Returns the rowIndex.
 	 */
 	public int getRowIndex() {
-		if(_grid.getRows() != 0 && _rowIndex >= _grid.getRows()){
+		if(rows != 0 && _rowIndex >= rows){
 			_rowIndex = 0;
 		}	
 		return _rowIndex;

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/SelectionRendererContributor.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/SelectionRendererContributor.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/java/org/richfaces/renderkit/html/SelectionRendererContributor.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -45,7 +45,7 @@
 	public void decode(FacesContext context, UIComponent component,
 			CompositeRenderer compositeRenderer) {
 		
-		UIScrollableDataTable grid = (UIScrollableDataTable) component;
+		final UIScrollableDataTable grid = (UIScrollableDataTable) component;
 		
 		ExternalContext externalContext = context.getExternalContext();
 		Map requestParamMap = externalContext.getRequestParameterMap();
@@ -103,6 +103,9 @@
 							
 							}
 							
+							if(i == clientSelection.getActiveRowIndex()) {
+								grid.setActiveRowKey(rowKey);
+							}
 							state.nextRow();
 							
 						}
@@ -165,8 +168,16 @@
 		ScriptOptions scriptOptions = new ScriptOptions(component);
 		scriptOptions.addOption("selectionInput", getSelectionInputName(
 				context, (UIScrollableDataTable) component));
-		scriptOptions.addOption("selectedClass");
-		scriptOptions.addOption("activeClass");
+		Map attributes = component.getAttributes();
+		Object attribut = attributes.get("selectedClass");
+		if (attribut == null) {
+			attribut = "";
+		}
+		scriptOptions.addOption("selectedClass", attribut);
+		attribut = attributes.get("activeClass");
+		if (attribut == null) {
+			attribut = "";
+		}scriptOptions.addOption("activeClass", attribut);
 		return scriptOptions;
 	}
 	
@@ -194,7 +205,7 @@
 	}
 	
 
-	private void encodeSelection(FacesContext context, UIScrollableDataTable grid) throws IOException {
+	private void encodeSelection(FacesContext context, final UIScrollableDataTable grid) throws IOException {
 		final ScrollableDataTableRendererState state = ScrollableDataTableRendererState.createState(context, grid);
 		
 		state.setRowIndex(ScrollableDataTableUtils.getClientRowIndex(grid));
@@ -217,6 +228,9 @@
 						clientSelection.addIndex(i);
 					}
 					
+					if (rowKey.equals(grid.getActiveRowKey())) {
+						clientSelection.setActiveRowIndex(state.getRowIndex());
+					}
 					
 					state.nextRow();
 					
@@ -245,13 +259,16 @@
 		Converter converter = 
 			application.createConverter(ClientSelection.class);
 		
+		ClientSelection selection = (ClientSelection)grid.getAttributes().get(CLIENT_SELECTION);
 		String string = 
-			converter.getAsString(context, grid, grid.getAttributes().get(CLIENT_SELECTION));
+			converter.getAsString(context, grid, selection);
 		
 		if (string == null) {
 			string = "";
 		}
 		
+		string += selection.getActiveRowIndex();
+		
 		String id = getSelectionInputName(context, grid);
 		
 		

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/common/box/ScrollableBox.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/common/box/ScrollableBox.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/common/box/ScrollableBox.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -6,7 +6,6 @@
 ClientUILib.declarePackage("ClientUI.common.box.ScrollableBox");
 
 ClientUILib.requireClass("ClientUI.common.box.Box");
-ClientUILib.requireClass("ClientUI.common.utils.CustomEvent");
 
 /**
  * This class target to manage scrollable box object.
@@ -18,10 +17,6 @@
 		$super(element, parentElement);
 		this.element.setStyle({overflow: 'auto'});
 		
-		// Create custom event producers
-		this.eventHScroll = new ClientUI.common.utils.CustomEvent('OnHScroll');
-		this.eventVScroll = new ClientUI.common.utils.CustomEvent('OnVScroll');
-
 		this.eventOnScroll = this.scrollContent.bindAsEventListener(this);
 		Event.observe(this.element, 'scroll', this.eventOnScroll);
 	},
@@ -34,13 +29,13 @@
 		// process horizontal scrolling
 		if(this.scrollLeft!==this.getViewportScrollX()) {
 			this.scrollLeft = this.getViewportScrollX();
-			this.eventHScroll.fire(this.getViewportScrollX());
+			this.element.fire("grid:onhcroll", {pos:this.getViewportScrollX()});
 		}
 		
 		// process vertical scrolling		
 		if(this.scrollTop!==this.getViewportScrollY()) {
 			this.scrollTop = this.getViewportScrollY();
-			this.eventVScroll.fire(this.getViewportScrollY());
+			this.element.fire("grid:onvcroll", {pos:this.getViewportScrollY()});
 		}
 	},
 	updateLayout: function($super) {
@@ -117,16 +112,4 @@
 	    this.scrollerWidth = (wNoScroll - wScroll);
 	    return this.scrollerWidth || 0;
 	}	
-});
-
-Object.extend(ClientUI.common.box.ScrollableBox.prototype, {
-	// Custom events
-	/**
-	 * Occured when content scrolled in horizontal
-	 */
-	eventHScroll: {},
-	/**
-	 * Occured when content scrolled in vertical
-	 */
-	eventVScroll: {}	
 });
\ No newline at end of file

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/common/utils/Utils.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/common/utils/Utils.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/common/utils/Utils.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -255,7 +255,7 @@
 				}, 100);
 			}
 	
-			dataModel.eventDataReady.fire(localOptions);
+			grid.getBody()._onDataReady(localOptions);
 		}	
 	}
 };

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/DataModel.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/DataModel.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/DataModel.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -5,8 +5,6 @@
  */
 ClientUILib.declarePackage("ClientUI.controls.grid.DataModel");
 
-ClientUILib.requireClass("ClientUI.common.utils.CustomEvent");
-
 /*
  * DataModel.js - Base datamodel class for grid control 
  * by Denis Morozov <dmorozov at exadel.com> distributed under the BSD license. 
@@ -16,7 +14,6 @@
 	
 	initialize: function() {
 		// constructor
-		this.eventDataReady = new ClientUI.common.utils.CustomEvent('DataModel::OnDataReady');
 	},	
 	
 	// interface method
@@ -38,9 +35,4 @@
 	getRequestDelay: function() {
 		return 1000;
 	}
-});
-
-Object.extend(ClientUI.controls.grid.DataModel.prototype, {
-	eventDataReady: {}
-});
-			
+});		

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/Grid.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/Grid.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/Grid.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -33,21 +33,16 @@
 		
 	initialize: function($super, element, dataModel, templates) {
 		$super(element);
-		if(!this.element || !this.element.id)
-			this.element.id = "ClientUI_Grid" + ClientUI_controls_grid_Grid_idGenerator++;
 		
 		this.dataModel = dataModel;
 		this.templates = $A(templates);
-		
-		this.eventOnSort = new ClientUI.common.utils.CustomEvent('OnSort');
-		this.eventOnResizeColumn = new ClientUI.common.utils.CustomEvent('OnResizeColumn');
-		
+	
 		this.createControl();
 		
 	},
 	createControl: function() {
 		var grid = this;
-		this.layout = new ClientUI.layouts.GridLayoutManager(this.getElement(), null);
+		this.layout = new ClientUI.layouts.GridLayoutManager(this.getElement().id + ":c", null);
 		
 		var pagePart, item;
 		for(var i=0; i<this.templates.length; i++) {
@@ -116,7 +111,7 @@
 		if(this.getFooter()) this.getFooter().adjustColumnWidth(index, width);
 		this.updateLayout();
 		this.getHeader().agjustSeparators();
-		this.eventOnResizeColumn.fire(index, width);		
+	//	this.eventOnResizeColumn.fire(index, width);		
 	},
 	adjustScrollPosition: function(pos) {
 		if(pos<0) {pos = 0;}
@@ -162,15 +157,14 @@
 	},
 	quickFind: function(column, text, startRow) {
 		var start = startRow || 0;
-	    var searchText = "*" + text + "*";
-	    searchText = searchText.replace(/\*/g, ".*");
+	    var searchText = ".*" + text + ".*";
 	    var searchReg = new RegExp(searchText, 'i');
 		var rowIndex = -1;
 		var body = this.getBody();
 		var rowsCount = body.rowsCount;
         for (var i = start; i < rowsCount; i++) {
             var currentTextInGrid = body.getCellText(i, column);
-            currentTextInGrid = currentTextInGrid.replace(/,/g,'');
+            currentTextInGrid = currentTextInGrid.replace(/(<[^<]*>)/g,'');
             if (currentTextInGrid.search(searchReg) != -1) {
                 rowIndex = i;
                 break;
@@ -204,21 +198,4 @@
 			this.updateLayout();
 		}
 	}
-});
-
-Object.extend(ClientUI.controls.grid.Grid.prototype, {
-	// Custom events
-	/**
-	 * Occured when content header clicked
-	 */
-	eventOnSort: {},
-	/**
-	 * Occured when column width adjusted
-	 */
-	eventOnResizeColumn: {}
-});
-
-if(!ClientUI_controls_grid_Grid_idGenerator) {
-var ClientUI_controls_grid_Grid_idGenerator = 0;
-};
-			
+});			

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/GridBody.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/GridBody.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/GridBody.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -24,26 +24,23 @@
 		$super(template);
 
 		// declare event listeners
-		this._eventOnHScroll = this._onContentHScroll.bind(this);
-		this._eventOnVScroll = this._onContentVScroll.bind(this);
-		this._eventOnDataReady = this._onDataReady.bind(this);
+		this._eventOnHScroll = this._onContentHScroll.bindAsEventListener(this);
+		this._eventOnVScroll = this._onContentVScroll.bindAsEventListener(this);
 		
 		this.createControl(template);
 		this.registerEvents();
 	},
 	registerEvents: function() {
-		Event.observe(this.scrollBox.eventHScroll, "grid body hscroll", this._eventOnHScroll);
-		Event.observe(this.scrollBox.eventVScroll, "grid body vscroll", this._eventOnVScroll);
-		Event.observe(this.grid.dataModel.eventDataReady, "grid data is loaded", this._eventOnDataReady);
+		Event.observe(this.scrollBox.element, "grid:onhcroll", this._eventOnHScroll);
+		Event.observe(this.scrollBox.element, "grid:onvcroll", this._eventOnVScroll);
 	},
 	destroy: function() {
-		Event.stopObserving(this.scrollBox.eventHScroll, "grid body hscroll", this._eventOnHScroll);
-		Event.stopObserving(this.scrollBox.eventVScroll, "grid body vscroll", this._eventOnVScroll);
-		Event.stopObserving(this.grid.dataModel.eventDataReady, "grid data is loaded", this._eventOnDataReady);
+		Event.stopObserving(this.scrollBox.element, "grid:onhcroll", this._eventOnHScroll);
+		Event.stopObserving(this.scrollBox.element, "grid:onvcroll", this._eventOnVScroll);
 	},
 	// event listeners
-	_onContentHScroll: function(xpos) {
-		this.grid.adjustScrollPosition(xpos);
+	_onContentHScroll: function(event) {
+		this.grid.adjustScrollPosition(event.memo.pos);
 	},
 	_onDataReady: function(options) {
 		// load rows data		
@@ -53,14 +50,14 @@
 		
 		window.loadingInvalidateTime = (new Date()).getTime();
 	},
-	_onContentVScroll: function(ypos) {
+	_onContentVScroll: function(event) {
 		this.helpObject1.moveToY(this.sizeBox.getHeight()+ this.defaultRowHeight + 5);
 		this.helpObject2.moveToY(this.sizeBox.getHeight()+ this.defaultRowHeight + 5);
-		this.setScrollPos(ypos);
-		this.adjustDataPosition(ypos);
+		this.setScrollPos(event.memo.pos);
+		this.adjustDataPosition(event.memo.pos);
 	},
 	createControl: function(template) {
-
+		this.scrollInput = $(this.gridId + ":si");
 		var childs = template.childNodes;
 		for(var i=0; i<childs.length; i++) {
 			if(childs[i].id == this.gridId + ":bc") {
@@ -71,6 +68,7 @@
 				break;
 			}
 		}
+		Event.observe(this.container.getElement(), 'keypress', this.synchronizeScroll.bindAsEventListener(this));
 		
 		// create scroll box
 		this.scrollBox = new ClientUI.common.box.ScrollableBox(this.gridId + ":scb", this.getElement());
@@ -97,6 +95,7 @@
 
 		this.contentBox = new ClientUI.common.box.Box(normal);
 		this.contentBox.makeAbsolute();
+		Event.observe(this.contentBox.getElement(), 'keypress', this.synchronizeScroll.bindAsEventListener(this));
 		this.frozenContentBox = new ClientUI.common.box.Box(frozen);
 		this.frozenContentBox.makeAbsolute();
 		
@@ -224,15 +223,6 @@
 		this.scrollBox.setHeight(this.getHeight()+1);
 		this.scrollBox.setWidth(this.getWidth());
 		this.scrollBox.setHeight(this.getHeight());
-		var viewWidth = this.scrollBox.getViewportWidth();
-		this.container.setWidth(viewWidth);
-
-		if(ClientUILib.isIE) {
-			this.contentBox.setWidth(viewWidth - frozenContentWidth);
-		}
-		else {
-			this.contentBox.setWidth(Math.max(this.getWidth(), totalWidth));
-		}
 		
 		height = this.scrollBox.getElement().clientHeight;
 				
@@ -242,18 +232,28 @@
 		this.container.setHeight(height - fixH);
 		
 		this.defaultRowHeight = this._calcDefaultRowHeight();
+		this.sizeBox.hide();
 		this.sizeBox.setHeight(this.defaultRowHeight * this.grid.dataModel.getCount() + fixH);
 		this.helpObject1.moveToY(this.sizeBox.getHeight()+ this.defaultRowHeight + 5);
 		this.helpObject2.moveToY(this.sizeBox.getHeight()+ this.defaultRowHeight + 5);
-
-		var scrollPos = Math.min(totalWidth - viewWidth, scrollLeft);
-		this.grid.adjustScrollPosition(scrollPos);
 		
 		this.dataVisible = parseInt(this.contentBox.getHeight() / this.defaultRowHeight, 10) + 1;
 		this.dataVisible = Math.min(this.dataVisible, this.rowsCount);
 		if(height > 0) {
 			this.adjustDataPosition(this.currentPos);	
 		}
+		this.sizeBox.show();
+		var viewWidth = this.scrollBox.getViewportWidth();
+		this.container.setWidth(viewWidth);
+		
+		if(ClientUILib.isIE) {
+			this.contentBox.setWidth(viewWidth - frozenContentWidth);
+		}
+		else {
+			this.contentBox.setWidth(Math.max(this.getWidth(), totalWidth));
+		}
+		var scrollPos = Math.min(totalWidth - viewWidth, scrollLeft);
+		this.grid.adjustScrollPosition(scrollPos);
 	},
 	adjustScrollPosition: function(pos) {
 		this.templNormal.moveToX(-pos);
@@ -283,6 +283,9 @@
 		}
 		else if(to == this.grid.dataModel.getCount()) {
 			from = to - this.rowsCount;
+			if (from < 0) {
+				from = 0;
+			}
 		}
 
 		var range = $R(from, to);
@@ -339,7 +342,7 @@
 		var columns = this.grid.getHeader().getColumns();
 		var bodyCell = columns.last().bodyCol;
 		if(bodyCell) bodyCell.width = 1;
-		var width = this.grid.getElement().offsetWidth - this.fTable.offsetWidth - this.nTable.offsetWidth;
+		var width = this.container.getElement().offsetWidth - this.fTable.offsetWidth - this.nTable.offsetWidth;
 		if (width < 1) {
 			width = 1;
 		}
@@ -360,6 +363,8 @@
 		var startRowIndx = 0;
 		var countToLoad = 0;
 		
+		this.scrollInput.value = task.pos + "," + range.start + "," + range.end; 
+
 		// if we have intersepted ranges than rearrange rows
 		// in other case just move rows table to first position
 		if(this.currRange.end < range.start 
@@ -768,6 +773,27 @@
 		} else {
 			return 16;
 		}
+	},
+	
+	restoreScrollState: function() {	
+		this.scrollInput = $(this.gridId + ":si");
+		var value = this.scrollInput.value
+		if(value !=''){
+			var values = value.split(',');
+			this.currentPos = values[0];
+			this.scrollBox.getElement().scrollTop = values[0];
+			this.currRange.start = values[1];
+			this.currRange.end = values[2];
+			var visibleRowPos = this.currRange.start * this.defaultRowHeight;
+			this.templFrozen.moveToY(visibleRowPos);
+			this.templNormal.moveToY(visibleRowPos);
+		}
+	},
+	
+	synchronizeScroll: function(event) {
+		if(Event.KEY_TAB == event.keyCode || Event.KEY_TAB == event.charCode) {
+			Event.stop(event);
+		}
 	}
 });
 

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/GridHeader.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/GridHeader.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/GridHeader.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -183,7 +183,7 @@
 				frozen: false,
 				fixedWidth: Validators.getBoolean(cell.getAttribute("fixedWidth"), false),
 				sortable: Validators.getBoolean(cell.getAttribute("sortable"), false),
-				sorted: Validators.getBoolean(cell.getAttribute("sorted"), "desc")
+				sorted: null
 			};
 			
 			if(columns[j].sortable)
@@ -422,9 +422,7 @@
 				*/
 				var rows = this.grid.getBody().templFrozen.getElement().rows;
 				var startRow = rows && rows.length>0 ? this.grid.getBody()._getRowIndex(rows[0].id) : 0;
-				this.grid.eventOnSort.fire({
-					column: index,
-					/*order: dir,*/
+				this.grid.element.fire("grid:onsort",{ column: index,
 					startRow: startRow,
 					index: this.grid.getBody().currRange.start
 				});
@@ -437,12 +435,12 @@
 		var cols = this.getColumns();
 		for(var i = 0; i < cols.length; i++) {
 			var col = cols[i];
-			var th = col.object;
+			var div = col.object.getElement().firstChild;
 			var icon = this._getCellElements(i)[1];
 			
 			if (icon) {
-				var newPosX = th.getWidth() - icon.getWidth();
-				var newPosY = (th.getHeight() - icon.getHeight())/2;
+				var newPosX = div.clientWidth - icon.getWidth();
+				var newPosY = (div.clientHeight - icon.getHeight())/2;
 				
 				newPosX = Math.floor(newPosX);
 				newPosY = Math.floor(newPosY);

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/ScrollableGrid.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/ScrollableGrid.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/ScrollableGrid.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -7,7 +7,6 @@
 		this.options = options;
 		this.client_id = this.options.client_id;
 		this.rows_count = $(this.client_id + "_rows_input").value;
-		this.scroll_si = $(this.client_id + ":si");
 		this.columns_count = this.options.columnsCount;
 		this.splash_id = this.options.splash_id; 
 		this.dataModel = new ClientUI.controls.grid.FakeArrayDataModel(this.rows_count, this.columns_count, this.client_id);
@@ -19,10 +18,6 @@
 		];			
 		var grid = this;
 		var s = $super;
-		
-		Event.onReady(function(){
-			grid.init(s);
-		});		
 		Utils.execOnLoad(
 			function(){
 				grid.init(s);
@@ -44,57 +39,31 @@
 			superCtor(this.client_id, this.dataModel, this.templates);
 						
 			this.endCreateTime = (new Date()).getTime();
-						
-			// suspend some processing
-			setTimeout(function() {
-				this.startPostProcessTime = (new Date()).getTime();
-				
-				this.eventOnPostSort = new ClientUI.common.utils.CustomEvent('OnSort');
-				this.eventOnPostScroll = new ClientUI.common.utils.CustomEvent('OnScroll');
-							
-				//var progress = new ClientUI.common.box.SplashBox(this.splash_id, null, 300, true);
-				//this.setProgressCtrl(progress);
-				Event.observe(this.eventOnSort, "on sort",  this.onSorted.bindAsEventListener(this));
-				if (this.options.selectionInput) {
-					this.selectionManager = new ClientUI.controls.grid.SelectionManager(this);
-				}
-				
-				this.endPostProcessTime = (new Date()).getTime();
-			}.bind(this), 500);
-			
-			if(this.scroll_si.value !=''){
-				var options = this.scroll_si.value.split(',');
-				this.restoreScrollState(options[0],options[1],options[2]);  		
+					
+			Event.observe(this.element, "grid:onsort",  this.onSorted.bindAsEventListener(this));
+			if (this.options.selectionInput) {
+				this.selectionManager = new ClientUI.controls.grid.SelectionManager(this);
 			}
-			
-			var form = this.getForm($(this.client_id));						
-			Event.observe(form, "submit",this.restoreScrollPos.bindAsEventListener(this));
+			this.element.fire("grid:initialized");
+			this.getBody().restoreScrollState();
 		}
-	},	
-	
-	getForm: function(element){
-		var node = element;
-		if(node){
-			while(node.tagName.toUpperCase()  != 'FORM'){
-				node = node.parentNode;	
-			}
-		}
-		
-		return node;	
 	},
 	
 	onSortComplete : function(request, event, data){
+		this.dataModel.count = $(this.client_id + "_rows_input").value;
 		var options = request.getJSON("options");				
 		Utils.AJAX.updateRows(options,request,
 								this,this.client_id, 
 								[this.updateSelectionCallBack], 
 								[function(){
 									this.selectionManager.restoreState();
-									this.eventOnPostSort.fire(options.column, options.order);
+									this.element.fire("grid:onpostsort",{column: options.column, order:options.order});
 								}]);
 		this.updateLayout();
+		this.getBody().restoreScrollState();
 	},
 	onScrollComplete : function(request, event, data){
+		this.dataModel.count = $(this.client_id + "_rows_input").value;
 		var options = this.dataModel.getCurrentOptions();
 		window.loadingServerTime = (new Date()).getTime();
 		Utils.AJAX.updateRows(options,request,
@@ -102,9 +71,11 @@
 								[this.updateSelectionCallBack],
 								[function(){
 									this.selectionManager.restoreState();
-									this.eventOnPostScroll.fire(this.getBody().currRange.start);
+									this.element.fire("grid:onpostscroll",{start:this.getBody().currRange.start});
 								}]);								
 								
+		this.updateLayout();
+		this.getBody().restoreScrollState();
 		window.loadingEndTime = (new Date()).getTime();
 		
 		// TODO: remove this time statistic logging
@@ -115,8 +86,8 @@
 		ClientUILib.log(ClientUILogger.WARNING, "...Selection mng time: " + (window.loadingEndTime - window.loadingInvalidateTime));
 	},
 	
-	onSorted: function(sortEvent) {
-		this.options.onSortAjaxUpdate(sortEvent);
+	onSorted: function(event) {
+		this.options.onSortAjaxUpdate(event.memo);
 	},
 	
 	updateSelectionCallBack: function(argMap) {
@@ -151,45 +122,5 @@
 		this.getBody().hideColumn(index, frozen);
 		if(this.getFooter()) {this.getFooter().hideColumn(index, frozen);}				
 		this.updateLayout();
-	},
-	
-	restoreScrollState: function(scrollPos, start, end) {
-		
-		var body = this.getBody(); 
-		body.scrollBox.getElement().scrollTop = scrollPos;
-		body.currentPos = scrollPos;
-		body.currRange.start = start;
-		body.currRange.end = end;
-		body._onContentVScroll(scrollPos);
-		var visibleRowPos = body.currRange.start * body.defaultRowHeight;
-		//setTimeout(function(){
-			body.templFrozen.moveToY(visibleRowPos);
-			body.templNormal.moveToY(visibleRowPos);
-		//}, 500);
-	},
-	
-	getScrollPos: function() {
-		return this.getBody().currentPos;
-	},
-	
-	restoreScrollPos: function(){
-		var body = this.getBody();
-		var start = body.currRange.start;
-		var end = body.currRange.end;
-		var index = this.getScrollPos();
-		this.scroll_si.value = index + "," + start + "," + end; 
 	}
-});
-
-Object.extend(ClientUI.controls.grid.ScrollableGrid.prototype, {
-	/**
-	* Occured when scroll position adjusted
-	*/
-	eventOnPostScroll: {},
-	
-	/**
-	 * Occured when sorting adjusted
-	 */
-	eventOnPostSort: {}
-	
 });
\ No newline at end of file

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/Selection.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/Selection.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/controls/grid/Selection.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -143,13 +143,12 @@
 		this.ranges = ranges;
 	},
 	
-	initRanges: function(rangesStr) {
-		if(!rangesStr) {
+	initRanges: function(rangeStrRArray) {
+		if(rangeStrRArray.length == 0) {
 			this.ranges = [];
 			return;
 		}
-		var rangeStrRArray = rangesStr.split(";");
-		this.ranges = new Array(rangeStrRArray.length -1);
+		this.ranges = new Array(rangeStrRArray.length);
 		var indexStrRArray;
 		for(var i = 0; i < this.ranges.length; i++) {
 			indexStrRArray = rangeStrRArray[i].split(",");
@@ -201,6 +200,7 @@
 		this.grid = grid;
 		this.selectionFlag;
 		this.firstIndex;
+		this.activeRow = -1;
 		var gridElement = grid.getElement();
 		this.prefix = gridElement.id;
 		this.selection = new ClientUI.controls.grid.Selection();
@@ -214,6 +214,13 @@
 		this.setListeners();
 		this.eventKeyPress = this.processKeyDown.bindAsEventListener(this);
 		Event.observe(document, "keypress", this.eventKeyPress);
+		A4J.AJAX.AddListener({
+			onafterajax: function(req, event, data) {
+				if(!$(this.prefix + ":n")) {
+					Event.stopObserving(document, "keypress", this.eventKeyPress);		
+				}
+			}.bind(this)
+		});
 		if (document.selection) {
 			Event.observe(gridElement, "click", this.resetSelection.bindAsEventListener(this));
 		}
@@ -239,7 +246,15 @@
 
 	restoreState: function() {
 		this.selectionFlag = null;
-		this.selection.initRanges($(this.inputElement).value);
+		var selStrAr = $(this.inputElement).value.split(";");
+		if(selStrAr.length != 0) {
+		var activeRowStr = selStrAr[selStrAr.length - 1];
+			if(activeRowStr.indexOf(";") == -1) {
+				this.setActiveRow(activeRowStr);
+				selStrAr.pop();
+			}
+		}
+		this.selection.initRanges(selStrAr);
 	//	this.firstIndex = Number($(this.prefix + ":f").rows[0].id.split(this.prefix)[1].split(":")[2]);;
 		var i = 0;
 		var j;
@@ -303,81 +318,83 @@
 	},
 
 	processKeyDown: function(event) {
-		if(!event.shiftKey) {
-			this.shiftRow = null;
-		}		
-		var range, rowIndex;
-		var activeRow = this.activeRow;
-		var noDefault = false;
-		this.firstIndex = Number($(this.prefix + ":n").rows[0].id.split(this.prefix)[1].split(":")[2]);;
-		switch (event.keyCode || event.charCode) {
-			case Event.KEY_UP:
-				if (this.inFocus && activeRow != null) {
-					if(this.firstIndex != activeRow) {
-						rowIndex = (this.rowCount + activeRow - 1) % this.rowCount;		
-						if (!event.ctrlKey && !event.shiftKey) {
-							this.selectionFlag = "x";
-							range = [rowIndex, rowIndex];
-							this.setSelection(range);		
-						} else if (!event.ctrlKey && event.shiftKey) {
-							if(!this.shiftRow) {
-								this.shiftRow = this.activeRow;
+		if ($(this.prefix + ":n").rows.length > 0) {
+			if(!event.shiftKey) {
+				this.shiftRow = null;
+			}		
+			var range, rowIndex;
+			var activeRow = this.activeRow;
+			var noDefault = false;
+			this.firstIndex = Number($(this.prefix + ":n").rows[0].id.split(this.prefix)[1].split(":")[2]);;
+			switch (event.keyCode || event.charCode) {
+				case Event.KEY_UP:
+					if (this.inFocus && activeRow != null) {
+						if(this.firstIndex != activeRow) {
+							rowIndex = (this.rowCount + activeRow - 1) % this.rowCount;		
+							if (!event.ctrlKey && !event.shiftKey) {
+								this.selectionFlag = "x";
+								range = [rowIndex, rowIndex];
+								this.setSelection(range);		
+							} else if (!event.ctrlKey && event.shiftKey) {
+								if(!this.shiftRow) {
+									this.shiftRow = this.activeRow;
+								}
+								if(this.shiftRow >= this.activeRow) {
+									this.addRowToSelection(rowIndex);						
+								} else {
+									this.removeRowFromSelection(activeRow);						
+								}
 							}
-							if(this.shiftRow >= this.activeRow) {
-								this.addRowToSelection(rowIndex);						
-							} else {
-								this.removeRowFromSelection(activeRow);						
-							}
+							noDefault = true;
+							this.setActiveRow(rowIndex);
+						} else {
+							this.grid.getBody().showRow("up");					
 						}
-						noDefault = true;
-						this.setActiveRow(rowIndex);
-					} else {
-						this.grid.getBody().showRow("up");					
 					}
-				}
-				break;
-			case Event.KEY_DOWN:
-				if (this.inFocus && activeRow != null) {
-					rowIndex = (activeRow + 1) % this.rowCount;		
-					if(this.firstIndex != rowIndex) {
-						if (!event.ctrlKey && !event.shiftKey) {
-							this.selectionFlag = "x";
-							range = [rowIndex, rowIndex];
-							this.setSelection(range);		
-						} else if (!event.ctrlKey && event.shiftKey) {
-							if(!this.shiftRow) {
-								this.shiftRow = this.activeRow;
+					break;
+				case Event.KEY_DOWN:
+					if (this.inFocus && activeRow != null) {
+						rowIndex = (activeRow + 1) % this.rowCount;		
+						if(this.firstIndex != rowIndex) {
+							if (!event.ctrlKey && !event.shiftKey) {
+								this.selectionFlag = "x";
+								range = [rowIndex, rowIndex];
+								this.setSelection(range);		
+							} else if (!event.ctrlKey && event.shiftKey) {
+								if(!this.shiftRow) {
+									this.shiftRow = this.activeRow;
+								}
+								if(this.shiftRow <= this.activeRow) {
+									this.addRowToSelection(rowIndex);						
+								} else {
+									this.removeRowFromSelection(activeRow);						
+								}
 							}
-							if(this.shiftRow <= this.activeRow) {
-								this.addRowToSelection(rowIndex);						
-							} else {
-								this.removeRowFromSelection(activeRow);						
-							}
+							noDefault = true;
+							this.setActiveRow(rowIndex);
+						} else {
+							this.grid.getBody().showRow("down");					
 						}
+					}
+					break;
+				case 65: case 97:								// Ctrl-A
+					if (this.inFocus && event.ctrlKey) {
+						this.selectionFlag = "a";
+						range = [0, this.rowCount];
+						this.setSelection(range);		
 						noDefault = true;
-						this.setActiveRow(rowIndex);
-					} else {
-						this.grid.getBody().showRow("down");					
 					}
-				}
-				break;
-			case 65: case 97:								// Ctrl-A
-				if (this.inFocus && event.ctrlKey) {
-					this.selectionFlag = "a";
-					range = [0, this.rowCount];
-					this.setSelection(range);		
-					noDefault = true;
-				}
-				break;
-			case Event.KEY_TAB:
-				this.lostFocus();
+					break;
+				case Event.KEY_TAB:
+					this.lostFocus();
+			}
+			if (noDefault) {
+				this.grid.getBody().showRow(this.activeRow);
+				this.selectionChanged(event);			
+				if (event.preventBubble) event.preventBubble();
+				Event.stop(event);
+			}
 		}
-		if (noDefault) {
-			this.grid.getBody().showRow(this.activeRow);
-			this.selectionChanged(event);			
-			if (event.preventBubble) event.preventBubble();
-			Event.stop(event);
-		}
 	},
 
 	processClick: function(event, rowIndex) {
@@ -424,7 +441,7 @@
 	},
 	
 	selectionChanged: function(event) {
-		$(this.inputElement).value = this.selection.inspectRanges()+ (this.selectionFlag ? this.selectionFlag : "") ;
+		$(this.inputElement).value = this.selection.inspectRanges() + this.activeRow + ";" + (this.selectionFlag ? this.selectionFlag : "") ;
 		var state = this.selection.getState();			
 		event.oldSelection = this.oldState;
 		event.newSelection = state;

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/layouts/LayoutManager.js
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/layouts/LayoutManager.js	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/javascript/ClientUI/layouts/LayoutManager.js	2007-12-19 18:12:29 UTC (rev 4931)
@@ -23,10 +23,6 @@
 		// declare event listeners
 		this.eventContainerResize = this.containerResize.bindAsEventListener(this);
 		
-		// Create custom event producers
-		this.eventOnBeforeResize = new ClientUI.common.utils.CustomEvent('OnBeforeResize');
-		this.eventOnAfterResize = new ClientUI.common.utils.CustomEvent('OnAfterResize');
-		
 		this.registerEvents();
 	},
 	registerEvents: function() {
@@ -36,10 +32,7 @@
 			Event.stopObserving(window, "resize", this.eventContainerResize);
 	},
    	containerResize: function(event) {
-	  	//Event.stop(event);
-	  	this.eventOnBeforeResize.fire();
 	  	this.updateLayout();
-	  	this.eventOnAfterResize.fire();
 	},
 	updateLayout: function($super) {
 		if(this.container) {
@@ -57,18 +50,4 @@
 	getContainer: function() {
 		return this.container;
 	}
-});
-
-Object.extend(ClientUI.layouts.LayoutManager.prototype, {
-	
-	// Custom events
-	/**
-	 * Occured before resizing
-	 */
-	eventOnBeforeResize: {},
-	/**
-	 * Occured after resizing
-	 */
-	eventOnAfterResize: {}	
-
 });
\ No newline at end of file

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/resources/org/richfaces/renderkit/html/css/scrollable-data-table.xcss
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/resources/org/richfaces/renderkit/html/css/scrollable-data-table.xcss	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/resources/org/richfaces/renderkit/html/css/scrollable-data-table.xcss	2007-12-19 18:12:29 UTC (rev 4931)
@@ -95,8 +95,6 @@
 		 */
 		.dr-sdt-hcbody {
 			white-space: nowrap;
-		 	position: relative;
-			display: block;
 			overflow: hidden;	
 			width: 100%;
 			font-weight: normal;
@@ -151,8 +149,6 @@
 			font-weight: normal;
 			padding: 3px 5px;
 			white-space: nowrap;
-			position: relative;
-			display: block;
 			overflow: hidden;
 		}
 		
@@ -161,8 +157,6 @@
 			font-weight: normal;
 			padding: 0px 0px;
 			white-space: nowrap;
-			position: relative;
-			display: block;
 			overflow: hidden;
 			width: 100%;
 		}
@@ -212,9 +206,6 @@
 			cursor: default;
 			font-weight: normal;
 			white-space: nowrap;	
-			padding: 0px 0px;
-		 	position: relative;
-			display: block;
 			overflow: hidden;
 			-o-text-overflow: ellipsis;
 			text-overflow: ellipsis;

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/templates/org/richfaces/scrollable-data-table-footer-cell.jspx
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/templates/org/richfaces/scrollable-data-table-footer-cell.jspx	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/templates/org/richfaces/scrollable-data-table-footer-cell.jspx	2007-12-19 18:12:29 UTC (rev 4931)
@@ -12,11 +12,9 @@
 	>
 	
 	<th class="dr-sdt-fc rich-sdt-footer-cell #{footerColumnClass} #{footerColumnSortClass} #{component.attributes['footerClass']}">
-		<span id="#{client_id}:fc_#{cell_index}" class="dr-sdt-fcbody1">
-			<span class="dr-sdt-fcbody">
-				<vcp:body/>
-			</span>
-		</span>
+		<div id="#{client_id}:fc_#{cell_index}" class="dr-sdt-fcbody1">
+			<vcp:body/>
+		</div>
 	</th>
 	
 </f:root>	
\ No newline at end of file

Modified: branches/3.1.x/ui/scrollableDataTable/src/main/templates/org/richfaces/scrollable-data-table.jspx
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/main/templates/org/richfaces/scrollable-data-table.jspx	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/main/templates/org/richfaces/scrollable-data-table.jspx	2007-12-19 18:12:29 UTC (rev 4931)
@@ -64,174 +64,217 @@
 			variables.setVariable("hStyle", hStyle);
 		]]>
 	</jsp:scriptlet>
-	
-	
-	<div id="#{clientId}" style="width: #{component.attributes['width']};height: #{component.attributes['height']};" class="dr-sdt rich-sdt #{component.attributes['styleClass']}" >
-		<div id="#{clientId}:cs" class="dr-sdt-hsplit" style="display:none;"/>
-		<div id="#{clientId}_GridHeaderTemplate" class="dr-sdt-inlinebox" style="#{hStyle}; width: #{component.attributes['width']};">
-			<iframe id="#{clientId}:hs" class="dr-sdt-substrate" src="" scrolling="no" frameborder="0" > <br/> </iframe>
-			<div style="display: block; left: 0px; top: 0px; width: #{sumWidth}px;">			
-					<span class="dr-sdt-tmplbox dr-sdt-fb" id="#{clientId}:header:FrozenBox">
-						<table cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+
+	<table id="#{clientId}" cellpadding="0" cellspacing="0" style="width: #{component.attributes['width']};height: #{component.attributes['height']};" class="dr-sdt rich-sdt #{component.attributes['styleClass']}" >
+		<tbody>
+			<jsp:scriptlet>
+	     		<![CDATA[				
+					UIComponent facet = component.getFacet("header");
+					if (null != facet && facet .isRendered()) {
+				]]>	
+			</jsp:scriptlet>
+			<tr>
+				<td>
+				    <u:insertFacet name="header" />
+				</td>
+			</tr>
+			<jsp:scriptlet>
+	     		<![CDATA[				
+					}
+				]]>	
+			</jsp:scriptlet>
+			<tr>
+				<td style="height: 100%;">
+					<div id="#{clientId}:c" style="height: 100%;">
+						<div id="#{clientId}:cs" class="dr-sdt-hsplit" style="display: none;"/>
+						<div id="#{clientId}_GridHeaderTemplate" class="dr-sdt-inlinebox" style="#{hStyle}; width: #{component.attributes['width']};">
+							<iframe id="#{clientId}:hs" class="dr-sdt-substrate" src="" scrolling="no" frameborder="0" > <br/> </iframe>
+							<div style="display: block; left: 0px; top: 0px; width: #{sumWidth}px;">			
+									<span class="dr-sdt-tmplbox dr-sdt-fb" id="#{clientId}:header:FrozenBox">
+										<table cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+											
+											<jsp:scriptlet>
+												<![CDATA[
+													renderCols(context, component, true);
+												]]>
+											</jsp:scriptlet>					
+											
+											<thead>
+												<tr class="dr-sdt-hr rich-std-header-row #{component.attributes['headerClass']}">
+													<jsp:scriptlet>
+								                   		<![CDATA[
+															renderHeaders(context, component, true);
+														]]>
+													</jsp:scriptlet>
+												</tr>
+											</thead>
+										</table>					
+									</span>
 							
-							<jsp:scriptlet>
-								<![CDATA[
-									renderCols(context, component, true);
-								]]>
-							</jsp:scriptlet>					
-							
-							<thead>
-								<tr class="dr-sdt-hr rich-std-header-row #{component.attributes['headerClass']}">
-									<jsp:scriptlet>
-				                   		<![CDATA[
-											renderHeaders(context, component, true);
-										]]>
-									</jsp:scriptlet>
-								</tr>
-							</thead>
-						</table>					
-					</span>
-			
-					<span class="dr-sdt-tmplbox dr-sdt-nb" id="#{clientId}:header:NormalBox">
-						<table cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
-							
-							<jsp:scriptlet>
-								<![CDATA[
-									renderCols(context, component, false);
-								]]>
-							</jsp:scriptlet>					
-							<col width="1"/>
-							<thead>
-								<tr class="dr-sdt-hr rich-std-header-row #{component.attributes['headerClass']}">
-									<jsp:scriptlet>
-				                   		<![CDATA[
-											renderHeaders(context, component, false);
-										]]>
-									</jsp:scriptlet>
-									<th></th>
-								</tr>
-							</thead>
-						</table>
-				</span>	
-			</div>			
-		</div>
-		
-		
-		
-		<div id="#{clientId}_GridBodyTemplate" class="dr-sdt-inlinebox" style="overflow: auto; width: #{component.attributes['width']}; height: #{component.attributes['height']};">
-			<div id="#{clientId}:scb" style="position: absolute; z-index: 0;">
-				<div id="#{clientId}:sb" style="position: absolute;" ><br/> </div>
-			</div>
-			<div id="#{clientId}:bc" style="display: block; width:  #{sumWidth}px;">
-				<span class="dr-sdt-tmplbox dr-sdt-fb" id="#{clientId}:body:FrozenBox">
-					<table id="#{clientId}:f" cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+									<span class="dr-sdt-tmplbox dr-sdt-nb" id="#{clientId}:header:NormalBox">
+										<table cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+											
+											<jsp:scriptlet>
+												<![CDATA[
+													renderCols(context, component, false);
+												]]>
+											</jsp:scriptlet>					
+											<col width="1"/>
+											<thead>
+												<tr class="dr-sdt-hr rich-std-header-row #{component.attributes['headerClass']}">
+													<jsp:scriptlet>
+								                   		<![CDATA[
+															renderHeaders(context, component, false);
+														]]>
+													</jsp:scriptlet>
+													<th class="dr-sdt-hc rich-sdt-header-cell">
+														<div class="dr-sdt-hcbody" />
+													</th>
+												</tr>
+											</thead>
+										</table>
+								</span>	
+							</div>			
+						</div>
 						
-						<jsp:scriptlet>
-							<![CDATA[
-								renderCols(context, component, true);
-							]]>
-						</jsp:scriptlet>					
-						<tbody>
-							<jsp:scriptlet>
-				                <![CDATA[
-									renderGridBody(context, component, true);	
-								]]>
-							</jsp:scriptlet>
-						</tbody>
-					</table>
-					<span class="dr-sdt-ho" id="#{clientId}:fho" ><br/></span>
-				</span>
-				<span class="dr-sdt-tmplbox dr-sdt-nb" id="#{clientId}:body:NormalBox">
-					<table id="#{clientId}:n" cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
 						
+						
+						<div id="#{clientId}_GridBodyTemplate" class="dr-sdt-inlinebox" style="overflow: auto; width: #{component.attributes['width']}; height: #{component.attributes['height']};">
+							<div id="#{clientId}:scb" style="position: absolute; z-index: 0;">
+								<div id="#{clientId}:sb" style="position: absolute;" ><br/> </div>
+							</div>
+							<div id="#{clientId}:bc" style="display: block; width:  #{sumWidth}px;">
+								<span class="dr-sdt-tmplbox dr-sdt-fb" id="#{clientId}:body:FrozenBox">
+									<table id="#{clientId}:f" cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+										
+										<jsp:scriptlet>
+											<![CDATA[
+												renderCols(context, component, true);
+											]]>
+										</jsp:scriptlet>					
+										<tbody>
+											<jsp:scriptlet>
+								                <![CDATA[
+													renderGridBody(context, component, true);	
+												]]>
+											</jsp:scriptlet>
+										</tbody>
+									</table>
+									<span class="dr-sdt-ho" id="#{clientId}:fho" ><br/></span>
+								</span>
+								<span class="dr-sdt-tmplbox dr-sdt-nb" id="#{clientId}:body:NormalBox">
+									<table id="#{clientId}:n" cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+										
+										<jsp:scriptlet>
+											<![CDATA[
+												renderCols(context, component, false);
+											]]>
+										</jsp:scriptlet>					
+										<col width="1"/>												
+										<tbody>
+											<jsp:scriptlet>
+							                	<![CDATA[
+													renderGridBody(context, component, false);	
+												]]>
+											</jsp:scriptlet>
+										</tbody>
+									</table>
+									<span class="dr-sdt-ho" id="#{clientId}:nho" ><br/></span>
+								</span>		
+							</div>			
+						</div>
+						
+						<div id="#{clientId}_GridFooterTemplate" class="dr-sdt-inlinebox" style="#{fStyle}; width: #{component.attributes['width']};">
+							<iframe id="#{clientId}:fs" class="dr-sdt-substrate" src="" scrolling="no" frameborder="0" >  <br/></iframe>
+							<div style="display: block; width: width: #{sumWidth}px;">
+								<span class="dr-sdt-tmplbox dr-sdt-fb" id="#{clientId}:footer:FrozenBox">
+									<table cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+										
+										<jsp:scriptlet>
+											<![CDATA[
+												renderCols(context, component, true);
+											]]>
+										</jsp:scriptlet>					
+										<tfoot>
+											<tr class="dr-sdt-fr rich-std-footer-row #{component.attributes['footerClass']}">	
+												<jsp:scriptlet>
+								        	        <![CDATA[
+														renderFooters(context, component,true);	
+													]]>
+												</jsp:scriptlet>
+											</tr>
+										</tfoot>
+									</table>			
+								</span>
+								
+								<span class="dr-sdt-tmplbox dr-sdt-nb" id="#{clientId}:footer:NormalBox">
+									<table cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+										
+										<jsp:scriptlet>
+											<![CDATA[
+												renderCols(context, component, false);
+											]]>
+										</jsp:scriptlet>					
+										<col width="1"/>												
+										<tfoot>
+											<tr class="dr-sdt-fr rich-std-footer-row #{component.attributes['footerClass']}">
+												<jsp:scriptlet>
+								        	        <![CDATA[
+														renderFooters(context, component,false);	
+													]]>
+												</jsp:scriptlet>
+												<th class="dr-sdt-fc rich-sdt-footer-cell">
+													<div class="dr-sdt-fcbody1" />
+												</th>
+											</tr>
+										</tfoot>
+									</table>
+								</span>			
+							</div>
+						</div>			
+					
+						<input type="hidden" name="#{clientId}_hc" id="#{clientId}_hc"/>
+						<input type="hidden" name="#{clientId}_state_input" id="#{clientId}_state_input"/>
+						<input type="hidden" name="#{clientId}_options_input" id="#{clientId}_options_input"/>
+						<input type="hidden" name="#{clienId}_rows_input" id="#{clientId}_rows_input" value="#{rows_count}"/>
+						<input type="button" name="#{clientId}_submit_input" id="#{clientId}_submit_input" onclick="#{this:getRowsAjaxUpdate(context,component)}" style="display:none"/>
 						<jsp:scriptlet>
-							<![CDATA[
-								renderCols(context, component, false);
+						   <![CDATA[
+								renderHiddenScrollInput(context, component);	
 							]]>
-						</jsp:scriptlet>					
-						<col width="1"/>												
-						<tbody>
-							<jsp:scriptlet>
-			                	<![CDATA[
-									renderGridBody(context, component, false);	
-								]]>
-							</jsp:scriptlet>
-						</tbody>
-					</table>
-					<span class="dr-sdt-ho" id="#{clientId}:nho" ><br/></span>
-				</span>		
-			</div>			
-		</div>
-		
-		<div id="#{clientId}_GridFooterTemplate" class="dr-sdt-inlinebox" style="#{fStyle}; width: #{component.attributes['width']};">
-			<iframe id="#{clientId}:fs" class="dr-sdt-substrate" src="" scrolling="no" frameborder="0" >  <br/></iframe>
-			<div style="display: block; width: width: #{sumWidth}px;">
-				<span class="dr-sdt-tmplbox dr-sdt-fb" id="#{clientId}:footer:FrozenBox">
-					<table cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
+						</jsp:scriptlet>
 						
-						<jsp:scriptlet>
-							<![CDATA[
-								renderCols(context, component, true);
-							]]>
-						</jsp:scriptlet>					
-						<tfoot>
-							<tr class="dr-sdt-fr rich-std-footer-row #{component.attributes['footerClass']}">	
-								<jsp:scriptlet>
-				        	        <![CDATA[
-										renderFooters(context, component,true);	
-									]]>
-								</jsp:scriptlet>
-							</tr>
-						</tfoot>
-					</table>			
-				</span>
+						<f:call name="contributorsEncodeHere"/>
+						<script id="#{clientId}_grid_create_scripts" type="text/javascript">
+						//<![CDATA[
+						
+						#{this:getJavaScriptVarName(context, component)} = #{this:createClientScrollableGrid(context, component)};
+						#{this:getScriptContributions(context, component)};
 				
-				<span class="dr-sdt-tmplbox dr-sdt-nb" id="#{clientId}:footer:NormalBox">
-					<table cellpadding="0" cellspacing="0" style="border-collapse:collapse; table-layout:fixed">
-						
-						<jsp:scriptlet>
-							<![CDATA[
-								renderCols(context, component, false);
-							]]>
-						</jsp:scriptlet>					
-						<col width="1"/>												
-						<tfoot>
-							<tr class="dr-sdt-fr rich-std-footer-row #{component.attributes['footerClass']}">
-								<jsp:scriptlet>
-				        	        <![CDATA[
-										renderFooters(context, component,false);	
-									]]>
-								</jsp:scriptlet>
-								<th></th>
-							</tr>
-						</tfoot>
-					</table>
-				</span>			
-			</div>
-		</div>			
-	
-		<input type="hidden" name="#{clientId}_hc" id="#{clientId}_hc"/>
-		<input type="hidden" name="#{clientId}_state_input" id="#{clientId}_state_input"/>
-		<input type="hidden" name="#{clientId}_options_input" id="#{clientId}_options_input"/>
-		<input type="hidden" name="#{clienId}_rows_input" id="#{clientId}_rows_input" value="#{rows_count}"/>
-		<input type="button" name="#{clientId}_submit_input" id="#{clientId}_submit_input" onclick="#{this:getRowsAjaxUpdate(context,component)}" style="display:none"/>
-		<jsp:scriptlet>
-		   <![CDATA[
-				renderHiddenScrollInput(context, component);	
-			]]>
-		</jsp:scriptlet>
-		
-		<f:call name="contributorsEncodeHere"/>
-		<script id="#{clientId}_grid_create_scripts" type="text/javascript">
-		//<![CDATA[
-		
-		#{this:getJavaScriptVarName(context, component)} = #{this:createClientScrollableGrid(context, component)};
-		#{this:getScriptContributions(context, component)};
-
-		//		]]>
-		</script>
-		<f:call name="tearDownState"/>	
-	</div>	
+						//		]]>
+						</script>
+						<f:call name="tearDownState"/>	
+					</div>
+				</td>
+			</tr>
+			<jsp:scriptlet>
+	     		<![CDATA[				
+					facet = component.getFacet("footer");
+					if (null != facet && facet .isRendered()) {
+				]]>	
+			</jsp:scriptlet>
+			<tr>
+				<td>
+				    <u:insertFacet name="footer" />
+				</td>
+			</tr>
+			<jsp:scriptlet>
+	     		<![CDATA[				
+					}
+				]]>	
+			</jsp:scriptlet>
+		</tbody>
+	</table>	
 </f:root>	
 	
 	

Modified: branches/3.1.x/ui/scrollableDataTable/src/test/java/org/richfaces/renderkit/html/ScrollableDataTableRendererTest.java
===================================================================
--- branches/3.1.x/ui/scrollableDataTable/src/test/java/org/richfaces/renderkit/html/ScrollableDataTableRendererTest.java	2007-12-19 18:00:05 UTC (rev 4930)
+++ branches/3.1.x/ui/scrollableDataTable/src/test/java/org/richfaces/renderkit/html/ScrollableDataTableRendererTest.java	2007-12-19 18:12:29 UTC (rev 4931)
@@ -35,6 +35,7 @@
 		javaScripts.add(PrototypeScript.class.getName());
 		
 		javaScripts.add("org/richfaces/renderkit/html/scripts/scrollable-data-table.js");
+		javaScripts.add("org/richfaces/renderkit/html/scripts/extend/extend.js");
 	}
 	
 	public ScrollableDataTableRendererTest(String arg0) {




More information about the richfaces-svn-commits mailing list