Author: nbelaevski
Date: 2008-06-19 15:21:31 -0400 (Thu, 19 Jun 2008)
New Revision: 9121
Added:
trunk/framework/impl/src/main/java/org/richfaces/component/util/AbstractMessageUtil.java
trunk/sandbox/api/src/main/java/org/richfaces/event/ChangeColumnVisibilityEvent.java
trunk/sandbox/api/src/main/java/org/richfaces/event/ChangeColumnVisibilityListener.java
trunk/sandbox/api/src/main/java/org/richfaces/event/ColumnResizeEvent.java
trunk/sandbox/api/src/main/java/org/richfaces/event/ColumnResizeListener.java
trunk/sandbox/api/src/main/java/org/richfaces/event/DragDropEvent.java
trunk/sandbox/api/src/main/java/org/richfaces/event/DragDropListener.java
trunk/sandbox/api/src/main/java/org/richfaces/messages/
trunk/sandbox/api/src/main/java/org/richfaces/messages/SandboxMessageUtil.java
trunk/sandbox/api/src/main/java/org/richfaces/model/DataProvider.java
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedDataTableModifiableModel.java
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedTableDataModel.java
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedTableDataModelWrapper.java
trunk/sandbox/api/src/main/resources/
trunk/sandbox/api/src/main/resources/org/
trunk/sandbox/api/src/main/resources/org/richfaces/
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages.properties
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_de.properties
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_en.properties
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_pl.properties
trunk/sandbox/impl/src/main/java/org/richfaces/component/
trunk/sandbox/impl/src/main/java/org/richfaces/component/util/
trunk/sandbox/impl/src/main/java/org/richfaces/component/util/SandboxMessageUtil.java
trunk/sandbox/ui/extendedDataTable/
trunk/sandbox/ui/extendedDataTable/generatescript.xml
trunk/sandbox/ui/extendedDataTable/pom.xml
trunk/sandbox/ui/extendedDataTable/src/
trunk/sandbox/ui/extendedDataTable/src/main/
trunk/sandbox/ui/extendedDataTable/src/main/config/
trunk/sandbox/ui/extendedDataTable/src/main/config/component/
trunk/sandbox/ui/extendedDataTable/src/main/config/component/ExtendedDataTable.xml
trunk/sandbox/ui/extendedDataTable/src/main/config/component/README
trunk/sandbox/ui/extendedDataTable/src/main/java/
trunk/sandbox/ui/extendedDataTable/src/main/java/org/
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/ExtendedTableColumnsIterator.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/README
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/SortedColumnsIterator.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/UIExtendedDataTable.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/UIExtendedDataTableState.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/AbstractExtendedRowsRenderer.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/AbstractExtendedTableRenderer.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/ExtendedTableHolder.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/DraggableRendererContributor.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/DropzoneRendererContributor.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/RichTableMenuRenderer.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/SimpleTableMenuRenderer.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableDragDropRenderer.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableMenuRenderer.java
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableSelectionRendererContributor.java
trunk/sandbox/ui/extendedDataTable/src/main/javascript/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/box/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/box/Box.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/StringBuilder.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/Utils.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/Validators.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTable.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTableHeader.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTableSelection.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUILib.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/common/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/common/prototype/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/common/prototype/ext/
trunk/sandbox/ui/extendedDataTable/src/main/javascript/common/prototype/ext/extend.js
trunk/sandbox/ui/extendedDataTable/src/main/javascript/common/scriptaculous/
trunk/sandbox/ui/extendedDataTable/src/main/resources/
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/css/
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/css/extendedDataTable.xcss
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/checked.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/col-move-bottom.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/col-move-top.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/columns.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/columns.png
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/grid3-hd-btn.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/group-by.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/group-by.png
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/hmenu-asc.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/hmenu-desc.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/item-over.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/loading.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu-sort-asc.png
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu-sort-desc.png
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menuHover.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/minusIcon.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/plusIcon.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/s.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/sep-span.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/unchecked.gif
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/dt-drag-indicator.js
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/simple-draggable.js
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/simple-dropzone.js
trunk/sandbox/ui/extendedDataTable/src/main/templates/
trunk/sandbox/ui/extendedDataTable/src/main/templates/README
trunk/sandbox/ui/extendedDataTable/src/main/templates/org/
trunk/sandbox/ui/extendedDataTable/src/main/templates/org/richfaces/
trunk/sandbox/ui/extendedDataTable/src/main/templates/org/richfaces/htmlExtendedDataTable.jspx
trunk/sandbox/ui/extendedDataTable/src/test/
trunk/sandbox/ui/extendedDataTable/src/test/java/
trunk/sandbox/ui/extendedDataTable/src/test/java/org/
trunk/sandbox/ui/extendedDataTable/src/test/java/org/richfaces/
trunk/sandbox/ui/extendedDataTable/src/test/java/org/richfaces/component/
trunk/sandbox/ui/extendedDataTable/src/test/java/org/richfaces/component/JSFComponentTest.java
Modified:
trunk/framework/impl/src/main/java/org/richfaces/component/util/MessageUtil.java
trunk/sandbox/impl/pom.xml
trunk/sandbox/ui/pom.xml
trunk/ui/dataTable/src/main/config/component/columnAttributes.ent
trunk/ui/dataTable/src/main/java/org/richfaces/component/UIColumn.java
Log:
Initial import for extendedDataTable
Added:
trunk/framework/impl/src/main/java/org/richfaces/component/util/AbstractMessageUtil.java
===================================================================
---
trunk/framework/impl/src/main/java/org/richfaces/component/util/AbstractMessageUtil.java
(rev 0)
+++
trunk/framework/impl/src/main/java/org/richfaces/component/util/AbstractMessageUtil.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,124 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces - 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.component.util;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.faces.application.Application;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+/**
+ * Created 19.06.2008
+ * @author Nick Belaevski
+ * @since 3.2.2
+ */
+
+public class AbstractMessageUtil {
+ private static final ResourceBundle getResourceBundle(String baseName, Locale locale,
ClassLoader loader) {
+ if (loader != null) {
+ return ResourceBundle.getBundle(baseName, locale, loader);
+ } else {
+ return ResourceBundle.getBundle(baseName, locale);
+ }
+ }
+
+ private static final FacesMessage getMessage(FacesContext context, String messageId,
+ Object[] parameters, Locale locale, String baseBundleName) {
+ String summary = null;
+ String detail = null;
+
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+ if (context != null) {
+ Application application = context.getApplication();
+ if (application != null) {
+ String messageBundleName = application.getMessageBundle();
+
+ if (messageBundleName != null) {
+ ResourceBundle bundle = getResourceBundle(messageBundleName, locale, loader);
+ if (bundle != null) {
+ try {
+ summary = bundle.getString(messageId);
+ detail = bundle.getString(messageId + "_detail");
+ } catch (MissingResourceException e) {
+ //do nothing
+ }
+ }
+ }
+ }
+ }
+
+ if (summary == null) {
+ ResourceBundle bundle = getResourceBundle(baseBundleName, locale, loader);
+ try {
+ summary = bundle.getString(messageId);
+
+ if (summary == null) {
+ return null;
+ }
+
+ detail = bundle.getString(messageId + "_detail");
+ } catch (MissingResourceException e) {
+ //do nothing
+ }
+ }
+
+ String formattedSummary = MessageFormat.format(summary, parameters);
+ String formattedDetail = null;
+ if (detail != null) {
+ formattedDetail = MessageFormat.format(detail, parameters);
+ }
+
+ return new FacesMessage(formattedSummary, formattedDetail);
+ }
+
+ protected static final FacesMessage getMessage(FacesContext context, String messageId,
+ Object[] parameters, String baseBundleName) {
+
+ Locale locale;
+ FacesMessage result = null;
+
+ if (context != null) {
+ UIViewRoot viewRoot = context.getViewRoot();
+ if (viewRoot != null) {
+ locale = viewRoot.getLocale();
+
+ if (locale != null) {
+ result = getMessage(context, messageId, parameters, locale, baseBundleName);
+ }
+ }
+ }
+
+ if (result == null) {
+ locale = Locale.getDefault();
+ result = getMessage(context, messageId, parameters, locale, baseBundleName);
+ }
+
+ return result;
+ }
+
+}
Modified:
trunk/framework/impl/src/main/java/org/richfaces/component/util/MessageUtil.java
===================================================================
---
trunk/framework/impl/src/main/java/org/richfaces/component/util/MessageUtil.java 2008-06-19
17:13:04 UTC (rev 9120)
+++
trunk/framework/impl/src/main/java/org/richfaces/component/util/MessageUtil.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -21,15 +21,9 @@
package org.richfaces.component.util;
-import java.text.MessageFormat;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
-import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
@@ -38,7 +32,7 @@
* created 06.02.2007
*
*/
-public class MessageUtil {
+public class MessageUtil extends AbstractMessageUtil {
private static final boolean IS_12;
static {
@@ -73,86 +67,9 @@
return o;
}
- private static final ResourceBundle getResourceBundle(String baseName, Locale locale,
ClassLoader loader) {
- if (loader != null) {
- return ResourceBundle.getBundle(baseName, locale, loader);
- } else {
- return ResourceBundle.getBundle(baseName, locale);
- }
- }
-
- private static final FacesMessage getMessage(FacesContext context, String messageId,
- Object[] parameters, Locale locale) {
- String summary = null;
- String detail = null;
-
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
-
- if (context != null) {
- Application application = context.getApplication();
- if (application != null) {
- String messageBundleName = application.getMessageBundle();
-
- if (messageBundleName != null) {
- ResourceBundle bundle = getResourceBundle(messageBundleName, locale, loader);
- if (bundle != null) {
- try {
- summary = bundle.getString(messageId);
- detail = bundle.getString(messageId + "_detail");
- } catch (MissingResourceException e) {
- //do nothing
- }
- }
- }
- }
- }
-
- if (summary == null) {
- ResourceBundle bundle = getResourceBundle(FacesMessage.FACES_MESSAGES, locale,
loader);
- try {
- summary = bundle.getString(messageId);
-
- if (summary == null) {
- return null;
- }
-
- detail = bundle.getString(messageId + "_detail");
- } catch (MissingResourceException e) {
- //do nothing
- }
- }
-
- String formattedSummary = MessageFormat.format(summary, parameters);
- String formattedDetail = null;
- if (detail != null) {
- formattedDetail = MessageFormat.format(detail, parameters);
- }
-
- return new FacesMessage(formattedSummary, formattedDetail);
- }
-
public static final FacesMessage getMessage(FacesContext context, String messageId,
Object[] parameters) {
- Locale locale;
- FacesMessage result = null;
-
- if (context != null) {
- UIViewRoot viewRoot = context.getViewRoot();
- if (viewRoot != null) {
- locale = viewRoot.getLocale();
-
- if (locale != null) {
- result = getMessage(context, messageId, parameters, locale);
- }
- }
- }
-
- if (result == null) {
- locale = Locale.getDefault();
- result = getMessage(context, messageId, parameters, locale);
- }
-
- return result;
+ return AbstractMessageUtil.getMessage(context, messageId, parameters,
FacesMessage.FACES_MESSAGES);
}
}
Added:
trunk/sandbox/api/src/main/java/org/richfaces/event/ChangeColumnVisibilityEvent.java
===================================================================
--- trunk/sandbox/api/src/main/java/org/richfaces/event/ChangeColumnVisibilityEvent.java
(rev 0)
+++
trunk/sandbox/api/src/main/java/org/richfaces/event/ChangeColumnVisibilityEvent.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,47 @@
+/**
+ *
+ */
+package org.richfaces.event;
+
+import javax.faces.component.UIComponent;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.FacesListener;
+
+/**
+ * @author pawelgo
+ *
+ */
+public class ChangeColumnVisibilityEvent extends FacesEvent {
+
+ private static final long serialVersionUID = 178097339066092532L;
+
+ private String columnId;
+
+ public ChangeColumnVisibilityEvent(UIComponent component, String columnId) {
+ super(component);
+ this.columnId = columnId;
+ }
+
+ /* (non-Javadoc)
+ * @see
javax.faces.event.FacesEvent#isAppropriateListener(javax.faces.event.FacesListener)
+ */
+ public boolean isAppropriateListener(FacesListener listener) {
+ return (listener instanceof ChangeColumnVisibilityListener);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.faces.event.FacesEvent#processListener(javax.faces.event.FacesListener)
+ */
+ public void processListener(FacesListener listener) {
+ ((ChangeColumnVisibilityListener)listener).processChangeVisibility(this);
+ }
+
+ public String getColumnId() {
+ return columnId;
+ }
+
+ public void setColumnId(String columnId) {
+ this.columnId = columnId;
+ }
+
+}
Added:
trunk/sandbox/api/src/main/java/org/richfaces/event/ChangeColumnVisibilityListener.java
===================================================================
---
trunk/sandbox/api/src/main/java/org/richfaces/event/ChangeColumnVisibilityListener.java
(rev 0)
+++
trunk/sandbox/api/src/main/java/org/richfaces/event/ChangeColumnVisibilityListener.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,15 @@
+/**
+ *
+ */
+package org.richfaces.event;
+
+import javax.faces.event.FacesListener;
+
+/**
+ * @author pawelgo
+ *
+ */
+public interface ChangeColumnVisibilityListener extends FacesListener {
+
+ public void processChangeVisibility(ChangeColumnVisibilityEvent event);
+}
Added: trunk/sandbox/api/src/main/java/org/richfaces/event/ColumnResizeEvent.java
===================================================================
--- trunk/sandbox/api/src/main/java/org/richfaces/event/ColumnResizeEvent.java
(rev 0)
+++ trunk/sandbox/api/src/main/java/org/richfaces/event/ColumnResizeEvent.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,47 @@
+/**
+ *
+ */
+package org.richfaces.event;
+
+import javax.faces.component.UIComponent;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.FacesListener;
+
+/**
+ * @author pawelgo
+ *
+ */
+public class ColumnResizeEvent extends FacesEvent {
+
+ private static final long serialVersionUID = -8424890931071484456L;
+
+ private String columnWidths;
+
+ public ColumnResizeEvent(UIComponent component, String columnWidths) {
+ super(component);
+ this.columnWidths = columnWidths;
+ }
+
+ /* (non-Javadoc)
+ * @see
javax.faces.event.FacesEvent#isAppropriateListener(javax.faces.event.FacesListener)
+ */
+ public boolean isAppropriateListener(FacesListener listener) {
+ return (listener instanceof ColumnResizeListener);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.faces.event.FacesEvent#processListener(javax.faces.event.FacesListener)
+ */
+ public void processListener(FacesListener listener) {
+ ((ColumnResizeListener)listener).processColumnResize(this);
+ }
+
+ public String getColumnWidths() {
+ return columnWidths;
+ }
+
+ public void setColumnWidths(String columnWidths) {
+ this.columnWidths = columnWidths;
+ }
+
+}
Added: trunk/sandbox/api/src/main/java/org/richfaces/event/ColumnResizeListener.java
===================================================================
--- trunk/sandbox/api/src/main/java/org/richfaces/event/ColumnResizeListener.java
(rev 0)
+++
trunk/sandbox/api/src/main/java/org/richfaces/event/ColumnResizeListener.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,15 @@
+/**
+ *
+ */
+package org.richfaces.event;
+
+import javax.faces.event.FacesListener;
+
+/**
+ * @author pawelgo
+ *
+ */
+public interface ColumnResizeListener extends FacesListener {
+
+ public void processColumnResize(ColumnResizeEvent event);
+}
Added: trunk/sandbox/api/src/main/java/org/richfaces/event/DragDropEvent.java
===================================================================
--- trunk/sandbox/api/src/main/java/org/richfaces/event/DragDropEvent.java
(rev 0)
+++ trunk/sandbox/api/src/main/java/org/richfaces/event/DragDropEvent.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,67 @@
+/**
+ *
+ */
+package org.richfaces.event;
+
+import javax.faces.component.UIComponent;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.FacesListener;
+
+/**
+ * @author pawelgo
+ *
+ */
+public class DragDropEvent extends FacesEvent {
+
+ private static final long serialVersionUID = 2589493255876683993L;
+
+ private Object dragValue;
+ private Object dropValue;
+ private String dragType;
+ private boolean dropBefore;
+
+ public DragDropEvent(UIComponent component) {
+ super(component);
+ }
+
+ public void processListener(FacesListener listener) {
+ ((DragDropListener)listener).processDragDrop(this);
+ }
+
+ public Object getDragValue() {
+ return dragValue;
+ }
+
+ public void setDragValue(Object dragValue) {
+ this.dragValue = dragValue;
+ }
+
+ public Object getDropValue() {
+ return dropValue;
+ }
+
+ public void setDropValue(Object dropValue) {
+ this.dropValue = dropValue;
+ }
+
+ public String getDragType() {
+ return dragType;
+ }
+
+ public void setDragType(String dragType) {
+ this.dragType = dragType;
+ }
+
+ public boolean isDropBefore() {
+ return dropBefore;
+ }
+
+ public void setDropBefore(boolean dropBefore) {
+ this.dropBefore = dropBefore;
+ }
+
+ public boolean isAppropriateListener(FacesListener listener) {
+ return (listener instanceof DragDropListener);
+ }
+
+}
Added: trunk/sandbox/api/src/main/java/org/richfaces/event/DragDropListener.java
===================================================================
--- trunk/sandbox/api/src/main/java/org/richfaces/event/DragDropListener.java
(rev 0)
+++ trunk/sandbox/api/src/main/java/org/richfaces/event/DragDropListener.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,15 @@
+/**
+ *
+ */
+package org.richfaces.event;
+
+import javax.faces.event.FacesListener;
+
+/**
+ * @author pawelgo
+ *
+ */
+public interface DragDropListener extends FacesListener {
+
+ public void processDragDrop(DragDropEvent event);
+}
Added: trunk/sandbox/api/src/main/java/org/richfaces/messages/SandboxMessageUtil.java
===================================================================
--- trunk/sandbox/api/src/main/java/org/richfaces/messages/SandboxMessageUtil.java
(rev 0)
+++
trunk/sandbox/api/src/main/java/org/richfaces/messages/SandboxMessageUtil.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,119 @@
+/**
+ *
+ */
+package org.richfaces.messages;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.faces.application.Application;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+/**
+ * @author pawelgo
+ *
+ */
+public class SandboxMessageUtil {
+
+ public static final String MESSAGES = "org.richfaces.sandbox.Messages";
+
+ private static final ResourceBundle getResourceBundle(String baseName, Locale locale,
ClassLoader loader) {
+ if (loader != null) {
+ return ResourceBundle.getBundle(baseName, locale, loader);
+ } else {
+ return ResourceBundle.getBundle(baseName, locale);
+ }
+ }
+
+ private static final FacesMessage getMessage(FacesContext context, String messageId,
+ Object[] parameters, Locale locale) {
+ String summary = null;
+ String detail = null;
+
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+ if (context != null) {
+ Application application = context.getApplication();
+ if (application != null) {
+ String messageBundleName = application.getMessageBundle();
+
+ if (messageBundleName != null) {
+ ResourceBundle bundle = getResourceBundle(messageBundleName, locale, loader);
+ if (bundle != null) {
+ try {
+ summary = bundle.getString(messageId);
+ detail = bundle.getString(messageId + "_detail");
+ } catch (MissingResourceException e) {
+ //do nothing
+ }
+ }
+ }
+ }
+ }
+
+ if (summary == null) {
+ ResourceBundle bundle = getResourceBundle(MESSAGES, locale, loader);
+ if (bundle != null) {
+ try {
+ summary = bundle.getString(messageId);
+ detail = bundle.getString(messageId + "_detail");
+ } catch (MissingResourceException e) {
+ //do nothing
+ }
+ }
+ }
+
+ if (summary == null) {
+ ResourceBundle bundle = getResourceBundle(FacesMessage.FACES_MESSAGES, locale,
loader);
+ try {
+ summary = bundle.getString(messageId);
+
+ if (summary == null) {
+ return null;
+ }
+
+ detail = bundle.getString(messageId + "_detail");
+ } catch (MissingResourceException e) {
+ //do nothing
+ }
+ }
+
+ String formattedSummary = MessageFormat.format(summary, parameters);
+ String formattedDetail = null;
+ if (detail != null) {
+ formattedDetail = MessageFormat.format(detail, parameters);
+ }
+
+ return new FacesMessage(formattedSummary, formattedDetail);
+ }
+
+ public static final FacesMessage getMessage(FacesContext context, String messageId,
+ Object[] parameters) {
+
+ Locale locale;
+ FacesMessage result = null;
+
+ if (context != null) {
+ UIViewRoot viewRoot = context.getViewRoot();
+ if (viewRoot != null) {
+ locale = viewRoot.getLocale();
+
+ if (locale != null) {
+ result = getMessage(context, messageId, parameters, locale);
+ }
+ }
+ }
+
+ if (result == null) {
+ locale = Locale.getDefault();
+ result = getMessage(context, messageId, parameters, locale);
+ }
+
+ return result;
+ }
+
+}
Added: trunk/sandbox/api/src/main/java/org/richfaces/model/DataProvider.java
===================================================================
--- trunk/sandbox/api/src/main/java/org/richfaces/model/DataProvider.java
(rev 0)
+++ trunk/sandbox/api/src/main/java/org/richfaces/model/DataProvider.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,50 @@
+/**
+ *
+ */
+package org.richfaces.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * G3DataProvider is an interface that defines methods for manage loading
data.<br>
+ * Usage:
+ * <pre>
+ * G3DataProvider<SomeDataType> dataProvider = new
G3DataProvider<SomeDataType>();
+ * </pre>
+ * @author pawelgo
+ *
+ */
+public interface DataProvider<T> extends Serializable {
+
+ /**
+ * Get number of all rows.
+ * @return number of rows.
+ */
+ public int getRowCount();
+
+ /**
+ * Loads elements from given range.
+ * Starting from startRow, and up to but excluding endRow.
+ * @param firstRow first row to load
+ * @param endRow end row to load
+ * @return element list
+ */
+ public List<T> getItemsByRange(int firstRow, int endRow);
+
+ /**
+ * Load single element by given key.
+ * @param key element key to be loaded.
+ * @return element or null, if not found
+ */
+ public T getItemByKey(Object key);
+
+ /**
+ * Get element key.
+ * If key is not instance of Integer or
org.richfaces.model.ScrollableTableDataModel.SimpleRowKey,
+ * it is necessary to implement javax.faces.convert.Converter for key type.
+ * @param item element, which key to be get
+ * @return element key
+ */
+ public Object getKey(T item);
+}
Added:
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedDataTableModifiableModel.java
===================================================================
---
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedDataTableModifiableModel.java
(rev 0)
+++
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedDataTableModifiableModel.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,196 @@
+/**
+ *
+ */
+package org.richfaces.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.faces.context.FacesContext;
+import javax.faces.model.DataModelListener;
+
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.model.ExtendedDataModel;
+import org.ajax4jsf.model.Range;
+import org.ajax4jsf.model.SequenceRange;
+import org.ajax4jsf.model.SerializableDataModel;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.richfaces.model.FilterField;
+import org.richfaces.model.SortField2;
+import org.richfaces.model.impl.expressive.JavaBeanWrapper;
+import org.richfaces.model.impl.expressive.ObjectWrapperFactory;
+import org.richfaces.model.impl.expressive.WrappedBeanComparator2;
+import org.richfaces.model.impl.expressive.WrappedBeanFilter;
+
+/**
+ * @author pawelgo
+ *
+ */
+public class ExtendedDataTableModifiableModel<T> extends ExtendedDataModel {
+
+ private static final Log log =
LogFactory.getLog(ExtendedDataTableModifiableModel.class);
+
+ private ExtendedDataModel delegate;
+
+ private ExtendedTableDataModel<T> originalModel;
+
+ private ExtendedDataModel modifiedModel;
+
+ private String var;
+
+ private List<FilterField> filterFields;
+ private List<SortField2> sortFields;
+
+ /**
+ * @param originalModel
+ * @param var
+ * @param filterFields
+ * @param sortFields
+ */
+ public ExtendedDataTableModifiableModel(ExtendedTableDataModel<T> originalModel,
+ String var, List<FilterField> filterFields,
+ List<SortField2> sortFields) {
+ this.originalModel = originalModel;
+ this.delegate = originalModel;
+ this.var = var;
+ this.filterFields = filterFields;
+ this.sortFields = sortFields;
+ }
+
+ public void addDataModelListener(DataModelListener listener) {
+ originalModel.addDataModelListener(listener);
+ }
+
+ public DataModelListener[] getDataModelListeners() {
+ return originalModel.getDataModelListeners();
+ }
+
+ public int getRowCount() {
+ return delegate.getRowCount();
+ }
+
+ public Object getRowData() {
+ return delegate.getRowData();
+ }
+
+ public int getRowIndex() {
+ return delegate.getRowIndex();
+ }
+
+ public Object getRowKey() {
+ return delegate.getRowKey();
+ }
+
+ public SerializableDataModel getSerializableModel(Range range) {
+ return delegate.getSerializableModel(range);
+ }
+
+ public Object getWrappedData() {
+ return delegate.getWrappedData();
+ }
+
+ public boolean isRowAvailable() {
+ return delegate.isRowAvailable();
+ }
+
+ public void removeDataModelListener(DataModelListener listener) {
+ delegate.removeDataModelListener(listener);
+ }
+
+ public void setRowIndex(int rowIndex) {
+ delegate.setRowIndex(rowIndex);
+ }
+
+ public void setRowKey(Object key) {
+ delegate.setRowKey(key);
+ }
+
+ public void setWrappedData(Object data) {
+ delegate.setWrappedData(data);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void walk(FacesContext context, DataVisitor visitor, Range range,
+ Object argument) throws IOException {
+
+ if (shouldSort() || shouldFilter()) {
+ if (modifiedModel == null) {
+ modifiedModel = new
ExtendedTableDataModelWrapper<T>(originalModel.getDataProvider(), (List<T>)
prepareCollection());
+ }
+ delegate = modifiedModel;
+ } else {
+ delegate = originalModel;
+ }
+
+ delegate.walk(context, visitor, range, argument);
+ }
+
+ private boolean shouldSort() {
+ return sortFields != null && !sortFields.isEmpty();
+ }
+
+ private boolean shouldFilter() {
+ return filterFields != null && !filterFields.isEmpty();
+ }
+
+ private List<?> prepareCollection() {
+ int rowCount = originalModel.getRowCount();
+ final List<Object> collection;
+
+ if (rowCount > 0) {
+ collection = new ArrayList<Object>(rowCount);
+ } else {
+ collection = new ArrayList<Object>();
+ }
+
+ FacesContext context = FacesContext.getCurrentInstance();
+ try {
+
+ originalModel.walk(context, new DataVisitor() {
+ public void process(FacesContext context, Object rowKey,
+ Object argument) throws IOException {
+ originalModel.setRowKey(rowKey);
+ if (originalModel.isRowAvailable()) {
+ collection.add(originalModel.getRowData());
+ }
+ }
+ }, new SequenceRange(0, -1),
+ null);
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ }
+
+ List<Object> modifedcollection = collection;
+
+ if (shouldFilter()) {
+ List <Object> filteredCollection = new ArrayList<Object>();
+ ObjectWrapperFactory wrapperFactory = new ObjectWrapperFactory(
+ context, var, filterFields);
+ WrappedBeanFilter wrappedBeanFilter = new WrappedBeanFilter(filterFields);
+ wrapperFactory.wrapList(modifedcollection);
+ for (Object object : modifedcollection) {
+ if(wrappedBeanFilter.accept((JavaBeanWrapper)object)) {
+ filteredCollection.add(object);
+ }
+ }
+ modifedcollection = filteredCollection;
+ wrapperFactory.unwrapList(modifedcollection);
+ }
+
+ if (shouldSort()) {
+ ObjectWrapperFactory wrapperFactory = new ObjectWrapperFactory(
+ context, var, sortFields);
+ WrappedBeanComparator2 wrappedBeanComparator = new WrappedBeanComparator2(
+ sortFields);
+ wrapperFactory.wrapList(modifedcollection);
+ Collections.sort(modifedcollection, wrappedBeanComparator);
+ wrapperFactory.unwrapList(modifedcollection);
+ }
+ return modifedcollection;
+
+ }
+
+}
Added: trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedTableDataModel.java
===================================================================
--- trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedTableDataModel.java
(rev 0)
+++
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedTableDataModel.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,353 @@
+/**
+ *
+ */
+package org.richfaces.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.model.Range;
+import org.ajax4jsf.model.SequenceRange;
+import org.ajax4jsf.model.SerializableDataModel;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Data model class for table components.<br>
+ * Usage:
+ * <pre>
+ * G3TableDataModel<SomeDataType> dataModel = new
G3TableDataModel<SomeDataType>(new G3DataProvider
<SomeDataType>());
+ * </pre>
+ * @author pawelgo
+ *
+ */
+public class ExtendedTableDataModel<T> extends SerializableDataModel {
+
+// /**
+// * Cache container for data presented in data model.
+// * It prevents load the same data many times.
+// * @author pawelgo
+// *
+// * @param <T> data type
+// */
+// private static class DataCache<T> implements Serializable {
+// private static final long serialVersionUID = 8409239905346930920L;
+// private int startRow;
+// private int endRow;
+// //private SortOrder sortOrder;
+// private List<T> loadedData;
+//
+// public DataCache(int startRow, int endRow,
+// List<T> loadedData) {
+// super();
+// this.startRow = startRow;
+// this.endRow = endRow;
+// //this.sortOrder = deepCopy(sortOrder);
+// this.loadedData = loadedData;
+// }
+//
+// /**
+// * Returns a deep copy of an object
+// */
+// @SuppressWarnings("unused")
+// private SortOrder deepCopy(SortOrder sortOrder) {
+// if (sortOrder == null)
+// return null;
+// SortOrder order = new SortOrder();
+// if (sortOrder.getFields() != null) {
+// SortField[] fields = new SortField[sortOrder.getFields().length];
+// for (int i = 0; i < sortOrder.getFields().length; i++) {
+// SortField f = sortOrder.getFields()[i];
+// fields[i] = new SortField(f.getName(), f.getIndex(), f
+// .getAscending());
+// }//for
+// order.setFields(fields);
+// }//if
+// return order;
+// }//deepCopy
+//
+// /**
+// * Returns a deep copy of an object using serialization.
+// */
+// static public Object deepCopy(Object oldObj) throws Exception {
+// ObjectOutputStream oos = null;
+// ObjectInputStream ois = null;
+// try {
+// ByteArrayOutputStream bos = new ByteArrayOutputStream();
+// oos = new ObjectOutputStream(bos);
+// // serialize and pass the object
+// oos.writeObject(oldObj);
+// oos.flush();
+// ByteArrayInputStream bin = new ByteArrayInputStream(bos
+// .toByteArray());
+// ois = new ObjectInputStream(bin);
+// // return the new object
+// return ois.readObject();
+// } catch (Exception e) {
+// if (log.isErrorEnabled())
+// log.error("Exception in ObjectCloner = " + e);
+// throw (e);
+// } finally {
+// oos.close();
+// ois.close();
+// }
+// }//deepCopy
+//
+// public boolean match(int s, int e) {
+// return s == startRow && e == endRow;
+// //&& sortOrdersMatch(sortOrder, this.sortOrder);
+// }//match
+//
+// @SuppressWarnings("unused")
+// private boolean sortOrdersMatch(SortOrder sortOrder1,
+// SortOrder sortOrder2) {
+// boolean result = sortOrder1 == sortOrder2;
+//
+// if (sortOrder1 != null && sortOrder2 != null) {
+// result = sortOrder1.equals(sortOrder2);
+// }
+//
+// return result;
+// }//sortOrdersMatch
+//
+// }//DataCache
+
+ private static final long serialVersionUID = 7374505108088114161L;
+
+ private static final Log log = LogFactory.getLog(ExtendedTableDataModel.class);
+
+ private DataProvider<T> dataProvider;
+ private Object rowKey;
+ //private Map<Object,T> wrappedData = new HashMap<Object,T>();
+ private List<Object> wrappedKeys = null;
+ private boolean detached = false;
+ private Map<Object, T> wrappedData = new HashMap<Object, T>();
+
+ //private DataCache<T> dataCache;
+
+ public ExtendedTableDataModel(DataProvider<T> dataProvider) {
+ this.dataProvider = dataProvider;
+ }
+
+ /* (non-Javadoc)
+ * @see org.ajax4jsf.model.SerializableDataModel#update()
+ */
+ public void update() {
+ ;
+ }
+
+ /**
+ * This method never called from framework.
+ * (non-Javadoc)
+ * @see org.ajax4jsf.model.ExtendedDataModel#getRowKey()
+ */
+ public Object getRowKey() {
+ return rowKey;
+ }
+
+ /**
+ * This method normally called by Visitor before request Data Row.
+ * (non-Javadoc)
+ * @see org.ajax4jsf.model.ExtendedDataModel#setRowKey(java.lang.Object)
+ */
+ public void setRowKey(Object key) {
+ rowKey = key;
+ }
+
+ /**
+ * This is main part of Visitor pattern. Method called by framework many times during
request processing.
+ * (non-Javadoc)
+ * @see org.ajax4jsf.model.ExtendedDataModel#walk(javax.faces.context.FacesContext,
org.ajax4jsf.model.DataVisitor, org.ajax4jsf.model.Range, java.lang.Object)
+ */
+ public void walk(FacesContext context, DataVisitor visitor, Range range,
+ Object argument) throws IOException {
+ int rowC = getRowCount();
+ int firstRow = ((SequenceRange) range).getFirstRow();
+ int numberOfRows = ((SequenceRange) range).getRows();
+ if (numberOfRows <= 0) {
+ numberOfRows = rowC;
+ }
+ if (detached) { // Is this serialized model
+ // Here we just ignore current Rage and use whatever data was saved in serialized
model.
+ // Such approach uses much more getByPk() operations, instead of just one request by
range.
+ // Concrete case may be different from that, so you can just load data from data
provider by range.
+ // We are using wrappedKeys list only to preserve actual order of items.
+ for (Object key : wrappedKeys) {
+ setRowKey(key);
+ visitor.process(context, key, argument);
+ }
+ } else { // if not serialized, than we request data from data provider
+ wrappedKeys = new ArrayList<Object>();
+ int endRow = firstRow + numberOfRows;
+ if (endRow > rowC){
+ endRow = rowC;
+ }
+ for (T item : loadData(firstRow, endRow)) {
+ Object key = getKey(item);
+ wrappedKeys.add(key);
+ wrappedData.put(key, item);
+ visitor.process(context, key, argument);
+ }
+ }
+ }//walk
+
+ /**
+ * Load range of data items from the source.
+ * Starting from startRow, and up to but excluding endRow
+ * @param startRow
+ * @param endRow
+ * @return list of ordered data
+ */
+ protected List<T> loadData(int startRow, int endRow) {
+ if (log.isDebugEnabled())
+ log.debug("load data from range: " + startRow + " - " + endRow);
+ if (startRow < 0){
+ startRow = 0;
+ throw new IllegalArgumentException("Illegal start index value: " +
startRow);
+ }
+ int rowCount = getRowCount();
+ if (endRow > rowCount){
+ endRow = rowCount;
+ throw new IllegalArgumentException("Illegal end index value: " + endRow);
+ }
+ /*
+ if (dataCache == null || !dataCache.match(startRow, endRow)) {
+ if (log.isDebugEnabled())
+ log.debug("load and store in cache");
+ List<T> data = dataProvider.getItemsByRange(startRow, endRow);
+ dataCache = new DataCache<T>(startRow, endRow, data);
+ }
+ return dataCache.loadedData;
+ */
+ //load all from provider and get sublist
+ return dataProvider.getItemsByRange(0, rowCount).subList(startRow, endRow);
+ }//loadData
+
+ /**
+ * This method must return actual data rows count from the Data Provider. It is used by
pagination control
+ * to determine total number of data items.
+ * (non-Javadoc)
+ * @see javax.faces.model.DataModel#getRowCount()
+ */
+ private Integer rowCount; // better to buffer row count locally
+
+ public int getRowCount() {
+ if (rowCount == null) {
+ rowCount = new Integer(dataProvider.getRowCount());
+ } else {
+ return rowCount.intValue();
+ }
+ return rowCount.intValue();
+ //return dataProvider.getRowCount();
+ }
+
+ /**
+ * This is main way to obtain data row. It is intensively used by framework.
+ * We strongly recommend use of local cache in that method.
+ * (non-Javadoc)
+ * @see javax.faces.model.DataModel#getRowData()
+ */
+ public T getRowData() {
+ if (rowKey == null) {
+ return null;
+ } else {
+ return getObjectByKey(rowKey);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object getKey(T o) {
+ return dataProvider.getKey(o);
+ }
+
+ public T getObjectByKey(Object key) {
+ T t = wrappedData.get(key);
+ if (t == null){
+ t = dataProvider.getItemByKey(key);
+ wrappedData.put(key, t);
+ }
+ return t;
+ }
+
+ private Integer rowIndex;
+
+ /**
+ * Unused rudiment from old JSF staff. (non-Javadoc)
+ *
+ * @see javax.faces.model.DataModel#getRowIndex()
+ */
+ public int getRowIndex() {
+ //throw new UnsupportedOperationException();
+ return rowIndex.intValue();
+ }
+
+ /**
+ * Unused rudiment from old JSF staff.
+ * (non-Javadoc)
+ * @see javax.faces.model.DataModel#setRowIndex(int)
+ */
+ public void setRowIndex(int rowIndex) {
+ //throw new UnsupportedOperationException();
+ this.rowIndex = rowIndex;
+ }
+
+ /**
+ * Unused rudiment from old JSF staff.
+ * (non-Javadoc)
+ * @see javax.faces.model.DataModel#getWrappedData()
+ */
+ public Object getWrappedData() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Unused rudiment from old JSF staff.
+ * (non-Javadoc)
+ * @see javax.faces.model.DataModel#setWrappedData(java.lang.Object)
+ */
+ public void setWrappedData(Object data) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Never called by framework.
+ * (non-Javadoc)
+ * @see javax.faces.model.DataModel#isRowAvailable()
+ */
+ public boolean isRowAvailable() {
+ return getRowData() != null;
+ }
+
+ /**
+ * This method suppose to produce SerializableDataModel that will be
+ * serialized into View State and used on a post-back. In current
+ * implementation we just mark current model as serialized. In more
+ * complicated cases we may need to transform data to actually serialized
+ * form.
+ */
+ public SerializableDataModel getSerializableModel(Range range) {
+ if (wrappedKeys != null) {
+ detached = true;
+ // Some activity to detach persistent data from wrappedData map may be taken here.
+ // In that specific case we are doing nothing.
+ return this;
+ } else {
+ return null;
+ }
+ }
+
+ public DataProvider<T> getDataProvider() {
+ return dataProvider;
+ }
+
+ public void setDataProvider(DataProvider<T> dataProvider) {
+ this.dataProvider = dataProvider;
+ }
+
+}
Added:
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedTableDataModelWrapper.java
===================================================================
---
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedTableDataModelWrapper.java
(rev 0)
+++
trunk/sandbox/api/src/main/java/org/richfaces/model/ExtendedTableDataModelWrapper.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,40 @@
+/**
+ *
+ */
+package org.richfaces.model;
+
+import java.util.List;
+
+/**
+ * @author pawelgo
+ *
+ */
+public class ExtendedTableDataModelWrapper<T> extends
ExtendedTableDataModel<T> {
+
+ private static final long serialVersionUID = 6932958007982793632L;
+
+ protected List<T> wrappedList;
+
+ /**
+ *
+ * @param dataProvider
+ * @param wrappedList
+ */
+ public ExtendedTableDataModelWrapper(DataProvider<T> dataProvider, List<T>
wrappedList) {
+ super(dataProvider);
+ this.wrappedList = wrappedList;
+ }
+
+ protected List<T> loadData(int startRow, int endRow) {
+ //return super.loadData(startRow, endRow);
+ return wrappedList.subList(startRow, endRow);
+ }
+
+ public int getRowCount() {
+ return wrappedList.size();
+ }
+
+
+
+
+}
Added:
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages.properties
===================================================================
---
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages.properties
(rev 0)
+++
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages.properties 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,10 @@
+# components
+org.richfaces.component.UIExtendedDataTable.Menu.Columns=Columns de
+org.richfaces.component.UIExtendedDataTable.Menu.SortAscending=Sort Ascending de
+org.richfaces.component.UIExtendedDataTable.Menu.SortDescending=Sort Descending de
+org.richfaces.component.UIExtendedDataTable.Menu.GroupByColumn=Group by this column de
+org.richfaces.component.UIExtendedDataTable.Menu.DisableGrouping=Disable Grouping de
+
+# converters
+
+# validators
Added:
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_de.properties
===================================================================
---
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_de.properties
(rev 0)
+++
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_de.properties 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,10 @@
+# components
+org.richfaces.component.UIExtendedDataTable.Menu.Columns=Columns de
+org.richfaces.component.UIExtendedDataTable.Menu.SortAscending=Sort Ascending de
+org.richfaces.component.UIExtendedDataTable.Menu.SortDescending=Sort Descending de
+org.richfaces.component.UIExtendedDataTable.Menu.GroupByColumn=Group by this column de
+org.richfaces.component.UIExtendedDataTable.Menu.DisableGrouping=Disable Grouping de
+
+# converters
+
+# validators
Added:
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_en.properties
===================================================================
---
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_en.properties
(rev 0)
+++
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_en.properties 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,10 @@
+# components
+org.richfaces.component.UIExtendedDataTable.Menu.Columns=Columns
+org.richfaces.component.UIExtendedDataTable.Menu.SortAscending=Sort Ascending
+org.richfaces.component.UIExtendedDataTable.Menu.SortDescending=Sort Descending
+org.richfaces.component.UIExtendedDataTable.Menu.GroupByColumn=Group by this column
+org.richfaces.component.UIExtendedDataTable.Menu.DisableGrouping=Disable Grouping
+
+# converters
+
+# validators
Added:
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_pl.properties
===================================================================
---
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_pl.properties
(rev 0)
+++
trunk/sandbox/api/src/main/resources/org/richfaces/sandbox/messages/Messages_pl.properties 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,10 @@
+# components
+org.richfaces.component.UIExtendedDataTable.Menu.Columns=Kolumny
+org.richfaces.component.UIExtendedDataTable.Menu.SortAscending=Sortuj Rosn\u0105co
+org.richfaces.component.UIExtendedDataTable.Menu.SortDescending=Sortuj malej\u0105co
+org.richfaces.component.UIExtendedDataTable.Menu.GroupByColumn=Grupuj po kolumnie
+org.richfaces.component.UIExtendedDataTable.Menu.DisableGrouping=Wy\u0142\u0105cz
grupowanie
+
+# converters
+
+# validators
Modified: trunk/sandbox/impl/pom.xml
===================================================================
--- trunk/sandbox/impl/pom.xml 2008-06-19 17:13:04 UTC (rev 9120)
+++ trunk/sandbox/impl/pom.xml 2008-06-19 19:21:31 UTC (rev 9121)
@@ -25,7 +25,12 @@
<artifactId>richfaces-test</artifactId>
<version>3.2.2-SNAPSHOT</version>
</dependency>
-
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>1.2_07</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
Added:
trunk/sandbox/impl/src/main/java/org/richfaces/component/util/SandboxMessageUtil.java
===================================================================
--- trunk/sandbox/impl/src/main/java/org/richfaces/component/util/SandboxMessageUtil.java
(rev 0)
+++
trunk/sandbox/impl/src/main/java/org/richfaces/component/util/SandboxMessageUtil.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,16 @@
+package org.richfaces.component.util;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+
+
+public class SandboxMessageUtil extends AbstractMessageUtil {
+
+ private static final String MESSAGE_BUNDLE_NAME =
"org.richfaces.sandbox.messages.Messages";
+
+ public static final FacesMessage getMessage(FacesContext context, String messageId,
+ Object[] parameters) {
+
+ return AbstractMessageUtil.getMessage(context, messageId, parameters,
MESSAGE_BUNDLE_NAME);
+ }
+}
Added: trunk/sandbox/ui/extendedDataTable/generatescript.xml
===================================================================
--- trunk/sandbox/ui/extendedDataTable/generatescript.xml (rev 0)
+++ trunk/sandbox/ui/extendedDataTable/generatescript.xml 2008-06-19 19:21:31 UTC (rev
9121)
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!-- ======================================================================
+ 12.11.2005 23:40:43
+
+ assemblescripts
+ Assemble all javaScript library files to one extended-data-table.js
+
+ maksim
+
+ ====================================================================== -->
+
+<project name="assemblescripts" default="merge-scripts">
+
+ <description>
+ Assemble all javaScript library files to one extended-data-table.js
+ </description>
+
+ <target name="merge-scripts-eclipse-3.3">
+ <property name="script-path"
value="org/richfaces/renderkit/html/scripts"></property>
+ <property name="gen-script-name"
value="extended-data-table.js"></property>
+ <property name="gen-script-full-name"
value="${target-dir}/${script-path}/${gen-script-name}"></property>
+ <concat append="false" binary="false"
destfile="${gen-script-full-name}">
+ <filelist dir="${resources-dir}">
+ <file name="${resources-dir}/ClientUILib.js"/>
+ <file name="${resources-dir}/ClientUI/common/utils/Utils.js"/>
+ <file
name="${resources-dir}/ClientUI/common/utils/StringBuilder.js"/>
+ <file
name="${resources-dir}/ClientUI/common/utils/Validators.js"/>
+ <file name="${resources-dir}/ClientUI/common/box/Box.js"/>
+ <file
name="${resources-dir}/ClientUI/controls/datatable/ExtendedDataTable.js"/>
+ <file
name="${resources-dir}/ClientUI/controls/datatable/ExtendedDataTableHeader.js"/>
+ <file
name="${resources-dir}/ClientUI/controls/datatable/ExtendedDataTableSelection.js"/>
+ </filelist>
+ </concat>
+ </target>
+
+
+ <target name="merge-scripts">
+ <property name="script-path"
value="org/richfaces/renderkit/html/scripts"></property>
+ <property name="gen-script-name"
value="extended-data-table.js"></property>
+ <property name="gen-script-full-name"
value="${target-dir}/${script-path}/${gen-script-name}"></property>
+ <concat append="false" binary="false"
destfile="${gen-script-full-name}">
+ <filelist dir="${resources-dir}">
+ <file name="ClientUILib.js"/>
+ <file name="/ClientUI/common/utils/Utils.js"/>
+ <file name="/ClientUI/common/utils/StringBuilder.js"/>
+ <file name="/ClientUI/common/utils/Validators.js"/>
+ <file name="/ClientUI/common/box/Box.js"/>
+ <file name="/ClientUI/controls/dataTable/ExtendedDataTable.js"/>
+ <file
name="/ClientUI/controls/datatable/ExtendedDataTableHeader.js"/>
+ <file
name="/ClientUI/controls/datatable/ExtendedDataTableSelection.js"/>
+ </filelist>
+ </concat>
+ </target>
+</project>
+
Added: trunk/sandbox/ui/extendedDataTable/pom.xml
===================================================================
--- trunk/sandbox/ui/extendedDataTable/pom.xml (rev 0)
+++ trunk/sandbox/ui/extendedDataTable/pom.xml 2008-06-19 19:21:31 UTC (rev 9121)
@@ -0,0 +1,80 @@
+<?xml version="1.0"?><project>
+ <parent>
+ <artifactId>ui</artifactId>
+ <groupId>org.richfaces.sandbox</groupId>
+ <version>3.2.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces.sandbox.ui</groupId>
+ <artifactId>extendedDataTable</artifactId>
+ <name>extendedDataTable</name>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.richfaces.cdk</groupId>
+ <artifactId>maven-cdk-plugin</artifactId>
+ <version>3.2.2-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <library>
+ <prefix>org.richfaces.sandbox</prefix>
+ <taglib>
+ <shortName>extendedDataTable</shortName>
+ </taglib>
+ </library>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <tasks>
+ <ant antfile="${basedir}/generatescript.xml"
inheritRefs="true">
+ <target name="merge-scripts" />
+ <property name="target-dir"
value="${project.build.directory}/classes">
+ </property>
+ <property name="resources-dir"
value="${basedir}/src/main/javascript">
+ </property>
+ </ant>
+ </tasks>
+ <resourceRoot>
+ ${project.build.directory}/generated-component/resources
+ </resourceRoot>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ <version>3.2.2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ <version>3.2.2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.sandbox</groupId>
+ <artifactId>richfaces-sandbox-api</artifactId>
+ <version>3.2.2-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
Added: trunk/sandbox/ui/extendedDataTable/src/main/config/component/ExtendedDataTable.xml
===================================================================
--- trunk/sandbox/ui/extendedDataTable/src/main/config/component/ExtendedDataTable.xml
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/config/component/ExtendedDataTable.xml 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
"http://labs.jboss.com/jbossrichfaces/component-config.dtd">
+<components>
+ <component>
+ <name>org.richfaces.ExtendedDataTable</name>
+ <family>org.richfaces.ExtendedDataTable</family>
+ <classname>org.richfaces.component.html.HtmlExtendedDataTable</classname>
+ <superclass>org.richfaces.component.UIExtendedDataTable</superclass>
+ <description>
+ <![CDATA[
+ ]]>
+ </description>
+ <renderer generate="true" override="true">
+ <name>org.richfaces.ExtendedDataTableRenderer</name>
+ <template>org/richfaces/htmlExtendedDataTable.jspx</template>
+ </renderer>
+ <tag>
+ <name>extendedDataTable</name>
+ <classname>org.richfaces.taglib.ExtendedDataTableTag</classname>
+ <superclass>
+ org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
+ </superclass>
+ </tag>
+ <!--
+ <taghandler>
+ <classname>org.ajax4jsf.tag.TestHandler</classname>
+ </taghandler>
+ -->
+ &ui_component_attributes;
+ &ui_data_attributes;
+ &html_universal_attributes;
+ &html_table_attributes;
+ &html_events;
+ &spec_table_attributes;
+ <property>
+ <name>onselectionchange</name>
+ <classname>java.lang.String</classname>
+ <description>
+ HTML: script expression to invoke on changing of rows selection
+ </description>
+ </property>
+ <property>
+ <name>selectionMode</name>
+ <classname>java.lang.String</classname>
+ <description>
+ single [default]: Single row can be selected.
+ multi: Multiple rows can be selected.
+ none: no rows can be selected.
+ </description>
+ <defaultvalue>
+ "single"
+ </defaultvalue>
+ </property>
+ <property>
+ <name>height</name>
+ <classname>java.lang.String</classname>
+ <description>Defines a height of the component. Default value is
500px</description>
+ <defaultvalue>"500px"</defaultvalue>
+ </property>
+ <property>
+ <name>selectedClass</name>
+ <classname>java.lang.String</classname>
+ <description>
+ CSS class for selected rows
+ </description>
+ </property>
+ <property>
+ <name>activeClass</name>
+ <classname>java.lang.String</classname>
+ <description>
+ CSS class for active row
+ </description>
+ </property>
+
+ <property>
+ <name>ajaxKeys</name>
+ <classname>java.util.Set</classname>
+ <description>This attribute defines row keys that are updated after an AJAX
request</description>
+ </property>
+ <property>
+ <name>border</name>
+ <classname>java.lang.String</classname>
+ <description>This attributes specifies the width of the frame around a
component</description>
+ <defaultvalue>"0"</defaultvalue>
+ </property>
+ <property>
+ <name>height</name>
+ <classname>java.lang.String</classname>
+ <description>This attributes specifies the height of the
component</description>
+ <defaultvalue>"500"</defaultvalue>
+ </property>
+ <property>
+ <name>cellpadding</name>
+ <classname>java.lang.String</classname>
+ <description>This attribute specifies the amount of space between the border of
the cell and its contents</description>
+ <defaultvalue>"0"</defaultvalue>
+ </property>
+ <property>
+ <name>cellspacing</name>
+ <classname>java.lang.String</classname>
+ <description>This attribute specifies the amount of space between the border of
the cell and its contents. The attribute also specifies the amount of space to leave
between cells
+ </description>
+ <defaultvalue>"0"</defaultvalue>
+ </property>
+ <property>
+ <name>captionClass</name>
+ <classname>java.lang.String</classname>
+ <description>Space-separated list of CSS style class(es) that are be applied to
caption for this component</description>
+ <defaultvalue>""</defaultvalue>
+ </property>
+ <property>
+ <name>captionStyle</name>
+ <classname>java.lang.String</classname>
+ <description>CSS style(s) is/are to be applied to caption when this component is
rendered</description>
+ </property>
+ <property>
+ <name>headerClass</name>
+ <classname>java.lang.String</classname>
+ <description>Space-separated list of CSS style class(es) that are be applied to
header for this component
+ </description>
+ <defaultvalue>""</defaultvalue>
+ </property>
+ <property>
+ <name>footerClass</name>
+ <classname>java.lang.String</classname>
+ <description>Space-separated list of CSS style class(es) that are be applied to
footer for this component
+ </description>
+ <defaultvalue>""</defaultvalue>
+ </property>
+
+ <property>
+ <name>componentState</name>
+ <classname>org.ajax4jsf.model.DataComponentState</classname>
+ <description>It defines EL-binding for a component state for saving or
redefinition</description>
+ </property>
+ <property hidden="true" existintag="false"
exist="false" >
+ <name>rowKey</name>
+ <classname>java.lang.Object</classname>
+ <description>
+ RowKey is a representation of an identifier for a specific data row
+ </description>
+ </property>
+ <property>
+ <name>rowKeyVar</name>
+ <classname>java.lang.String</classname>
+ <description>The attribute provides access to a row key in a Request
scope</description>
+ </property>
+ <property>
+ <name>stateVar</name>
+ <classname>java.lang.String</classname>
+ <description>
+ The attribute provides access to a component state on the client side
+ </description>
+ </property>
+ <property>
+ <name>value</name>
+ <classname>java.lang.Object</classname>
+ <description>
+ The current value for this component
+ </description>
+ </property>
+ <!-- rows javascript events -->
+ <property>
+ <name>onRowClick</name>
+ <classname>java.lang.String</classname>
+ <description>
+ HTML: a script expression; a pointer button is clicked on row
+ </description>
+ </property>
+ <property>
+ <name>onRowDblClick</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: a script expression; a pointer button is double-clicked on
row
+ </description>
+ </property>
+ <property>
+ <name>onRowMouseUp</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: script expression; a pointer button is released on row
+ </description>
+ </property>
+ <property>
+ <name>onRowMouseDown</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: script expression; a pointer button is pressed down on row
+ </description>
+ </property>
+ <property>
+ <name>onRowMouseOver</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: a script expression; a pointer is moved onto of row
+ </description>
+ </property>
+ <property>
+ <name>onRowMouseOut</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: a script expression; a pointer is moved away of row
+ </description>
+ </property>
+ <property>
+ <name>onRowMouseMove</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: a script expression; a pointer is moved within of row
+ </description>
+ </property>
+ <property>
+ <name>sortPriority</name>
+ <classname>java.util.Collection</classname>
+ <description>Defines a set of column ids in the order the columns could be
set</description>
+ </property>
+ <property hidden="true" existintag="false"
exist="false" >
+ <name>sortFields</name>
+ </property>
+ <property hidden="true" existintag="false"
exist="false" >
+ <name>filterFields</name>
+ </property>
+ <property>
+ <name>sortMode</name>
+ <classname>java.lang.String</classname>
+ <description>
+ Defines mode of sorting. Possible values are 'single' for sorting of one
column and 'multi' for some.
+ </description>
+ </property>
+ <property hidden="true" existintag="false"
exist="false" >
+ <name>summary</name>
+ <classname>java.lang.Object</classname>
+ </property>
+
+ <property elonly="true">
+ <name>tableState</name>
+ <classname>java.lang.String</classname>
+ <description>
+ ValueBinding pointing at a property of a String to hold table state
+ </description>
+ </property>
+
+ <property attachedstate="true" elonly="true">
+ <name>selection</name>
+ <classname>org.richfaces.model.selection.Selection</classname>
+ <description>Value binding representing selected rows</description>
+ </property>
+
+ </component>
+</components>
Added: trunk/sandbox/ui/extendedDataTable/src/main/config/component/README
===================================================================
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/ExtendedTableColumnsIterator.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/ExtendedTableColumnsIterator.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/ExtendedTableColumnsIterator.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,77 @@
+/**
+ *
+ */
+package org.richfaces.component;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.faces.component.UIComponent;
+
+import org.richfaces.component.UIColumn;
+
+/**
+ * Columns iterator that work exactly like org.richfaces.component.ColumnsIterator
+ * but raw type is {@link org.richfaces.component.UIColumn} instead of {@link
javax.faces.component.UIComponent}
+ * @see org.richfaces.component.ColumnsIterator
+ * @author pawelgo
+ *
+ */
+public class ExtendedTableColumnsIterator implements Iterator<UIColumn> {
+
+ protected Iterator<UIComponent> childrenIterator;
+ protected UIColumn next;
+ protected boolean initialized = false;
+
+ /**
+ * Creates iterator for table.
+ * @param dataTable table for which iterator is created
+ */
+ public ExtendedTableColumnsIterator(UIExtendedDataTable dataTable) {
+ super();
+ childrenIterator = dataTable.getChildren().iterator();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ if(!initialized){
+ next = nextColumn();
+ initialized = true;
+ }
+ return null != next;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Iterator#next()
+ */
+ public UIColumn next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ UIColumn result = next;
+ next = nextColumn();
+ return result;
+ }
+
+ protected UIColumn nextColumn(){
+ UIColumn nextColumn = null;
+ while (childrenIterator.hasNext()) {
+ UIComponent child = childrenIterator.next();
+ if(child instanceof UIColumn){
+ nextColumn = (UIColumn)child;
+ break;
+ }
+ }
+ return nextColumn;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Iterator#remove()
+ */
+ public void remove() {
+ throw new UnsupportedOperationException("Iterator is read-only");
+ }
+
+}
Added: trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/README
===================================================================
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/SortedColumnsIterator.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/SortedColumnsIterator.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/SortedColumnsIterator.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,26 @@
+/**
+ *
+ */
+package org.richfaces.component;
+
+/**
+ * Columns iterator that returns column in sort order.
+ *
+ * @see UIExtendedDataTable#getSortedChildren()
+ * @author pawelgo
+ *
+ */
+public class SortedColumnsIterator extends ExtendedTableColumnsIterator {
+
+ /**
+ * Creates iterator for table.
+ *
+ * @param dataTable
+ * table for which iterator is created
+ */
+ public SortedColumnsIterator(UIExtendedDataTable dataTable) {
+ super(dataTable);
+ childrenIterator = dataTable.getSortedChildren().iterator();
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/UIExtendedDataTable.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/UIExtendedDataTable.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/UIExtendedDataTable.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,283 @@
+/**
+ *
+ */
+
+package org.richfaces.component;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.PhaseId;
+
+import org.ajax4jsf.event.AjaxEvent;
+import org.ajax4jsf.model.ExtendedDataModel;
+import org.richfaces.event.ChangeColumnVisibilityEvent;
+import org.richfaces.event.ColumnResizeEvent;
+import org.richfaces.event.DragDropEvent;
+import org.richfaces.model.ExtendedDataTableModifiableModel;
+import org.richfaces.model.ExtendedTableDataModel;
+import org.richfaces.model.FilterField;
+import org.richfaces.model.ModifiableModel;
+import org.richfaces.model.SortField2;
+
+/**
+ * JSF component class
+ *
+ */
+public abstract class UIExtendedDataTable extends UIDataTable implements
+ Selectable {
+
+ /**
+ * COMPONENT_TYPE
+ */
+ public static final String COMPONENT_TYPE =
"org.richfaces.ExtendedDataTable";
+
+ /**
+ * COMPONENT_FAMILY
+ */
+ public static final String COMPONENT_FAMILY =
"org.richfaces.ExtendedDataTable";
+
+ protected UIExtendedDataTableState state;
+
+ public abstract Object getActiveRowKey();
+
+ public abstract void setActiveRowKey(Object activeRowKey);
+
+ public void broadcast(FacesEvent event) throws AbortProcessingException {
+ super.broadcast(event);
+ if (event instanceof DragDropEvent) {
+ processDradDrop((DragDropEvent) event);
+ } else if (event instanceof ChangeColumnVisibilityEvent) {
+ processChangeColumnVisibility((ChangeColumnVisibilityEvent) event);
+ } else if (event instanceof ColumnResizeEvent) {
+ processColumnResize((ColumnResizeEvent) event);
+ }
+
+ }
+
+ public void queueEvent(FacesEvent event) {
+ if (event instanceof DragDropEvent) {
+ new AjaxEvent(this).queue();
+ event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
+ // event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
+ // new AjaxEvent(this).queue();
+ } else if (event instanceof ChangeColumnVisibilityEvent) {
+ new AjaxEvent(this).queue();
+ event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
+ } else if (event instanceof ColumnResizeEvent) {
+ new AjaxEvent(this).queue();
+ event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
+ }
+ super.queueEvent(event);
+ }
+
+ public Iterator<UIColumn> getSortedColumns() {
+ return new SortedColumnsIterator(this);
+ }
+
+ public Iterator<UIColumn> getChildColumns() {
+ return new ExtendedTableColumnsIterator(this);
+ }
+
+ public void processDradDrop(DragDropEvent event) {
+ String dragValue = event.getDragValue().toString();// dnd_drag_script
+ String dropValue = event.getDropValue().toString();// dnd_drop_script
+
+ ensureTableStateInitialized();
+ state.changeColumnsOrder(dragValue, dropValue, event.isDropBefore());
+ state.publishChanges(getFacesContext(), this);
+
+ getFacesContext().renderResponse();
+ }
+
+ public List<UIComponent> getSortedChildren() {
+ ensureTableStateInitialized();
+ return state.sortColumns(getFacesContext(), super.getChildren());
+ }
+
+ public void ensureTableStateInitialized() {
+ if (state == null) {
+ state = UIExtendedDataTableState.getUIExtendedDataTableState(this);
+ }
+ }
+
+ public void processChangeColumnVisibility(ChangeColumnVisibilityEvent event) {
+ ensureTableStateInitialized();
+ state.toggleColumnVisibility(this, event.getColumnId());
+ state.publishChanges(getFacesContext(), this);
+
+ getFacesContext().renderResponse();
+ }// processChangeColumnVisibility
+
+ public boolean isColumnVisible(UIComponent column) {
+ ensureTableStateInitialized();
+ return state.isColumnVisible(column.getId());
+ }// isColumnVisible
+
+ public void processColumnResize(ColumnResizeEvent event) {
+ ensureTableStateInitialized();
+ state.changeColumnSize(this, event.getColumnWidths());
+ state.publishChanges(getFacesContext(), this);
+
+ getFacesContext().renderResponse();
+ }// processChangeColumnVisibility
+
+ public String getColumnSize(UIComponent column) {
+ ensureTableStateInitialized();
+ return state.getColumnSize(column);
+ }
+
+ public boolean isGroupingOn() {
+ ensureTableStateInitialized();
+ return state.isGroupingOn();
+ }
+
+ public String getGroupingColumnId() {
+ ensureTableStateInitialized();
+ return state.getGroupingColumnId();
+ }
+
+ public UIColumn getGroupingColumn() {
+ String groupingColumnId = getGroupingColumnId();
+ if (groupingColumnId == null)
+ return null;
+ for (Iterator<UIColumn> columns = getChildColumns(); columns.hasNext();) {
+ UIColumn child = columns.next();
+ if (groupingColumnId.equalsIgnoreCase(child.getId())) {
+ return child;
+ }
+ }
+ return null;
+ }// getGroupingColumn
+
+ public void setGroupingColumn(org.richfaces.component.UIColumn column) {
+ ensureTableStateInitialized();
+ if (column == null) {
+ state.disableGrouping();
+ } else {
+ state.groupBy(column.getId(), column.getSortOrder());
+ }
+ state.publishChanges(getFacesContext(), this);
+ }
+
+ public void resetGroupVisibilityState() {
+ ensureTableStateInitialized();
+ state.resetGroupVisibilityState();
+ }
+
+ public void disableGrouping() {
+ ensureTableStateInitialized();
+ state.disableGrouping();
+ state.publishChanges(getFacesContext(), this);
+ }
+
+ public boolean groupIsExpanded(int index) {
+ ensureTableStateInitialized();
+ return state.groupIsExpanded(index);
+ }
+
+ public void toggleGroup(int index) {
+ ensureTableStateInitialized();
+ state.toggleGroup(index);
+ state.publishChanges(getFacesContext(), this);
+ }
+
+ public Collection<Object> getSortPriority() {
+ Collection<Object> priority = super.getSortPriority();
+ if (isGroupingOn()) {// grouping is on
+ String groupColId = getGroupingColumnId();
+ // try to add group column id as first
+ if (priority.contains(groupColId)) {
+ priority.remove(groupColId);
+ }
+ if (priority instanceof List) {
+ ((List<Object>) priority).add(0, groupColId);
+ } else {
+ priority.add(groupColId);
+ }
+ }
+ return priority;
+ }
+
+ public Object saveState(FacesContext context) {
+ Object values[] = new Object[2];
+ values[0] = super.saveState(context);
+ values[1] = state;
+ return values;
+ }
+
+ public void restoreState(FacesContext context, Object state) {
+ Object values[] = (Object[]) state;
+ super.restoreState(context, values[0]);
+ this.state = (UIExtendedDataTableState) values[1];
+ }
+
+ public int getVisibleColumnsCount() {
+ int count = 0;
+ for (Iterator<UIColumn> iter = getChildColumns(); iter.hasNext();) {
+ UIColumn column = iter.next();
+ if (column.isRendered())
+ count++;
+ }// for
+ return count;
+ }// getVisibleColumnnCount
+
+ @SuppressWarnings("unchecked")
+ protected ExtendedDataModel createDataModel() {
+ List<FilterField> filterFields = new LinkedList<FilterField>();
+ Map<String, SortField2> sortFieldsMap = new LinkedHashMap<String,
SortField2>();
+ List<UIComponent> list = getChildren();
+ for (Iterator<UIComponent> iterator = list.iterator(); iterator
+ .hasNext();) {
+ UIComponent component = iterator.next();
+ if (component instanceof org.richfaces.component.UIColumn) {
+ org.richfaces.component.UIColumn column =
(org.richfaces.component.UIColumn) component;
+ FilterField filterField = column.getFilterField();
+ if (filterField != null) {
+ filterFields.add(filterField);
+ }
+ SortField2 sortField = column.getSortField();
+ if (sortField != null) {
+ sortFieldsMap.put(component.getId(), sortField);
+ }
+ }
+
+ }
+ List<SortField2> sortFields = new LinkedList<SortField2>();
+ Collection<Object> sortPriority = getSortPriority();
+ if (sortPriority != null) {
+ for (Object object : sortPriority) {
+ if (object instanceof String) {
+ String id = (String) object;
+ SortField2 sortField = sortFieldsMap.get(id);
+ if (sortField != null) {
+ sortFields.add(sortField);
+ sortFieldsMap.remove(id);
+ }
+ }
+ }
+ }
+ sortFields.addAll(sortFieldsMap.values());
+ setFilterFields(filterFields);
+ setSortFields(sortFields);
+ ExtendedDataModel dataModel = (ExtendedDataModel) super.getDataModel();
+ if (dataModel instanceof ExtendedTableDataModel<?>) {
+ ExtendedTableDataModel<?> tableDataModel =
(ExtendedTableDataModel<?>) dataModel;
+ return new ExtendedDataTableModifiableModel(tableDataModel, getVar(),
+ getFilterFields(), getSortFields());
+ } else {
+ ModifiableModel modifiableModel = new ModifiableModel(dataModel, getVar());
+ modifiableModel.modify(getFilterFields(), getSortFields());
+
+ return modifiableModel;
+ }
+ }
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/UIExtendedDataTableState.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/UIExtendedDataTableState.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/component/UIExtendedDataTableState.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,700 @@
+/**
+ *
+ */
+package org.richfaces.component;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.el.ValueExpression;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+import org.richfaces.model.Ordering;
+
+/**
+ * @author pawelgo
+ *
+ */
+public class UIExtendedDataTableState implements Serializable {
+
+ private static final long serialVersionUID = -3103664821855261335L;
+
+ public static final String TABLE_STATE_ATTR_NAME = "tableState";
+
+ protected static final String SEP = ":";
+
+ protected ColumnsOrder columnsOrder;
+ protected ColumnsVisibility columnsVisibility;
+ protected ColumnsSizeState columnsSizeState;
+ protected ColumnGroupingState columnGroupingState;
+
+ public static UIExtendedDataTableState getUIExtendedDataTableState(UIExtendedDataTable
extendedDataTable){
+ UIExtendedDataTableState state = new UIExtendedDataTableState();
+ state.init(extendedDataTable);
+ return state;
+ }//init
+
+ /**
+ * Converts its state based on table attribute value or create default state if it is
not set.
+ */
+ protected void init(UIExtendedDataTable extendedDataTable){
+ //get state value from components attributes
+ String value = (String)extendedDataTable.getAttributes().get(TABLE_STATE_ATTR_NAME);
+ //split state value into parts
+ String[] values = fromString(value);
+ //initialize columns order part
+ String val = (values != null && values.length>0) ? values[0] : null;
+ columnsOrder = ColumnsOrder.getColumnsOrder(extendedDataTable, val);
+ //initialize columns visibility part
+ val = (values != null && values.length>1) ? values[1] : null;
+ columnsVisibility = ColumnsVisibility.getColumnsVisibility(extendedDataTable, val);
+ //initialize columns size part
+ val = (values != null && values.length>2) ? values[2] : null;
+ columnsSizeState = ColumnsSizeState.getColumnsSize(extendedDataTable, val);
+ //initialize column grouping part
+ val = (values != null && values.length>3) ? values[3] : null;
+ columnGroupingState = ColumnGroupingState.getColumnGropingState(extendedDataTable,
val);
+ }//init
+
+ /**
+ * Puts own state into component state.
+ */
+ public void publishChanges(FacesContext context, UIExtendedDataTable
extendedDataTable){
+ ValueExpression ve = extendedDataTable.getValueExpression(TABLE_STATE_ATTR_NAME);
+ if ((null != ve) && (!ve.isReadOnly(context.getELContext()))) {
+ ve.setValue(context.getELContext(), toString());
+ }
+ }//publishChanges
+
+ /**
+ * Converts its state to String representation.
+ */
+ public String toString(){
+ String[] values = new String[4];
+ values[0] = columnsOrder.toString();
+ values[1] = columnsVisibility.toString();
+ values[2] = columnsSizeState.toString();
+ values[3] = columnGroupingState.toString();
+ StringBuilder builder = new StringBuilder();
+ for (String str : values){
+ builder.append(str).append(SEP);
+ }//for
+ return builder.toString();
+ }//toString
+
+ public String[] fromString(String value){
+ return (value == null) ? null : value.split(SEP);
+ }//fromString
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnsOrder#changeOrder(String, String)
+ */
+ public void changeColumnsOrder(String sourceColumnId, String targetColumnId, boolean
dropBefore) {
+ columnsOrder.changeOrder(sourceColumnId, targetColumnId, dropBefore);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnsOrder#sortColumns(FacesContext, List)
+ */
+ public List<UIComponent> sortColumns(FacesContext context,
+ List<UIComponent> children) {
+ return columnsOrder.sortColumns(context, children);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnsVisibility#isVisible(String)
+ */
+ public boolean isColumnVisible(String columnId) {
+ return columnsVisibility.isVisible(columnId);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnsVisibility#toggleVisibility(UIExtendedDataTable, String)
+ */
+ public void toggleColumnVisibility(UIExtendedDataTable extendedDataTable,
+ String columnId) {
+ columnsVisibility.toggleVisibility(extendedDataTable, columnId);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnsSizeState#changeColumnSize(UIExtendedDataTable, String)
+ */
+ public void changeColumnSize(UIExtendedDataTable extendedDataTable,
+ String newValue) {
+ columnsSizeState.changeColumnSize(extendedDataTable, newValue);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnsSizeState#getColumnSize(UIComponent)
+ */
+ public String getColumnSize(UIComponent column) {
+ return columnsSizeState.getColumnSize(column);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnGroupingState#isGroupingOn()
+ */
+ public boolean isGroupingOn(){
+ return columnGroupingState.isGroupingOn();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnGroupingState#getGroupingColumnId()
+ */
+ public String getGroupingColumnId(){
+ return columnGroupingState.getGroupingColumnId();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnGroupingState#groupBy(String, Ordering)
+ */
+ public void groupBy(String colId, Ordering ordering) {
+ columnGroupingState.groupBy(colId, ordering);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnGroupingState#resetGroupVisibilityState()
+ */
+ public void resetGroupVisibilityState(){
+ columnGroupingState.resetGroupVisibilityState();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnGroupingState#disableGrouping()
+ */
+ public void disableGrouping(){
+ columnGroupingState.disableGrouping();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnGroupingState#groupIsExpanded(int)
+ */
+ public boolean groupIsExpanded(int index) {
+ return columnGroupingState.groupIsExpanded(index);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ColumnGroupingState#toggleGroup(int)
+ */
+ public void toggleGroup(int index) {
+ columnGroupingState.toggleGroup(index);
+ }
+
+
+}
+
+class ColumnsSizeState implements Serializable{
+
+ private static final long serialVersionUID = 8724163192351491340L;
+
+ private static final String SEP = ";";
+
+ private static final String DEFAULT_WIDTH = "100";
+
+ private String value;
+
+ private ColumnsSizeState() {
+ super();
+ }
+
+ static ColumnsSizeState getColumnsSize(UIExtendedDataTable extendedDataTable, String
val){
+ ColumnsSizeState columnsSize = new ColumnsSizeState();
+ columnsSize.init(extendedDataTable, val);
+ return columnsSize;
+ }
+
+ /**
+ * Converts its state from String representation or create default state if it is not
set.
+ */
+ private void init(UIExtendedDataTable extendedDataTable, String val){
+ value = val;
+ if ((value == null) || (value.length() == 0))
+ createDefaultColumnsSizeState(extendedDataTable);
+ }
+
+ /**
+ * Converts its state to String representation.
+ */
+ public String toString(){
+ return value;
+ }
+
+ /**
+ * Create default column order based on component children.
+ */
+ private void createDefaultColumnsSizeState(UIExtendedDataTable extendedDataTable){
+ StringBuilder builder = new StringBuilder();
+
+ for (Iterator<UIColumn> iter = extendedDataTable.getChildColumns();
iter.hasNext();) {
+ UIColumn col = iter.next();
+ builder.append(col.getId().toUpperCase()).append("-").append(getDefaultColumnSize(col)).append(SEP);
+ }
+ value = builder.toString();
+ }
+
+ private String getDefaultColumnSize(UIComponent column){
+ String widthStr = (String) column.getAttributes().get("width");
+ return formatWidth((widthStr == null || widthStr.length() == 0) ? DEFAULT_WIDTH :
widthStr);
+ }
+
+ public String getColumnSize(UIComponent column){
+ if (value == null)
+ return getDefaultColumnSize(column);
+ String[] widths = value.split(SEP);
+ if (widths != null){
+ String colId = column.getId().toUpperCase();
+ for (String val : widths){
+ if (val.toUpperCase().startsWith(colId+"-")){
+ return formatWidth(val.split("-")[1]);
+ }
+ }//for
+ }
+ return getDefaultColumnSize(column);
+ }
+
+ private String formatWidth(String value){
+ if(value.endsWith("px"))
+ return value.substring(0,value.indexOf("px"));
+ return value;
+ }
+
+ public void changeColumnSize(UIExtendedDataTable extendedDataTable, String newValue){
+ if (value == null)
+ return;
+ Set<String> widths = new
HashSet<String>(Arrays.asList(value.toUpperCase().split(SEP)));
+ String[] newWidths = newValue.split(";");
+ int index = 0;
+ for (Iterator<UIColumn> iter = extendedDataTable.getSortedColumns();
iter.hasNext();) {
+ UIComponent col = (UIComponent) iter.next();
+ if (col.isRendered()){
+ String colId = col.getId().toUpperCase();
+ //remove existing item
+ Set<String> toDel = new HashSet<String>();
+ for (String val : widths){
+ if (val.toUpperCase().startsWith(colId+"-")){
+ toDel.add(val);
+ }
+ }//for
+ widths.removeAll(toDel);
+ //create new item
+ String newWidth = newWidths[index++];
+ String item = colId + "-" + newWidth;;
+ widths.add(item);
+ }//if
+ }//for
+ //build new value
+ StringBuilder builder = new StringBuilder();
+ for (String val : widths){
+ builder.append(val).append(SEP);
+ }
+ value = builder.toString();
+ }//changeColumnSize
+
+}//ColumnsSizeState
+
+class ColumnsOrder implements Serializable{
+
+ private static final long serialVersionUID = 907700564445889954L;
+
+ private static final String SEP = ";";
+
+ private String value;
+
+ private ColumnsOrder() {
+ super();
+ }
+
+ static ColumnsOrder getColumnsOrder(UIExtendedDataTable extendedDataTable, String val){
+ ColumnsOrder columnsOrder = new ColumnsOrder();
+ columnsOrder.init(extendedDataTable, val);
+ return columnsOrder;
+ }
+
+ /**
+ * Converts its state from String representation or create default state if it is not
set.
+ */
+ private void init(UIExtendedDataTable extendedDataTable, String val){
+ value = val;
+ if ((value == null) || (value.length() == 0))
+ createDefaultColumnsOrder(extendedDataTable);
+ }
+
+ /**
+ * Converts its state to String representation.
+ */
+ public String toString(){
+ return value;
+ }
+
+ /**
+ * Create default column order based on component children.
+ */
+ private void createDefaultColumnsOrder(UIExtendedDataTable extendedDataTable){
+ StringBuilder builder = new StringBuilder();
+ for (Iterator<UIColumn> iter = extendedDataTable.getChildColumns();
iter.hasNext();) {
+ UIColumn child = iter.next();
+ builder.append(child.getId().toUpperCase()).append(SEP);
+ }
+ value = builder.toString();
+ }
+
+ /**
+ * Get column index in order.
+ * @param columnId column id to be found
+ * @return column index or null if not found
+ */
+ private Integer getColumnIndex(String columnId){
+ if (value == null)
+ return null;
+ List<String> list = Arrays.asList(value.toUpperCase().split(SEP));
+ if (list.contains(columnId.toUpperCase()))
+ return list.indexOf(columnId.toUpperCase());
+ return null;
+ }//getColumnIndex
+
+ /**
+ * Changes column order. Moves source column to be next to target column.
+ * @param sourceColumnId source column id to be moved
+ * @param targetColumnId target column id
+ * @param dropBefore
+ */
+ void changeOrder(String sourceColumnId, String targetColumnId, boolean dropBefore){
+ if (value == null)
+ return;
+ if (sourceColumnId.equals(targetColumnId))
+ return;
+ List<String> list = new
ArrayList<String>(Arrays.asList(value.toUpperCase().split(SEP)));
+ //get index of source column
+ int sourceIndex = list.indexOf(sourceColumnId.toUpperCase());
+ //remove from order if exist
+ if (sourceIndex != -1)
+ list.remove(sourceIndex);
+ //get index of target column
+ int targetIndex = list.indexOf(targetColumnId.toUpperCase());
+ //add source column after or before target column
+ if (targetIndex == -1)//add to end
+ list.add(sourceColumnId.toUpperCase());
+ else{
+ //add at proper position
+ list.add((targetIndex + (dropBefore ? 0 : 1)), sourceColumnId.toUpperCase());
+ }
+ //convert from List to String
+ StringBuilder builder = new StringBuilder();
+ for (String str : list)
+ builder.append(str).append(SEP);
+ value = builder.toString();
+ }
+
+ /**
+ * Sort column by given order.
+ * @param context faces context
+ * @param children list of unsorted columns
+ * @return list of sorted columns
+ */
+ List<UIComponent> sortColumns(final FacesContext context, List<UIComponent>
children){
+ List<UIComponent> childs = new ArrayList<UIComponent>(children);
+ Collections.sort(childs, new Comparator<UIComponent>() {
+ public int compare(UIComponent o1, UIComponent o2) {
+ Integer index1 = getColumnIndex(o1.getId());
+ Integer index2 = getColumnIndex(o2.getId());
+ if (index1 == null) {
+ return ((index2 == null) ? 0 : 1);
+ }
+ return ((index2 == null) ? -1 : index1.compareTo(index2));
+ }
+ });
+ return childs;
+ }
+
+}//ColumnsOrder
+
+class ColumnsVisibility implements Serializable{
+
+ private static final long serialVersionUID = -3923409650272094713L;
+
+ private static final String SEP = ";";
+
+ private String value;
+
+ private ColumnsVisibility() {
+ super();
+ }
+
+ static ColumnsVisibility getColumnsVisibility(UIExtendedDataTable extendedDataTable,
String val){
+ ColumnsVisibility columnsVisibility = new ColumnsVisibility();
+ columnsVisibility.init(extendedDataTable, val);
+ return columnsVisibility;
+ }
+
+ /**
+ * Converts its state from String representation or create default state if it is not
set.
+ */
+ private void init(UIExtendedDataTable extendedDataTable, String val){
+ value = val;
+ if ((value == null) || (value.length() == 0))
+ createDefaultColumnsVisibility(extendedDataTable);
+ //set visibility flag for all columns
+ for (Iterator<UIColumn> iter = extendedDataTable.getChildColumns();
iter.hasNext();) {
+ UIColumn child = iter.next();
+ if (child instanceof UIColumn) {
+ UIColumn dataColumn = (UIColumn) child;
+ dataColumn.setVisible(isVisible(dataColumn.getId()));
+ }//if
+ }//for
+ }//init
+
+ /**
+ * Converts its state to String representation.
+ */
+ public String toString(){
+ return value;
+ }
+
+ /**
+ * Create default column visibility based on component children.
+ */
+ private void createDefaultColumnsVisibility(UIExtendedDataTable extendedDataTable){
+ StringBuilder builder = new StringBuilder();
+ for (Iterator<UIColumn> iter = extendedDataTable.getChildColumns();
iter.hasNext();) {
+ UIColumn kid = iter.next();
+ builder.append(kid.getId().toUpperCase()).append(SEP);
+ }
+ value = builder.toString();
+ }//createDefaultColumnsVisibility
+
+ /**
+ * Get column visibility.
+ * @param columnId column id to be found
+ * @return true if column is visible, otherwise false
+ */
+ boolean isVisible(String columnId){
+ if (value == null)
+ return true;
+ Set<String> visibleIds = new
HashSet<String>(Arrays.asList(value.toUpperCase().split(SEP)));
+ return visibleIds.contains(columnId.toUpperCase());
+ }//isVisible
+
+ /**
+ * Toggle column visibility.
+ * @param extendedDataTable table component
+ * @param columnId column id
+ */
+ void toggleVisibility(UIExtendedDataTable extendedDataTable, String columnId){
+ if (value == null)
+ return;
+ UIColumn column = null;
+ //find column by id
+ for (Iterator<UIColumn> iter = extendedDataTable.getChildColumns();
iter.hasNext();) {
+ UIColumn col = iter.next();
+ if (col.getId().equalsIgnoreCase(columnId)){
+ if (col instanceof UIColumn){
+ column = (UIColumn) col;
+ }
+ break;
+ }//if
+ }//for
+ if (column == null)
+ return;
+ boolean visible = column.isVisible();
+ //toggle visibility
+ visible = !visible;
+ //set visibility flag for column
+ column.setVisible(visible);
+ Set<String> visibleIds = new
HashSet<String>(Arrays.asList(value.toUpperCase().split(SEP)));
+ if (visible){
+ //add id to set
+ visibleIds.add(columnId.toUpperCase());
+ }
+ else{
+ //remove id from list
+ visibleIds.remove(columnId.toUpperCase());
+ }
+ //convert from Set to String
+ StringBuilder builder = new StringBuilder();
+ for (String str : visibleIds)
+ builder.append(str).append(SEP);
+ value = builder.toString();
+ }//changeVisibility
+
+}//ColumnsVisibility
+
+class ColumnGroupingState implements Serializable{
+
+ private static final long serialVersionUID = -3923409650272094713L;
+
+ private static final String SEP = ";";
+ //private static final String TRUE = "1";
+ //private static final String FALSE = "0";
+ private static final Boolean DEF = Boolean.TRUE;//expanded
+
+ private String columnId;
+ private List<Boolean> groupExpanded;
+ private Ordering ordering;
+ //private String value;
+
+ private ColumnGroupingState() {
+ super();
+ }
+
+ static ColumnGroupingState getColumnGropingState(UIExtendedDataTable extendedDataTable,
String val){
+ ColumnGroupingState groupingState = new ColumnGroupingState();
+ groupingState.init(extendedDataTable, val);
+ return groupingState;
+ }
+
+ /**
+ * Converts its state from String representation or create default state if it is not
set.
+ */
+ private void init(UIExtendedDataTable extendedDataTable, String val){
+ columnId = null;
+ ordering = Ordering.UNSORTED;
+ groupExpanded = new ArrayList<Boolean>();
+ if ((val == null) || (val.length() == 0))
+ return;
+ List<String> tmp = Arrays.asList(val.split(SEP));
+ if (!tmp.isEmpty()){
+ columnId = tmp.get(0); //column id
+ ordering = Ordering.valueOf(tmp.get(1)); //sort order
+ if (ordering == null)
+ ordering = Ordering.UNSORTED;
+// tmp = tmp.subList(2, tmp.size());//remove fist and second item
+// for (String s : tmp){
+// groupExpanded.add(Boolean.valueOf(s.equals(TRUE)));
+// }//for
+ }
+ //get column by id and set sort order
+ for (Iterator<UIColumn> columns = extendedDataTable.getChildColumns();
columns.hasNext(); ){
+ UIColumn child = columns.next();
+ if (columnId.equalsIgnoreCase(child.getId())) {
+ child.setSortOrder(ordering);
+ break;
+ }
+ }
+ }//init
+
+ /**
+ * Converts its state to String representation.
+ */
+ public String toString(){
+ if (columnId == null)
+ return "";
+ StringBuilder builder = new StringBuilder();
+ builder.append(columnId).append(SEP); //add column id
+ builder.append(ordering).append(SEP); //add sort order
+// for (Boolean b : groupExpanded){
+// builder.append(b ? TRUE : FALSE).append(SEP);
+// }
+ return builder.toString();
+ }
+
+ /**
+ * Gets grouped column id.
+ * @return grouped column id if grouping is on, otherwise false
+ */
+ String getGroupingColumnId(){
+ return columnId;
+ }
+
+ /**
+ * Checks if grouping is on.
+ * @return true if grouping is on, otherwise false
+ */
+ boolean isGroupingOn(){
+ return (columnId != null);
+ }
+
+ /**
+ * Turn on grouping for column.
+ * @param colId id of column to be grouped
+ * @param ordering sort order
+ */
+ void groupBy(String colId, Ordering ordering){
+ columnId = colId;
+ this.ordering = ordering;
+ resetGroupVisibilityState();
+ }
+
+ /**
+ * Resets information about group visibility state.
+ * All group will be mark as expanded.
+ */
+ void resetGroupVisibilityState(){
+ groupExpanded.clear();
+ }
+
+ /**
+ * Turn off grouping.
+ */
+ void disableGrouping(){
+ columnId = null;
+ ordering = Ordering.UNSORTED;
+ resetGroupVisibilityState();
+ }
+
+ /**
+ * Toggle group. It means that group will be expanded if is collapsed
+ * and group will be collapsed if is expanded.
+ * @param index index of group to be toggled
+ */
+ void toggleGroup(int index){
+ if (index < 0)
+ throw new IllegalArgumentException("Illegal index value :"+index);
+ if (index >= groupExpanded.size()){
+ //add default values for lower indexes
+ int count = index - groupExpanded.size() + 1;
+ for (int i = 0; i < count; i++){
+ groupExpanded.add(DEF);
+ }///for
+ }
+ groupExpanded.add(index,!groupExpanded.remove(index));
+ }
+
+ /**
+ * Checks if group is expanded.
+ * @param index index of group to be tested
+ * @return true if group is expanded, otherwise false
+ */
+ boolean groupIsExpanded(int index){
+ if (index < 0)
+ throw new IllegalArgumentException("Illegal index value :"+index);
+ if (index >= groupExpanded.size()){
+ return DEF;
+ }
+ return groupExpanded.get(index).booleanValue();
+ }
+
+}//ColumnGroupingState
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/AbstractExtendedRowsRenderer.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/AbstractExtendedRowsRenderer.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/AbstractExtendedRowsRenderer.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,393 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces - 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.renderkit;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.ajax4jsf.component.SequenceDataAdaptor;
+import org.ajax4jsf.component.UIDataAdaptor;
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
+import org.ajax4jsf.renderkit.RendererUtils;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.ajax4jsf.resource.InternetResource;
+import org.richfaces.component.Row;
+import org.richfaces.renderkit.AbstractRowsRenderer;
+import org.richfaces.renderkit.CompositeRenderer;
+import org.richfaces.renderkit.RendererContributor;
+import org.richfaces.renderkit.ScriptOptions;
+import org.richfaces.renderkit.TableHolder;
+
+import org.richfaces.component.UIExtendedDataTable;
+import org.richfaces.renderkit.html.TableSelectionRendererContributor;
+
+/**
+ * @author shura
+ *
+ */
+public abstract class AbstractExtendedRowsRenderer extends
+ HeaderResourcesRendererBase implements DataVisitor {
+
+ protected static final String MENU_ID = "_TABLE_MENU_ID_";
+ protected boolean firstRow = true;
+
+ protected class CompositeRendererEnabler extends CompositeRenderer {
+ public CompositeRendererEnabler() {
+ addContributor(new TableSelectionRendererContributor());
+ }
+
+ protected Class<? extends UIComponent> getComponentClass() {
+ return AbstractExtendedRowsRenderer.this.getComponentClass();
+ }
+
+ public void mergeScriptOptions(ScriptOptions scriptOptions,
+ FacesContext context, UIComponent component) {
+ super.mergeScriptOptions(scriptOptions, context, component);
+
+ }
+
+ public String getScriptContributions(String varString,
+ FacesContext context, UIComponent component) {
+ return super.getScriptContributions(varString, context, component);
+ }
+
+ public RendererContributor[] getContributors() {
+ return super.getContributors();
+ }
+
+ public InternetResource[] getScripts() {
+ return super.getScripts();
+ }
+
+ public InternetResource[] getStyles() {
+ return super.getStyles();
+ }
+ }
+
+ public static final String[][] TABLE_EVENT_ATTRS = {
+ { "onclick", "onRowClick" }, { "ondblclick",
"onRowDblClick" },
+ { "onmousemove", "onRowMouseMove" },
+ { "onmouseup", "onRowMouseUp" },
+ { "onmousedown", "onRowMouseDown" },
+ { "onmouseover", "onRowMouseOver" },
+ { "onmouseout", "onRowMouseOut" } };
+
+ public static final String ROW_CLASS_KEY = AbstractRowsRenderer.class
+ .getName()
+ + ".rowClass";
+
+ public static final String SKIN_ROW_CLASS_KEY = AbstractRowsRenderer.class
+ .getName()
+ + ".skinRowClass";
+
+ public static final String CELL_CLASS_KEY = AbstractRowsRenderer.class
+ .getName()
+ + ".cellClass";
+
+ public static final String SKIN_CELL_CLASS_KEY = AbstractRowsRenderer.class
+ .getName()
+ + ".skinCellClass";
+
+ public static final String SKIN_FIRST_ROW_CLASS_KEY = AbstractRowsRenderer.class
+ .getName()
+ + ".firstRowSkinClass";
+
+ // protected TableMenuRenderer menuRenderer = new RichTableMenuRenderer();
+
+ protected CompositeRendererEnabler composite = new CompositeRendererEnabler();
+
+ // protected Object lastData = null;
+ // protected Object lastKey = null;
+ // TODO move this property to holder
+ // protected int groupIndex = -1;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
org.ajax4jsf.ajax.repeat.DataVisitor#process(javax.faces.context.FacesContext,
+ * java.lang.Object, java.lang.Object)
+ */
+ public void process(FacesContext context, Object rowKey, Object argument)
+ throws IOException {
+ ExtendedTableHolder holder = (ExtendedTableHolder) argument;
+ UIDataAdaptor table = holder.getTable();
+ if (holder.getLastKey() != null) {
+ table.setRowKey(context, holder.getLastKey());
+ holder.setLastData(table.getRowData());
+ }
+ holder.setLastKey(rowKey);
+ table.setRowKey(context, rowKey);
+ encodeOneRow(context, holder);
+ holder.nextRow();
+ }
+
+ public void encodeRows(FacesContext context, UIComponent component)
+ throws IOException {
+ encodeRows(context, component, new ExtendedTableHolder(
+ (UIExtendedDataTable) component));
+ }
+
+ /**
+ * Iterate over all rows for this table.
+ *
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ protected void encodeRows(FacesContext context, UIComponent component,
+ ExtendedTableHolder tableHolder) throws IOException {
+ this.firstRow = true;
+ UIDataAdaptor table = (UIDataAdaptor) component;
+ Object key = table.getRowKey();
+ table.captureOrigValue(context);
+ table.walk(context, this, tableHolder);
+ doCleanup(context, tableHolder);
+ table.setRowKey(key);
+ table.restoreOrigValue(context);
+ }
+
+ /**
+ * @param context
+ * TODO
+ * @param tableHolder
+ * @throws IOException
+ */
+ protected void doCleanup(FacesContext context, TableHolder tableHolder)
+ throws IOException {
+ // Hoock method for perform encoding after all rows is rendered
+
+ }
+
+ public abstract void encodeOneRow(FacesContext context,
+ ExtendedTableHolder holder) throws IOException;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.render.Renderer#getRendersChildren()
+ */
+ public boolean getRendersChildren() {
+ return true;
+ }
+
+ public void encodeChildren(FacesContext context, UIComponent component)
+ throws IOException {
+ encodeRows(context, component);
+ }
+
+ public void encodeCaption(FacesContext context, SequenceDataAdaptor table)
+ throws IOException {
+ ResponseWriter writer = context.getResponseWriter();
+ UIComponent caption = table.getFacet("caption");
+ if (caption != null) {
+ String captionClass = (String) table.getAttributes().get(
+ "captionClass");
+ String captionStyle = (String) table.getAttributes().get(
+ "captionStyle");
+ writer.startElement("caption", table);
+ if (captionClass != null) {
+ captionClass = "dr-table-caption rich-table-caption "
+ + captionClass;
+ } else {
+ captionClass = "dr-table-caption rich-table-caption";
+ }
+ writer.writeAttribute("class", captionClass,
"captionClass");
+ if (captionStyle != null) {
+ writer.writeAttribute("style", captionStyle,
"captionStyle");
+ }
+ renderChild(context, caption);
+ writer.endElement("caption");
+ }
+
+ }
+
+ /**
+ * @param context
+ * @param table
+ * @throws IOException
+ */
+ protected void encodeRowEvents(FacesContext context, UIDataAdaptor table)
+ throws IOException {
+ RendererUtils utils2 = getUtils();
+ for (int i = 0; i < TABLE_EVENT_ATTRS.length; i++) {
+ String[] attrs = TABLE_EVENT_ATTRS[i];
+ utils2.encodeAttribute(context, table, attrs[1], attrs[0]);
+ }
+ }
+
+ /**
+ * Encode HTML "class" attribute, if is not empty. Classes combined from
+ * pre-defined skin classes, class from parent component, and custom
+ * attribute.
+ *
+ * @param writer
+ * @param parentPredefined
+ * TODO
+ * @param predefined
+ * predefined skin classes
+ * @param parent
+ * class from parent component
+ * @param custom
+ * custom classes.
+ * @throws IOException
+ */
+ protected void encodeStyleClass(ResponseWriter writer,
+ Object parentPredefined, Object predefined, Object parent,
+ Object custom) throws IOException {
+ StringBuffer styleClass = new StringBuffer();
+ // Construct predefined classes
+ if (null != parentPredefined) {
+ styleClass.append(parentPredefined).append(" ");
+ } else if (null != predefined) {
+ styleClass.append(predefined).append(" ");
+ }
+ // Append class from parent component.
+ if (null != parent) {
+ styleClass.append(parent).append(" ");
+ }
+ if (null != custom) {
+ styleClass.append(custom);
+ }
+ if (styleClass.length() > 0) {
+ writer.writeAttribute(HTML.class_ATTRIBUTE, styleClass,
+ "styleClass");
+ }
+ }
+
+ protected void encodeStyle(ResponseWriter writer, Object parentPredefined,
+ Object predefined, Object parent, Object custom) throws IOException {
+ StringBuffer style = new StringBuffer();
+ // Construct predefined styles
+ if (null != parentPredefined) {
+ style.append(parentPredefined).append(" ");
+ } else if (null != predefined) {
+ style.append(predefined).append(" ");
+ }
+ // Append style from parent component.
+ if (null != parent) {
+ style.append(parent).append(" ");
+ }
+ if (null != custom) {
+ style.append(custom);
+ }
+ if (style.length() > 0) {
+ writer.writeAttribute("style", style, "style");
+ }
+ }
+
+ /**
+ * Render component and all its children with current row/cell style
+ * classes.
+ *
+ * @param context
+ * @param cell
+ * @param skinFirstRowClass
+ * TODO
+ * @param skinRowClass
+ * TODO
+ * @param rowClass
+ * @param skinCellClass
+ * TODO
+ * @param cellClass
+ * @throws IOException
+ */
+ protected void encodeCellChildren(FacesContext context, UIComponent cell,
+ String skinFirstRowClass, String skinRowClass, String rowClass,
+ String skinCellClass, String cellClass) throws IOException {
+ Map<String, Object> requestMap = context.getExternalContext()
+ .getRequestMap();
+ // Save top level class parameters ( if any ), and put new for this
+ // component
+ Object savedRowClass = requestMap.get(ROW_CLASS_KEY);
+ if (null != rowClass) {
+ requestMap.put(ROW_CLASS_KEY, rowClass);
+
+ }
+ Object savedSkinFirstRowClass = requestMap
+ .get(SKIN_FIRST_ROW_CLASS_KEY);
+ if (null != skinRowClass) {
+ requestMap.put(SKIN_FIRST_ROW_CLASS_KEY, skinFirstRowClass);
+
+ }
+ Object savedSkinRowClass = requestMap.get(SKIN_ROW_CLASS_KEY);
+ if (null != skinRowClass) {
+ requestMap.put(SKIN_ROW_CLASS_KEY, skinRowClass);
+
+ }
+ Object savedCellClass = requestMap.get(CELL_CLASS_KEY);
+ if (null != cellClass) {
+ requestMap.put(CELL_CLASS_KEY, cellClass);
+ }
+ Object savedSkinCellClass = requestMap.get(SKIN_CELL_CLASS_KEY);
+ if (null != skinCellClass) {
+ requestMap.put(SKIN_CELL_CLASS_KEY, skinCellClass);
+
+ }
+ renderChild(context, cell);
+ // Restore original values.
+ requestMap.put(ROW_CLASS_KEY, savedRowClass);
+ requestMap.put(CELL_CLASS_KEY, savedCellClass);
+ requestMap.put(SKIN_FIRST_ROW_CLASS_KEY, savedSkinFirstRowClass);
+ requestMap.put(SKIN_ROW_CLASS_KEY, savedSkinRowClass);
+ requestMap.put(SKIN_CELL_CLASS_KEY, savedSkinCellClass);
+
+ }
+
+ protected void encodeTableHeaderFacet(FacesContext context, int columns,
+ ResponseWriter writer, UIComponent footer,
+ String skinFirstRowClass, String skinRowClass,
+ String skinCellClass, String footerClass, String element,
+ String facetName) throws IOException {
+ boolean isColgroup = footer instanceof Row;
+ if (!isColgroup) {
+ writer.startElement("tr", footer);
+ encodeStyleClass(writer, null, skinFirstRowClass, footerClass, null);
+ writer.startElement(element, footer);
+ encodeStyleClass(writer, null, skinCellClass, footerClass, null);
+ if (columns > 0) {
+ writer.writeAttribute("colspan", String.valueOf(columns),
null);
+ }
+ writer.writeAttribute("scope", "colgroup", null);
+ }
+ encodeCellChildren(context, footer, skinFirstRowClass, skinRowClass,
+ footerClass, skinCellClass, null);
+ if (!isColgroup) {
+ writer.endElement(element);
+ writer.endElement("tr");
+ }
+
+ }
+
+ protected InternetResource[] getScripts() {
+ return composite.getScripts();
+ }
+
+ protected InternetResource[] getStyles() {
+ return composite.getStyles();
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/AbstractExtendedTableRenderer.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/AbstractExtendedTableRenderer.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/AbstractExtendedTableRenderer.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,1721 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces - 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.renderkit;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.ajax4jsf.context.AjaxContext;
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.JSReference;
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.ajax4jsf.renderkit.AjaxRendererUtils;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.richfaces.component.Column;
+import org.richfaces.component.Row;
+import org.richfaces.component.UIColumn;
+import org.richfaces.component.UIDataTable;
+import org.richfaces.component.UIExtendedDataTable;
+import org.richfaces.component.nsutils.NSUtils;
+import org.richfaces.event.ChangeColumnVisibilityEvent;
+import org.richfaces.event.ColumnResizeEvent;
+import org.richfaces.event.DragDropEvent;
+import org.richfaces.model.Ordering;
+import org.richfaces.model.SortField2;
+import org.richfaces.model.impl.expressive.JavaBeanWrapper;
+import org.richfaces.model.impl.expressive.ObjectWrapperFactory;
+import org.richfaces.model.impl.expressive.WrappedBeanComparator2;
+import org.richfaces.renderkit.html.HTMLEncodingContributor;
+import org.richfaces.renderkit.html.RichTableMenuRenderer;
+import org.richfaces.renderkit.html.TableDragDropRenderer;
+import org.richfaces.renderkit.html.TableMenuRenderer;
+import org.richfaces.renderkit.html.iconimages.DataTableIconSortNone;
+import org.richfaces.renderkit.html.images.TriangleIconDown;
+import org.richfaces.renderkit.html.images.TriangleIconUp;
+
+/**
+ * @author shura
+ *
+ */
+public abstract class AbstractExtendedTableRenderer extends
+ AbstractExtendedRowsRenderer {
+
+ private static final String SORT_FILTER_PARAMETER = "fsp";
+
+ private static final String SORT_DIR_PARAMETER = "sortDir";
+
+ private static final String SORT_DIR_PARAMETER_ASC = "asc";
+
+ private static final String SORT_DIR_PARAMETER_DESC = "desc";
+
+ private static final String FILTER_INPUT_FACET_NAME = "filterValueInput";
+
+ private static final String COL_RESIZE_ACTION_NAME = "columnResizeAction";
+
+ private final static String CHANGE_COL_VISIBILITY = "change_col_v";
+
+ private static final String SORT_FUNCTION = "sortFunction";
+
+ private static final String SHOW_MENU_FUNCTION = "showMenuFunction";
+
+ private static final String ON_RESIZE_FUNCTION = "onColumnResize";
+
+ private static final String GROUP_FILTER_PARAMETER = "groupParam";
+
+ private static final String ON_GROUP_TOGGLE_FUNCTION =
"onGroupToggleFunction";
+
+ private static final String GROUP_TOGGLE_ACTION_NAME =
"groupToggleAction";
+
+ /**
+ * Encode all table structure - colgroups definitions, caption, header,
+ * footer
+ *
+ * @param context
+ * @param table
+ * @throws IOException
+ */
+
+ public void encodeTableStructure(FacesContext context,
+ UIExtendedDataTable table) throws IOException {
+ ResponseWriter writer = context.getResponseWriter();
+ // int columns = getColumnsCount(table);
+ Iterator<UIColumn> cols = table.getSortedColumns();
+ // columns = extendedDataTable.getVisibleColumnsCount();
+ // Encode colgroup definition.
+ // writer.startElement("colgroup", table);
+ // writer.writeAttribute("span", String.valueOf(columns), null);
+
+ while (cols.hasNext()) {
+ UIColumn col = cols.next();
+ if (col.isRendered()) {
+ writer.startElement("col", table);
+ writer.writeAttribute("width", table.getColumnSize(col),
null);
+ writer.endElement("col");
+ }
+ }
+ writer.startElement("col", table);
+ writer.writeAttribute("width", "1*", null);
+ writer.endElement("col");
+ // writer.endElement("colgroup");
+ encodeCaption(context, table);
+ }
+
+ public void encodeHeader(FacesContext context, UIExtendedDataTable table)
+ throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ UIComponent header = table.getHeader();
+ boolean columnFacetPresent = isColumnFacetPresent(table, "header");
+ Iterator<UIColumn> colums = table.getSortedColumns();
+ // int numberOfColumns = getColumnsCount(table);
+ int numberOfColumns = table.getVisibleColumnsCount() + 1;
+ if (header != null || columnFacetPresent) {
+ writer.startElement("thead", table);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, table
+ .getBaseClientId(context)
+ + ":header", null);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "dr-table-thead",
null);
+ String headerClass = (String) table.getAttributes().get(
+ "headerClass");
+ // String menuId = (String) table.getAttributes().get(MENU_ID);
+ if (header != null) {
+ writer.startElement("tr", header);
+ encodeStyleClass(writer, null,
+ "dr-table-header rich-table-header", headerClass,
null);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, table
+ .getBaseClientId(context)
+ + ":fakeIeRow", null);
+ for (int i = 0; i < numberOfColumns; i++) {
+ writer.startElement("th", header);
+ encodeStyleClass(writer, null,
+ "dr-table-headercell rich-table-headercell",
+ headerClass, null);
+ writer.endElement("th");
+ }
+ writer.endElement("tr");
+
+ encodeTableHeaderFacet(context, numberOfColumns, writer,
+ header, "dr-table-header rich-table-header",
+ "dr-table-header-continue rich-table-header-continue",
+ "dr-table-headercell rich-table-headercell",
+ headerClass, "th", "header");
+ }
+
+ if (columnFacetPresent) {
+ writer.startElement("tr", table);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, table
+ .getBaseClientId(context)
+ + ":headerRow", null);
+ encodeStyleClass(writer, null,
+ "dr-table-subheader rich-table-subheader", null,
+ headerClass);
+ encodeHeaderFacets(
+ context,
+ writer,
+ table,
+ colums,
+ "extdt-dr-menucell extdt-subheadercell
rich-table-subheadercell",
+ headerClass, "header", "th",
numberOfColumns);
+ /* encoding additional empty column used in resizing columns */
+ writer.startElement("th", table);
+ encodeStyleClass(writer, null,
+ "extdt-subheadercell rich-table-subheadercell", null,
+ null);
+ writer.endElement("th");
+ writer.endElement("tr");
+
+ encodeFilterRow(context, writer, table, table
+ .getSortedColumns(),
+ "extdt-subheadercell rich-table-subheadercell",
+ headerClass, "header", HTML.th_ELEM);
+
+ }
+ writer.endElement("thead");
+ }
+ }
+
+ private void encodeFilterRow(FacesContext context, ResponseWriter writer,
+ UIExtendedDataTable table, Iterator<UIColumn> headers,
+ String skinCellClass, String headerClass, String facetName,
+ String element) throws IOException {
+ if (filteringEnabled(table)) {
+ writer.startElement(HTML.TR_ELEMENT, table);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, table
+ .getBaseClientId(context)
+ + ":filterRow", null);
+ encodeStyleClass(writer, null,
+ "extdt-table-filterrow rich-table-subheader", null,
+ headerClass);
+ encodeFilterInputs(context, writer, table, headers, skinCellClass,
+ headerClass, facetName, element);
+ writer.startElement(HTML.th_ELEM, table);
+ encodeStyleClass(writer, null,
+ "extdt-subheadercell rich-table-subheadercell", null,
null);
+ writer.endElement(HTML.th_ELEM);
+ writer.endElement(HTML.TR_ELEMENT);
+ }
+ }
+
+ /**
+ * Checks if column has filtering enabled
+ *
+ * @param dataColumn
+ * column to inspect
+ * @return true if filtering is enabled, false otherwise
+ * @author pbuda
+ */
+ private boolean filterEnabledColumn(UIColumn dataColumn) {
+ return dataColumn.getFilterMethod() == null
+ && dataColumn.getValueExpression("filterExpression") ==
null
+ && dataColumn.getValueExpression("filterBy") != null;
+ }
+
+ /**
+ * Checks whether filtering is enabled in this table
+ *
+ * @param table
+ * table to inspect
+ * @return true if filtering is enabled, false otherwise
+ * @author pbuda
+ */
+ private boolean filteringEnabled(UIExtendedDataTable table) {
+ Iterator<UIColumn> columns = table.getSortedColumns();
+ boolean enabled = false;
+ while (columns.hasNext()) {
+ UIColumn col = columns.next();
+ if (col instanceof UIColumn) {
+ UIColumn dataColumn = (UIColumn) col;
+ if (filterEnabledColumn(dataColumn) && dataColumn.isRendered())
{
+ enabled = true;
+ break;
+ }
+ }
+ }
+ return enabled;
+ }
+
+ /**
+ * Encodes a new row of the table and places filter inputs for corresponding
+ * columns in that new row
+ *
+ * @param context
+ * current FacesContext instance
+ * @param writer
+ * ResponseWriter for this context
+ * @param table
+ * table instance
+ * @param headers
+ * iterator over headers in table
+ * @param skinCellClass
+ * css class of skin
+ * @param headerClass
+ * css class of header
+ * @param facetName
+ * facet to encode
+ * @param element
+ * element to encode
+ * @throws IOException
+ * if ResponseWriter fails it's operation
+ * @author pbuda
+ */
+ private void encodeFilterInputs(FacesContext context,
+ ResponseWriter writer, UIDataTable table,
+ Iterator<UIColumn> headers, String skinCellClass,
+ String headerClass, String facetName, String element)
+ throws IOException {
+ while (headers.hasNext()) {
+ UIColumn column = headers.next();
+ if (column instanceof UIColumn) {
+ if (column.isRendered()) {
+ writer.startElement(element, table);
+ String classAttribute = facetName + "Class";
+ String columnHeaderClass = (String) column.getAttributes()
+ .get(classAttribute);
+ encodeStyleClass(writer, null, skinCellClass, headerClass,
+ columnHeaderClass);
+ UIColumn dataColumn = (UIColumn) column;
+ if (filterEnabledColumn(dataColumn)) {
+ writer.startElement(HTML.DIV_ELEM, column);
+ addInplaceInput(context, column, buildAjaxFunction(
+ context, column, false,
+ getOnAjaxCompleteFunction(context,
+ (UIDataTable) column.getParent())));
+ writer.endElement(HTML.DIV_ELEM);
+ }
+ writer.endElement(element);
+ }
+ }
+ }
+ }
+
+ public boolean isColumnFacetPresent(UIDataTable table, String facetName) {
+ Iterator<UIComponent> columns = table.columns();
+ boolean result = false;
+ while (columns.hasNext() && !result) {
+ UIComponent component = columns.next();
+ if (isColumnRendered(component)) {
+ if (null != component.getFacet(facetName)) {
+ result = true;
+ } /*
+ * else if(component instanceof Column) { Column column =
+ * (Column)component; result = column.isSelfSorted(); }
+ */
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param component
+ * @return
+ */
+ protected boolean isColumnRendered(UIComponent component) {
+ boolean rendered = true;
+ try {
+ rendered = component.isRendered();
+ } catch (Exception e) {
+ // DO nothing, rendered binded to row variable;
+ }
+ return rendered;
+ }
+
+ protected void encodeHeaderFacets(FacesContext context,
+ ResponseWriter writer, UIDataTable table,
+ Iterator<UIColumn> headers, String skinCellClass,
+ String headerClass, String facetName, String element, int colCount)
+ throws IOException {
+ int t_colCount = 0;
+
+ // HeaderEncodeStrategy richEncodeStrategy = new
+ // RichHeaderEncodeStrategy();
+ // HeaderEncodeStrategy simpleEncodeStrategy = new
+ // SimpleHeaderEncodeStrategy();
+
+ while (headers.hasNext()) {
+ UIColumn column = headers.next();
+ if (isColumnRendered(column)) {
+ if ((Integer) column.getAttributes().get("colspan") != null) {
+ t_colCount = t_colCount
+ + ((Integer)
column.getAttributes().get("colspan"))
+ .intValue();
+ } else {
+ t_colCount++;
+ }
+ if (t_colCount > colCount) {
+ break;
+ }
+
+ String classAttribute = facetName + "Class";
+ String columnHeaderClass = (String) column.getAttributes().get(
+ classAttribute);
+
+ writer.startElement(element, column);
+ encodeStyleClass(writer, null, skinCellClass, headerClass,
+ columnHeaderClass);
+ writer.writeAttribute("scope", "col", null);
+ getUtils().encodeAttribute(context, column, "colspan");
+
+ boolean sortableColumn = column
+ .getValueExpression("comparator") != null
+ || column.getValueExpression("sortBy") != null;
+ column.getAttributes().put("sortable",
+ Boolean.valueOf(sortableColumn));
+
+ HeaderEncodeStrategy strategy = (column instanceof UIColumn &&
"header"
+ .equals(facetName)) ? new G3HeaderEncodeStrategy()
+ : new RichHeaderEncodeStrategy();
+
+ strategy.encodeBegin(context, writer, column, facetName,
+ sortableColumn);
+
+ UIComponent facet = column.getFacet(facetName);
+ if (facet != null && isColumnRendered(facet)) {
+ renderChild(context, facet);
+ }
+
+ strategy.encodeEnd(context, writer, column, facetName,
+ sortableColumn);
+
+ writer.endElement(element);
+
+ }
+
+ }
+ }
+
+ public void encodeFooter(FacesContext context, UIExtendedDataTable table)
+ throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ UIComponent footer = table.getFooter();
+ boolean columnFacetPresent = isColumnFacetPresent(table, "footer");
+ Iterator<UIColumn> tableColumns = table.getSortedColumns();
+ // int columns = getColumnsCount(table);
+ int columns = table.getVisibleColumnsCount() + 1;
+ if (footer != null || columnFacetPresent) {
+ writer.startElement("tfoot", table);
+ String footerClass = (String) table.getAttributes().get(
+ "footerClass");
+
+ if (columnFacetPresent) {
+ writer.startElement("tr", table);
+ encodeStyleClass(writer, null,
+ "dr-table-subfooter rich-table-subfooter", null,
+ footerClass);
+
+ encodeHeaderFacets(context, writer, table, tableColumns,
+ "dr-table-subfootercell rich-table-subfootercell",
+ footerClass, "footer", "td", columns);
+
+ writer.endElement("tr");
+ }
+ if (footer != null) {
+ encodeTableHeaderFacet(context, columns, writer, footer,
+ "dr-table-footer rich-table-footer",
+ "dr-table-footer-continue rich-table-footer-continue",
+ "dr-table-footercell rich-table-footercell",
+ footerClass, "td", "footer");
+ }
+ writer.endElement("tfoot");
+ }
+
+ }
+
+ /**
+ * Encodes the false row to enable proper rendering in IE when rows grouping
+ * is on (IE won't render the table properly if it has first row with
+ * colspan).
+ *
+ * @param table
+ * to render false row to,
+ * @param context
+ * of the table.
+ * @throws IOException
+ */
+
+ private void encodeFakeIeRow(FacesContext context,
+ UIExtendedDataTable table, ExtendedTableHolder holder)
+ throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ int numberOfColumns = getColumnsCount(table) + 1;
+
+ writer.startElement("tr", table);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, table.getBaseClientId(context)
+ + ":body:fakeIeRow", null);
+ for (int i = 0; i < numberOfColumns; i++) {
+ writer.startElement("td", table);
+ encodeStyleClass(writer, null, getCellSkinClass(), null, null);
+ writer.endElement("td");
+ }
+ writer.endElement("tr");
+
+ }
+
+ /**
+ * Encodes the grouping row.
+ *
+ * @param table
+ * to render group row to,
+ * @param context
+ * of the table.
+ * @throws IOException
+ */
+ private void encodeGroupRow(FacesContext context,
+ UIExtendedDataTable table, ExtendedTableHolder holder)
+ throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ int numberOfColumns = getColumnsCount(table) + 1;
+ int actGroupRow = holder.getGroupRowCounter();
+ writer.startElement(HTML.TR_ELEMENT, table);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "extdt-group-row", null);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, table.getBaseClientId(context)
+ + ":group-row:" + actGroupRow, null);
+
+ writer.writeAttribute("expanded",
+ table.groupIsExpanded(actGroupRow) ? "true" :
"false", null);
+ writer.writeAttribute("groupindex", String.valueOf(actGroupRow),
null);
+
+ writer.startElement(HTML.td_ELEM, table);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dr-table-cell extdt-group-cell", null);
+ writer.writeAttribute("colspan", numberOfColumns, null);
+ writer.startElement(HTML.SPAN_ELEM, table);
+ writer.startElement(HTML.IMG_ELEMENT, table);
+
+ String imagePlusUri = getResource(
+ "/org/richfaces/renderkit/html/images/plusIcon.gif").getUri(
+ context, null);
+ String imageMinusUri = getResource(
+ "/org/richfaces/renderkit/html/images/minusIcon.gif").getUri(
+ context, null);
+ if (table.groupIsExpanded(actGroupRow)) {
+ writer.writeAttribute(HTML.src_ATTRIBUTE, imageMinusUri, null);
+ writer.writeAttribute("alternatesrc", imagePlusUri, null);
+ } else {
+ writer.writeAttribute(HTML.src_ATTRIBUTE, imagePlusUri, null);
+ writer.writeAttribute("alternatesrc", imageMinusUri, null);
+ }
+ writer.endElement(HTML.IMG_ELEMENT);
+ writer.endElement(HTML.SPAN_ELEM);
+ writer.startElement(HTML.SPAN_ELEM, table);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "extdt-group-text", null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE, "font-weight: bold;",
null);
+ String label = holder.getGroupingColumnLabel();
+ writer.writeText((label == null) ? "" : label + ": ", null);
+ writer.endElement(HTML.SPAN_ELEM);
+ renderChildren(context, holder.getGroupingColumn());
+ writer.startElement(HTML.SPAN_ELEM, table);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "extdt-group-text", null);
+ writer.endElement(HTML.SPAN_ELEM);
+ writer.endElement(HTML.td_ELEM);
+ writer.endElement(HTML.TR_ELEMENT);
+ holder.nextGroupRow();
+ }
+
+ protected boolean rowGroupChanged(FacesContext context,
+ ExtendedTableHolder holder) {
+ UIExtendedDataTable table = holder.getTable();
+ if (holder.getLastData() == null)
+ return true;
+
+ // get sort fields
+ List<SortField2> sortFields = table.getSortFields();
+ // get group field which is actually the first from sort fields
+ List<SortField2> groupFields = new ArrayList<SortField2>();
+ if (!sortFields.isEmpty())
+ groupFields.add(sortFields.get(0));
+ // create wrapper factory
+ ObjectWrapperFactory wrapperFactory = new ObjectWrapperFactory(context,
+ table.getVar(), groupFields);
+ // create wrapper for last data
+ JavaBeanWrapper wrappedLstD = wrapperFactory.wrapObject(holder
+ .getLastData());
+ // create wrapper for current data
+ JavaBeanWrapper wrappedActD = wrapperFactory.wrapObject(table
+ .getRowData());
+ // create comparator
+ WrappedBeanComparator2 wrappedBeanComparator = new WrappedBeanComparator2(
+ (groupFields));
+ // compare last and current data
+ return (wrappedBeanComparator.compare(wrappedLstD, wrappedActD) != 0);
+ }// rowGroupChanged
+
+ public void encodeOneRow(FacesContext context, ExtendedTableHolder holder)
+ throws IOException {
+ UIExtendedDataTable table = holder.getTable();
+ ResponseWriter writer = context.getResponseWriter();
+ Iterator<UIColumn> iter = table.getSortedColumns();
+ boolean first = true;
+ int currentColumn = 0;
+ UIColumn column = null;
+ if (holder.isGroupingOn() && (rowGroupChanged(context, holder))) {
+ if (this.firstRow) {
+ encodeFakeIeRow(context, table, holder);
+ }
+ encodeGroupRow(context, table, holder);
+ }
+ this.firstRow = false;
+ while (iter.hasNext()) {
+ column = iter.next();
+ // Start new row for first column - expect a case of the detail
+ // table, wich will be insert own row.
+ boolean isRow = (column instanceof Row);
+ if (first && !isRow) {
+ encodeRowStart(context, getFirstRowSkinClass(), holder
+ .getRowClass(), table, holder, writer);
+ }
+
+ // TODO PKA CHANGE COLUMN RENDERER TO GET RID OF && false
+ if (false && (column instanceof Column)) {
+ boolean breakBefore = ((Column) column).isBreakBefore()
+ || isRow;
+ if (breakBefore && !first) {
+ // close current row
+ writer.endElement(HTML.TR_ELEMENT);
+ // reset columns counter.
+ currentColumn = 0;
+ // Start new row, expect a case of the detail table, wich
+ // will be insert own row.
+ if (!isRow) {
+ holder.nextRow();
+ encodeRowStart(context, holder.getRowClass(), table,
+ holder, writer);
+ }
+ }
+ encodeCellChildren(context, column,
+ first ? getFirstRowSkinClass() : null,
+ getRowSkinClass(), holder.getRowClass(),
+ getCellSkinClass(), holder
+ .getColumnClass(currentColumn));
+ // renderChild(context, column);
+ if (isRow && iter.hasNext()) {
+ // Start new row for remained columns.
+ holder.nextRow();
+ encodeRowStart(context, holder.getRowClass(), table,
+ holder, writer);
+ // reset columns counter.
+ currentColumn = -1;
+ }
+ } else if (column.isRendered()) {
+ // UIColumn don't have own renderer
+ writer.startElement(HTML.td_ELEM, table);
+ getUtils().encodeId(context, column);
+ encodeStyleClass(writer, null, getCellSkinClass(), null, null);
+ // TODO - encode column attributes.
+ writer.startElement(HTML.DIV_ELEM, table);
+ writer.writeAttribute("class", "dt-cell-div", null);
+ // writer.writeAttribute("class", "dt-sdt-bcbody",
null); //KAW
+ // IE
+ renderChildren(context, column);
+ writer.endElement(HTML.DIV_ELEM);
+ writer.endElement(HTML.td_ELEM);
+ }
+ currentColumn++;
+ first = false;
+ }
+ // encode additional empty row for resizing
+ writer.startElement(HTML.td_ELEM, table);
+ String columnClass = holder.getColumnClass(currentColumn);
+ encodeStyleClass(writer, null, getCellSkinClass(), null, columnClass);
+ writer.startElement(HTML.DIV_ELEM, table);
+ writer.writeAttribute("class", "dt-cell-div", null);
+ writer.endElement(HTML.DIV_ELEM);
+ writer.endElement(HTML.td_ELEM);
+ // Close row if then is open.
+ if (!first && !(column instanceof Row)) {
+ writer.endElement(HTML.TR_ELEMENT);
+ }
+ }
+
+ protected void encodeRowStart(FacesContext context, String rowClass,
+ UIDataTable table, TableHolder holder, ResponseWriter writer)
+ throws IOException {
+ encodeRowStart(context, getRowSkinClass(), rowClass, table, holder,
+ writer);
+ }
+
+ /**
+ * @return
+ */
+ protected String getRowSkinClass() {
+ return "dr-table-row rich-table-row";
+ }
+
+ /**
+ * @return
+ */
+ protected String getFirstRowSkinClass() {
+ return "dr-table-firstrow rich-table-firstrow";
+ // return "dt-sdt-rb rich-table-firstrow"; //KAW IE
+ }
+
+ /**
+ * @return
+ */
+ protected String getCellSkinClass() {
+ return "dr-table-cell rich-table-cell";
+ // return "dt-sdt-bc rich-table-cell"; //KAW IE
+
+ }
+
+ protected void encodeRowStart(FacesContext context, String skinClass,
+ String rowClass, UIDataTable table, TableHolder holder,
+ ResponseWriter writer) throws IOException {
+ writer.startElement(HTML.TR_ELEMENT, table);
+ encodeRowId(context, writer, table, holder.getRowCounter());
+ encodeStyleClass(writer, null, skinClass, null, rowClass);
+ encodeRowEvents(context, table);
+ }
+
+ /**
+ * Row ID generator
+ *
+ * @param context
+ * current FacesContext
+ * @param writer
+ * ResponseWriter for FacesContext
+ * @param table
+ * table for which this row is being encoded
+ * @param rowId
+ * new rowId to encode
+ * @throws IOException
+ * if ResponseWriter fails
+ */
+ protected void encodeRowId(FacesContext context, ResponseWriter writer,
+ UIDataTable table, int rowId) throws IOException {
+ String[] ownersId = table.getClientId(context).split(":");
+ String ownerId = ownersId[0] + ":" + ownersId[1];
+ getUtils().writeAttribute(writer, "id", ownerId + ":n:" +
rowId);
+ }
+
+ /**
+ * Calculate total number of columns in table.
+ *
+ * @param context
+ * @param table
+ * @return
+ */
+ protected int getColumnsCount(UIDataTable table) {
+ int count = 0;
+ // check for exact value in component
+ Integer span = (Integer) table.getAttributes().get("columns");
+ if (null != span && span.intValue() != Integer.MIN_VALUE) {
+ count = span.intValue();
+ } else {
+ // calculate max html columns count for all columns/rows children.
+ Iterator<UIComponent> col = table.columns();
+ count = calculateRowColumns(col);
+ }
+ return count;
+ }
+
+ /**
+ * Calculate max number of columns per row. For rows, recursive calculate
+ * max length.
+ *
+ * @param col -
+ * Iterator other all columns in table.
+ * @return
+ */
+ protected int calculateRowColumns(Iterator<UIComponent> col) {
+ int count = 0;
+ int currentLength = 0;
+ while (col.hasNext()) {
+ UIComponent column = (UIComponent) col.next();
+ if (column.isRendered()) {
+ if (column instanceof Row) {
+ // Store max calculated value of previsous rows.
+ if (currentLength > count) {
+ count = currentLength;
+ }
+ // Calculate number of columns in row.
+ currentLength = calculateRowColumns(((Row) column)
+ .columns());
+ // Store max calculated value
+ if (currentLength > count) {
+ count = currentLength;
+ }
+ currentLength = 0;
+ } else if (column instanceof Column) {
+ Column tableColumn = (Column) column;
+ // For new row, save length of previsous.
+ if (tableColumn.isBreakBefore()) {
+ if (currentLength > count) {
+ count = currentLength;
+ }
+ currentLength = 0;
+ }
+ Integer colspan = (Integer) column.getAttributes().get(
+ "colspan");
+ // Append colspan of this column
+ if (null != colspan
+ && colspan.intValue() != Integer.MIN_VALUE) {
+ currentLength += colspan.intValue();
+ } else {
+ currentLength++;
+ }
+ } else if (column instanceof javax.faces.component.UIColumn) {
+ // UIColumn always have colspan == 1.
+ currentLength++;
+ }
+
+ }
+ }
+ if (currentLength > count) {
+ count = currentLength;
+ }
+ return count;
+ }
+
+ public void encodeScriptIfNecessary(FacesContext context,
+ UIExtendedDataTable table) throws IOException {
+ boolean shouldRender = false;
+ Iterator<UIColumn> columns = table.getSortedColumns();
+ while (columns.hasNext() && !shouldRender) {
+ UIColumn next = columns.next();
+ shouldRender = next.isSortable();
+ shouldRender = true;// shouldRender || (next instanceof
+ // HtmlDataColumn);
+ }
+ shouldRender = true;
+ if (shouldRender) {
+ getUtils().writeScript(context, table,
+ createClientDataTable(context, table));
+ }
+ }
+
+ public String createClientDataTable(FacesContext context,
+ UIExtendedDataTable table) {
+ JSFunction function = new JSFunction("new
ExtendedDataTable.DataTable");
+ function.addParameter(table.getBaseClientId(context));
+ ScriptOptions scriptOptions = new ScriptOptions(table);
+ // add on resize column AJAX function
+ scriptOptions.addOption(ON_RESIZE_FUNCTION, getOnResizeFunctionDef(
+ context, table));
+ scriptOptions.addOption(SORT_FUNCTION, getSortFunctionDef(context,
+ table));
+ scriptOptions.addOption(SHOW_MENU_FUNCTION, getShowMenuFunction(
+ context, table));
+ /* Not needed if we do not save open/close state */
+ scriptOptions.addOption(ON_GROUP_TOGGLE_FUNCTION,
+ getOnGroupToggleFunctionDef(context, table));
+ scriptOptions.addOption("minColumnWidth", 100);
+ composite.mergeScriptOptions(scriptOptions, context, table);
+ function.addParameter(scriptOptions);
+ return function.toScript();
+ }
+
+ protected JSFunctionDefinition getShowMenuFunction(FacesContext context,
+ UIDataTable table) {
+ return new RichTableMenuRenderer().createShowMenuEventFunction();
+ }
+
+ protected JSFunctionDefinition getSortFunctionDef(FacesContext context,
+ UIDataTable table) {
+ return getSortFunctionDef(context, table, null);
+ }
+
+ protected JSFunctionDefinition getSortFunctionDef(FacesContext context,
+ UIDataTable table, Boolean asc) {
+ JSFunctionDefinition definition = new JSFunctionDefinition();
+ definition.addParameter("event");
+ definition.addParameter("columnId");
+ String id = table.getClientId(context);
+ Map<String, Object> eventOptions = AjaxRendererUtils.buildEventOptions(
+ context, table);
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>) eventOptions
+ .get("parameters");
+ parameters.put(id, SORT_FILTER_PARAMETER);
+ if (asc != null) {
+ parameters.put(SORT_DIR_PARAMETER, asc ? SORT_DIR_PARAMETER_ASC
+ : SORT_DIR_PARAMETER_DESC);
+ }
+ // parameters.put(SORT_FILTER_PARAMETER, column.getClientId(context));
+ JSFunctionDefinition onAjaxCompleteFunction = getOnAjaxCompleteFunction(
+ context, table);
+ if (onAjaxCompleteFunction != null) {
+ eventOptions.put(AjaxRendererUtils.ONCOMPLETE_ATTR_NAME,
+ onAjaxCompleteFunction);
+ }
+ definition.addToBody("var options = ").addToBody(
+ ScriptUtils.toScript(eventOptions)).addToBody(";\n");
+ definition.addToBody("options.parameters['" +
SORT_FILTER_PARAMETER
+ + "'] = columnId;\n");
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(table,
+ context);
+ ajaxFunction.addParameter(new JSReference("options"));
+ definition.addToBody(ajaxFunction.toScript()).addToBody(";\n");
+ return definition;
+ }// getSortFunction
+
+ protected JSFunction getSortFunction(FacesContext context, UIDataTable table) {
+ String id = table.getClientId(context);
+ Map<String, Object> requestOpts = AjaxRendererUtils.buildEventOptions(
+ context, table);
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>) requestOpts
+ .get("parameters");
+ parameters.put(id, SORT_FILTER_PARAMETER);
+ parameters.put(SORT_DIR_PARAMETER, "{sortDirection}");
+ parameters.put(SORT_FILTER_PARAMETER, "{columnId}");
+ JSFunctionDefinition onAjaxCompleteFunction = getOnAjaxCompleteFunction(
+ context, table);
+ if (onAjaxCompleteFunction != null) {
+ requestOpts.put(AjaxRendererUtils.ONCOMPLETE_ATTR_NAME,
+ onAjaxCompleteFunction);
+ }
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(table,
+ context);
+ ajaxFunction.addParameter(requestOpts);
+ return ajaxFunction;
+ }// getSortFunction
+
+ protected JSFunctionDefinition getOnGroupToggleFunctionDef(
+ FacesContext context, UIDataTable table) {
+ JSFunctionDefinition definition = new JSFunctionDefinition();
+ definition.addParameter("event");
+ definition.addParameter("groupIndex");
+ Map<String, Object> eventOptions = AjaxRendererUtils.buildEventOptions(
+ context, table);
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>) eventOptions
+ .get("parameters");
+ parameters.put(GROUP_TOGGLE_ACTION_NAME, GROUP_TOGGLE_ACTION_NAME);
+ definition.addToBody("var options = ").addToBody(
+ ScriptUtils.toScript(eventOptions)).addToBody(";\n");
+ definition
+ .addToBody("options.parameters['groupIndex'] =
groupIndex;\n");
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(table,
+ context);
+ ajaxFunction.addParameter(new JSReference("options"));
+ definition.addToBody(ajaxFunction.toScript()).addToBody(";\n");
+ return definition;
+ }// getSortFunction
+
+ protected JSFunction getGroupFunction(FacesContext context,
+ UIDataTable table) {
+ String id = table.getClientId(context);
+ Map<String, Object> requestOpts = AjaxRendererUtils.buildEventOptions(
+ context, table);
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>) requestOpts
+ .get("parameters");
+ parameters.put(id, GROUP_FILTER_PARAMETER);
+ parameters.put(GROUP_FILTER_PARAMETER, "{columnId}");
+ JSFunctionDefinition onAjaxCompleteFunction = getOnAjaxCompleteFunction(
+ context, table);
+ if (onAjaxCompleteFunction != null) {
+ requestOpts.put(AjaxRendererUtils.ONCOMPLETE_ATTR_NAME,
+ onAjaxCompleteFunction);
+ }
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(table,
+ context);
+ ajaxFunction.addParameter(requestOpts);
+ return ajaxFunction;
+ }// getSortFunction
+
+ protected JSFunctionDefinition getOnResizeFunctionDef(FacesContext context,
+ UIDataTable table) {
+ JSFunctionDefinition definition = new JSFunctionDefinition();
+ definition.addParameter("event");
+ definition.addParameter("columnWidths");
+
+ Map<String, Object> eventOptions = AjaxRendererUtils.buildEventOptions(
+ context, table);
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>) eventOptions
+ .get("parameters");
+ parameters.put(COL_RESIZE_ACTION_NAME, COL_RESIZE_ACTION_NAME);
+ definition.addToBody("var options = ").addToBody(
+ ScriptUtils.toScript(eventOptions)).addToBody(";\n");
+ definition
+ .addToBody("options.parameters['columnWidths'] =
columnWidths;\n");
+
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(table,
+ context);
+ ajaxFunction.addParameter(new JSReference("options"));
+ definition.addToBody(ajaxFunction.toScript()).addToBody(";\n");
+ return definition;
+ }
+
+ protected JSFunction getChangeColumnVisibilityFunction(
+ FacesContext context, UIDataTable table) {
+ boolean ajaxSingle = true;
+ Map<String, Object> requestOpts = AjaxRendererUtils.buildEventOptions(
+ context, table);
+
+ JSFunctionDefinition onAjaxCompleteFunction = getOnAjaxCompleteFunction(
+ context, table);
+ if (onAjaxCompleteFunction != null)
+ requestOpts.put(AjaxRendererUtils.ONCOMPLETE_ATTR_NAME,
+ onAjaxCompleteFunction);
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>) requestOpts
+ .get("parameters");
+ if (parameters == null) {
+ parameters = new HashMap<String, Object>();
+ requestOpts.put("parameters", parameters);
+ }
+ if (ajaxSingle) {
+ if (!parameters
+ .containsKey(AjaxRendererUtils.AJAX_SINGLE_PARAMETER_NAME))
+ parameters.put(AjaxRendererUtils.AJAX_SINGLE_PARAMETER_NAME,
+ table.getClientId(context));
+ if (!requestOpts.containsKey("control"))
+ requestOpts.put("control", JSReference.THIS);
+ }
+ parameters.put(
+ table.getClientId(context) + ":" + CHANGE_COL_VISIBILITY,
+ "{columnId}");
+
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(table,
+ context);
+ ajaxFunction.addParameter(requestOpts);
+ return ajaxFunction;
+ }
+
+ protected JSFunction getPreSendAjaxRequestFunction(FacesContext context,
+ UIDataTable table) {
+ return new JSFunction(getJavaScriptVarName(context, table)
+ + ".preSendAjaxRequest");
+ }
+
+ protected void preDecode(FacesContext context, UIComponent component) {
+ if (component instanceof UIExtendedDataTable) {
+ UIExtendedDataTable table = (UIExtendedDataTable) component;
+ table.ensureTableStateInitialized();
+ }
+ super.preDecode(context, component);
+ }
+
+ protected void preEncodeBegin(FacesContext context, UIComponent component)
+ throws IOException {
+ if (component instanceof UIExtendedDataTable) {
+ UIExtendedDataTable table = (UIExtendedDataTable) component;
+
+ for (Iterator<UIColumn> columns = table.getChildColumns(); columns
+ .hasNext();) {
+ UIColumn column = columns.next();
+ column.setId(column.getId());
+ }
+
+ table.ensureTableStateInitialized();
+ }
+ super.preEncodeBegin(context, component);
+ }
+
+ protected void doDecode(FacesContext context, UIComponent component) {
+ super.doDecode(context, component);
+ composite.decode(context, component);
+
+ if (component instanceof UIExtendedDataTable) {
+ UIExtendedDataTable table = (UIExtendedDataTable) component;
+ Map<String, String> map = context.getExternalContext()
+ .getRequestParameterMap();
+ String clientId = component.getClientId(context);
+
+ if (SORT_FILTER_PARAMETER.equals(map.get(clientId))) {
+ String sortColumnId = map.get(SORT_FILTER_PARAMETER);
+ boolean isSingleSortMode =
!"multi".equals(table.getSortMode());
+
+ boolean isGroupingOn = table.isGroupingOn();
+ boolean sortByGroupingColumn = false;
+ // String groupingColumnId = null;
+ UIColumn groupingColumn = null;
+ if (isGroupingOn) {
+ groupingColumn = table.getGroupingColumn();
+ sortByGroupingColumn = (groupingColumn == null ? false
+ : groupingColumn.getClientId(context).equals(
+ sortColumnId));
+ // groupingColumnId = table.getGroupingColumnId();
+ }
+ for (Iterator<UIColumn> columns = table.getChildColumns(); columns
+ .hasNext();) {
+ UIColumn column = columns.next();
+ String id = column.getId();
+ column.setId(id);
+
+ if (sortColumnId != null) {
+ boolean isGroupingColumn = (isGroupingOn && column
+ .equals(groupingColumn));
+ if (sortColumnId.equals(column.getClientId(context))) {
+ // set sort order
+ if (map.containsKey(SORT_DIR_PARAMETER)) {
+ String sortDir = (String) map
+ .get(SORT_DIR_PARAMETER);
+ column
+ .setSortOrder((sortDir
+ .equals(SORT_DIR_PARAMETER_ASC) ?
Ordering.ASCENDING
+ : (sortDir
+ .equals(SORT_DIR_PARAMETER_DESC)
? Ordering.DESCENDING
+ : Ordering.UNSORTED)));
+ } else {
+ column.toggleSortOrder();
+ }
+
+ Collection<Object> sortPriority = table
+ .getSortPriority();
+ // clear sort priority in case of single sort mode
+ if (isSingleSortMode) {
+ sortPriority.clear();
+ }
+ // add column to sort priority if is not added yet
+ if (!sortPriority.contains(id)) {
+ sortPriority.add(id);
+ }
+ if (isGroupingColumn) {
+ // set as grouping column to mark that grouping
+ // order has changed
+ table.setGroupingColumn(column);
+ }
+ } else if (isSingleSortMode) { // in case of single
+ // sort mode
+ if (!isGroupingColumn) { // grouping is not by
+ // this column
+ if (!sortByGroupingColumn) {// sort not by
+ // grouping column
+ // disable sort by this column
+ column.setSortOrder(Ordering.UNSORTED);
+ }
+ }
+ }
+ }
+
+ UIInput filterValueInput = (UIInput) column
+ .getFacet(FILTER_INPUT_FACET_NAME);
+ if (null != filterValueInput) {
+ filterValueInput.decode(context);
+ String oldFilterValue = column.getFilterValue();
+ Object submittedValue = filterValueInput
+ .getSubmittedValue();
+ String newFilterValue = null;
+ if (null != submittedValue) {
+ newFilterValue = filterValueInput
+ .getSubmittedValue().toString();
+ if ((newFilterValue != null)
+ && (newFilterValue.length() == 0)) {
+ newFilterValue = null;
+ }
+ column.setFilterValue(newFilterValue);
+ }
+ boolean filterChanged = (newFilterValue == null ? (oldFilterValue
!= null)
+ : !newFilterValue.equals(oldFilterValue));
+ if (filterChanged) {
+ table.resetGroupVisibilityState();
+ }
+ }
+ }
+
+ AjaxContext.getCurrentInstance().addComponentToAjaxRender(
+ component);
+ // AjaxContext.getCurrentInstance().addRenderedArea(clientId +
+ // ":tu");
+ }
+
+ // GROUP COLUMNS
+ if (GROUP_FILTER_PARAMETER.equals(map.get(clientId))) {
+ String groupColumnId = map.get(GROUP_FILTER_PARAMETER);
+ // turn off grouping
+ table.disableGrouping();
+ if (groupColumnId != null) {
+ // turn off sorting by all columns
+ table.getSortPriority().clear();
+ for (Iterator<UIColumn> columns = table.getChildColumns();
columns
+ .hasNext();) {
+ UIColumn column = columns.next();
+ // child.setId(child.getId());
+ if (groupColumnId.equals(column.getClientId(context))) { //
group
+ //
by
+ //
this
+ //
column
+ // set sort order if is not set
+ if (column.getSortOrder().equals(Ordering.UNSORTED)) {
+ column.setSortOrder(Ordering.ASCENDING);
+ }
+ // set as grouping column
+ table.setGroupingColumn(column);
+ } else { // grouping is not by this column
+ // turn off sorting by this column
+ column.setSortOrder(Ordering.UNSORTED);
+ }
+ }// for columns
+ }// if
+
+ AjaxContext.getCurrentInstance().addComponentToAjaxRender(
+ component);
+ // AjaxContext.getCurrentInstance().addRenderedArea(clientId +
+ // ":tu");
+ }// group columns
+
+ // CHANGE COLUMN ORDER - DRAG AND DROP
+ String dragSourceId = (String) map
+
.get(org.richfaces.renderkit.DraggableRendererContributor.DRAG_SOURCE_ID);
+ String dropTargetId = (String) map
+
.get(org.richfaces.renderkit.DropzoneRendererContributor.DROP_TARGET_ID);
+ if ((dragSourceId != null) && (dropTargetId != null)) {
+ Pattern sourcePattern = Pattern.compile(clientId + ":(\\w*):"
+ + TableDragDropRenderer.DRAG_SOURCE_SCRIPT_ID);
+ Pattern targetPattern = Pattern.compile(clientId + ":(\\w*):"
+ + TableDragDropRenderer.DROP_TARGET_SCRIPT_ID + "("
+ + TableDragDropRenderer.DROP_TARGET_BEFORE + "|"
+ + TableDragDropRenderer.DROP_TARGET_AFTER + ")");
+ Matcher sourceMatcher = sourcePattern.matcher(dragSourceId);
+ Matcher targetMatcher = targetPattern.matcher(dropTargetId);
+ if (sourceMatcher.find() && targetMatcher.find()) {
+ String sourceColumnId = sourceMatcher.group(1);
+ String targetColumnId = targetMatcher.group(1);
+ String kind = targetMatcher.group(2);
+
+ DragDropEvent dragDropEvent = new DragDropEvent(component);
+ dragDropEvent.setDragValue(sourceColumnId);
+ dragDropEvent.setDropValue(targetColumnId);
+ dragDropEvent.setDropBefore(kind
+ .equals(TableDragDropRenderer.DROP_TARGET_BEFORE));
+
+ dragDropEvent.queue();
+
+ AjaxContext.getCurrentInstance().addComponentToAjaxRender(
+ component);
+ // AjaxContext ajaxContext =
+ // AjaxContext.getCurrentInstance();
+ // ajaxContext.addComponentToAjaxRender(component);
+ // ajaxContext.addRenderedArea(clientId + ":tb");// body
+ // ajaxContext.addRenderedArea(clientId + ":tu");
+ // ajaxContext.addRenderedArea(clientId + ":tm");// menu
+ // AjaxContext.getCurrentInstance().addRenderedArea(clientId);
+ }
+ }// change column order
+
+ // CHANGE COLUMN VISIBILITY
+ String columnToChange = (String) map.get(clientId + ":"
+ + TableMenuRenderer.CHANGE_COL_VISIBILITY);
+ if (columnToChange != null) {
+ ChangeColumnVisibilityEvent event = new ChangeColumnVisibilityEvent(
+ component, columnToChange);
+
+ event.queue();
+
+ AjaxContext.getCurrentInstance().addComponentToAjaxRender(
+ component);
+ // AjaxContext ajaxContext = AjaxContext.getCurrentInstance();
+ // ajaxContext.addComponentToAjaxRender(component);
+ // ajaxContext.addRenderedArea(clientId + ":tb");// body
+ // ajaxContext.addRenderedArea(clientId + ":tu");
+ // ajaxContext.addRenderedArea(clientId + ":tm");// menu
+ }// change column visibility
+
+ // COLUMN RESIZE
+ if (COL_RESIZE_ACTION_NAME.equals(map.get(COL_RESIZE_ACTION_NAME))) {
+ String colWidths = (String) map.get("columnWidths");
+ ColumnResizeEvent event = new ColumnResizeEvent(component,
+ colWidths);
+ event.queue();
+ }
+
+ // TOGGLE ROW GROUP
+ if (GROUP_TOGGLE_ACTION_NAME.equals(map
+ .get(GROUP_TOGGLE_ACTION_NAME))) {
+ String group = (String) map.get("groupIndex");
+ if (group != null) {
+ try {
+ table.toggleGroup(Integer.valueOf(group));
+ } catch (NumberFormatException _) {
+ }
+ }// if
+ }
+
+ }
+ }
+
+ public void encodeEnd(FacesContext context, UIComponent component)
+ throws IOException {
+ super.encodeEnd(context, component);
+ String clientId = component.getClientId(context);
+ Set<String> ajaxRenderedAreas = AjaxContext.getCurrentInstance()
+ .getAjaxRenderedAreas();
+ // if (ajaxRenderedAreas.contains(clientId + ":tb")) {
+ // ajaxRenderedAreas.remove(clientId);
+ // }
+ if (ajaxRenderedAreas.contains(clientId)) {
+ // remove all child elements
+ for (Iterator<String> iter = ajaxRenderedAreas.iterator(); iter
+ .hasNext();) {
+ String area = iter.next();
+ if (area.startsWith(clientId) && (!area.equals(clientId))) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ protected void addInplaceInput(FacesContext context, UIComponent column,
+ String buffer) throws IOException {
+ UIInput filterValueInput = (UIInput) column
+ .getFacet(FILTER_INPUT_FACET_NAME);
+ if (null == filterValueInput) {
+ filterValueInput = (UIInput) context.getApplication()
+ .createComponent(UIInput.COMPONENT_TYPE);
+ filterValueInput.setId(column.getId() + SORT_FILTER_PARAMETER);
+ filterValueInput.setImmediate(true);
+ column.getFacets().put(FILTER_INPUT_FACET_NAME, filterValueInput);
+ filterValueInput.getAttributes().put(HTML.onclick_ATTRIBUTE,
+ "Event.stop(event);");
+ }
+ String filterEvent = (String)
column.getAttributes().get("filterEvent");
+ if (null == filterEvent || "".equals(filterEvent)) {
+ filterEvent = "onchange";
+ }
+
+ filterValueInput.getAttributes().put(filterEvent, buffer);
+ filterValueInput.setValue(column.getAttributes().get("filterValue"));
+
+ getUtils().encodeBeginFormIfNessesary(context, column);
+ renderChild(context, filterValueInput);
+ getUtils().encodeEndFormIfNessesary(context, column);
+ }
+
+ protected String buildAjaxFunction(FacesContext context,
+ UIComponent column, boolean sortable,
+ JSFunctionDefinition onAjaxCompleteFunction) {
+ UIComponent table = column.getParent();
+ String id = table.getClientId(context);
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(table,
+ context);
+ Map<String, Object> eventOptions = AjaxRendererUtils.buildEventOptions(
+ context, table);
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>) eventOptions
+ .get("parameters");
+
+ parameters.put(id, SORT_FILTER_PARAMETER);
+ if (sortable) {
+ parameters.put(SORT_FILTER_PARAMETER, column.getClientId(context));
+ }
+ if (onAjaxCompleteFunction != null)
+ eventOptions.put(AjaxRendererUtils.ONCOMPLETE_ATTR_NAME,
+ onAjaxCompleteFunction);
+ ajaxFunction.addParameter(eventOptions);
+ StringBuffer buffer = new StringBuffer();
+ ajaxFunction.appendScript(buffer);
+
+ return buffer.toString();
+ }
+
+ protected class SimpleHeaderEncodeStrategy implements HeaderEncodeStrategy {
+
+ public void encodeBegin(FacesContext context, ResponseWriter writer,
+ UIComponent column, String facetName, boolean sortableColumn)
+ throws IOException {
+
+ }
+
+ public void encodeEnd(FacesContext context, ResponseWriter writer,
+ UIComponent column, String facetName, boolean sortableColumn)
+ throws IOException {
+
+ }
+
+ }
+
+ protected class RichHeaderEncodeStrategy implements HeaderEncodeStrategy {
+
+ public void encodeBegin(FacesContext context, ResponseWriter writer,
+ UIComponent column, String facetName, boolean sortableColumn)
+ throws IOException {
+ UIColumn col = (UIColumn) column;
+ String clientId = col.getClientId(context) + facetName;
+ writer.writeAttribute("id", clientId, null);
+
+ if (sortableColumn && col.isSelfSorted()) {
+ writer.writeAttribute(HTML.onclick_ATTRIBUTE,
+ buildAjaxFunction(context, column, true, null)
+ .toString(), null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE, "cursor:
pointer;",
+ null);
+ }
+
+ writer.startElement(HTML.DIV_ELEM, column);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, clientId + ":sortDiv",
+ null);
+ AjaxContext.getCurrentInstance().addRenderedArea(
+ clientId + ":sortDiv");
+
+ if (sortableColumn) {
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dr-table-sortable-header", null);
+ }
+ }
+
+ public void encodeEnd(FacesContext context, ResponseWriter writer,
+ UIComponent column, String facetName, boolean sortableColumn)
+ throws IOException {
+ UIColumn col = (UIColumn) column;
+ if (sortableColumn) {
+ String imageUrl = null;
+ if (Ordering.ASCENDING.equals(col.getSortOrder())) {
+ if (null != col.getSortIconAscending()) {
+ imageUrl = col.getSortIconAscending();
+ } else {
+ imageUrl = getResource(TriangleIconUp.class.getName())
+ .getUri(context, null);
+ }
+ } else if (Ordering.DESCENDING.equals(col.getSortOrder())) {
+ if (null != col.getSortIconDescending()) {
+ imageUrl = col.getSortIconDescending();
+ } else {
+ imageUrl = getResource(TriangleIconDown.class.getName())
+ .getUri(context, null);
+ }
+ } else if (col.isSelfSorted()) {
+ if (null != col.getSortIcon()) {
+ imageUrl = col.getSortIcon();
+ } else {
+ imageUrl = getResource(
+ DataTableIconSortNone.class.getName()).getUri(
+ context, null);
+ }
+ }
+
+ if (imageUrl != null) {
+ writer.startElement(HTML.IMG_ELEMENT, column);
+ writer.writeAttribute(HTML.src_ATTRIBUTE, imageUrl, null);
+ writer.writeAttribute(HTML.width_ATTRIBUTE, "15", null);
+ writer.writeAttribute(HTML.height_ATTRIBUTE, "15", null);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dr-table-header-sort-img", null);
+ writer.endElement(HTML.IMG_ELEMENT);
+ }
+ writer.endElement(HTML.SPAN_ELEM);
+ }
+
+ writer.endElement(HTML.DIV_ELEM);
+
+ if (col.getFilterMethod() == null
+ && col.getValueExpression("filterExpression") ==
null
+ && col.getValueExpression("filterBy") != null) {
+
+ writer.startElement(HTML.DIV_ELEM, column);
+ addInplaceInput(context, column, buildAjaxFunction(context,
+ column, false, null));
+ writer.endElement(HTML.DIV_ELEM);
+ }
+ }
+ }
+
+ protected class G3HeaderEncodeStrategy implements HeaderEncodeStrategy {
+
+ public void encodeBegin(FacesContext context, ResponseWriter writer,
+ UIComponent column, String facetName, boolean sortableColumn)
+ throws IOException {
+ if (column instanceof UIColumn) {
+ UIColumn dataColumn = (UIColumn) column;
+ String clientId = dataColumn.getClientId(context);// +
+ // facetName;
+ writer.writeAttribute("id", clientId, null);
+ column.getAttributes().put("columnClientId", clientId);
+ boolean sortable = sortableColumn && dataColumn.isSelfSorted();
+ if (sortable) {
+ /*
+ * writer.writeAttribute(HTML.onclick_ATTRIBUTE,
+ * buildAjaxFunction( context, column, true,
+ * getOnAjaxCompleteFunction(context, (UIDataTable)
+ * column.getParent())) .toString(), null);
+ */
+ writer.writeAttribute(HTML.style_ATTRIBUTE,
+ "cursor: pointer;", null);
+ }
+ writer.writeAttribute("sortable", String.valueOf(sortable),
+ null);
+ //
column.getAttributes().put("sortable",Boolean.valueOf(sortable));
+ // drag source area
+ writer.startElement(HTML.DIV_ELEM, dataColumn);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, dataColumn.getParent()
+ .getClientId(context)
+ + "_hdrag_" + dataColumn.getId(), null);
+
+ writer.startElement(HTML.DIV_ELEM, dataColumn);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, clientId +
":sortDiv",
+ null);
+ AjaxContext.getCurrentInstance().addRenderedArea(
+ clientId + ":sortDiv");
+
+ if (sortableColumn) {
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dr-table-sortable-header", null);
+ }
+ }
+ }
+
+ public void encodeEnd(FacesContext context, ResponseWriter writer,
+ UIComponent column, String facetName, boolean sortableColumn)
+ throws IOException {
+ if (column instanceof UIColumn) {
+ UIColumn dataColumn = (UIColumn) column;
+ String clientId = dataColumn.getClientId(context) + facetName;
+ String tableId = dataColumn.getParent().getClientId(context);
+
+ if (sortableColumn) {
+ String imageUrl = null;
+ if (Ordering.ASCENDING.equals(dataColumn.getSortOrder())) {
+ if (null != dataColumn.getSortIconAscending()) {
+ imageUrl = dataColumn.getSortIconAscending();
+ } else {
+ imageUrl = getResource(
+ TriangleIconUp.class.getName()).getUri(
+ context, null);
+ }
+ } else if (Ordering.DESCENDING.equals(dataColumn
+ .getSortOrder())) {
+ if (null != dataColumn.getSortIconDescending()) {
+ imageUrl = dataColumn.getSortIconDescending();
+ } else {
+ imageUrl = getResource(
+ TriangleIconDown.class.getName()).getUri(
+ context, null);
+ }
+ } else if (dataColumn.isSelfSorted()) {
+ if (null != dataColumn.getSortIcon()) {
+ imageUrl = dataColumn.getSortIcon();
+ } else {
+ imageUrl = getResource(
+ DataTableIconSortNone.class.getName())
+ .getUri(context, null);
+ }
+ }
+
+ if (imageUrl != null) {
+ writer.startElement(HTML.IMG_ELEMENT, column);
+ writer.writeAttribute(HTML.src_ATTRIBUTE, imageUrl,
+ null);
+ writer.writeAttribute(HTML.width_ATTRIBUTE, "15",
null);
+ writer
+ .writeAttribute(HTML.height_ATTRIBUTE, "15",
+ null);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dr-table-header-sort-img", null);
+ writer.endElement(HTML.IMG_ELEMENT);
+ }
+ writer.endElement(HTML.SPAN_ELEM);
+ }
+
+ writer.endElement(HTML.DIV_ELEM);
+
+ // drag source area
+ writer.endElement(HTML.DIV_ELEM);
+ String dragSourceId = tableId + "_hdrag_" +
dataColumn.getId();
+ String indicatorId = tableId + ":dataTable_indicator";
+ renderDragSupport(context, dataColumn, dragSourceId,
+ indicatorId, dataColumn.getColumnLabel());
+
+ // separator area
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, clientId +
":sepSpan",
+ null);
+ writer
+ .writeAttribute(HTML.class_ATTRIBUTE, "dt-sdt-hsep",
+ null);
+ writer.endElement(HTML.SPAN_ELEM);
+
+ // drop target area LEFT
+ String spanId = tableId + "_hdrop_" + dataColumn.getId()
+ + "left";
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, spanId, null);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "dt-sdt-hdrop",
+ null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE,
+ "visibility: hidden;", null);
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dt-sdt-hdrop-top dt-sdt-hdrop-top-left", null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE,
+ "visibility: hidden;", null);
+ writer.endElement(HTML.SPAN_ELEM);
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dt-sdt-hdrop-bottom dt-sdt-hdrop-bottom-left", null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE,
+ "visibility: hidden;", null);
+ writer.endElement(HTML.SPAN_ELEM);
+ writer.endElement(HTML.SPAN_ELEM);
+ renderDropSupport(context, dataColumn, spanId, true);
+
+ // drop target area RIGHT
+ spanId = tableId + "_hdrop_" + dataColumn.getId() +
"right";
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, spanId, null);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "dt-sdt-hdrop",
+ null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE,
+ "visibility: hidden;", null);
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dt-sdt-hdrop-top dt-sdt-hdrop-top-right", null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE,
+ "visibility: hidden;", null);
+ writer.endElement(HTML.SPAN_ELEM);
+ writer.startElement(HTML.SPAN_ELEM, column);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dt-sdt-hdrop-bottom dt-sdt-hdrop-bottom-right",
null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE,
+ "visibility: hidden;", null);
+ writer.endElement(HTML.SPAN_ELEM);
+ writer.endElement(HTML.SPAN_ELEM);
+ renderDropSupport(context, dataColumn, spanId, false);
+
+ // menu
+ if ("header".equals(facetName)) {
+ writer.startElement(HTML.DIV_ELEM, column);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "extdt-menu-div", null);
+ writer.endElement(HTML.DIV_ELEM);
+ }
+
+ // if (dataColumn.getFilterMethod() == null
+ // && dataColumn.getValueExpression("filterExpression")
== null
+ // && dataColumn.getValueExpression("filterBy") !=
null) {
+ //
+ // writer.startElement(HTML.DIV_ELEM, column);
+ // addInplaceInput(context, column, buildAjaxFunction(context,
+ // column, false, getOnAjaxCompleteFunction(context,
+ // (UIDataTable) column.getParent())));
+ // writer.endElement(HTML.DIV_ELEM);
+ // }
+ }
+ }
+ }
+
+ public void encodeDragDropChildScripts(FacesContext context,
+ UIComponent component) throws IOException {
+ TableDragDropRenderer.getInstance(context).encodeChildScripts(context,
+ component);
+ }
+
+ public void encodeNamespace(FacesContext context, UIComponent component)
+ throws IOException {
+ NSUtils.writeNameSpace(context, component);
+ }
+
+ public void renderDragSupport(FacesContext context, UIColumn column,
+ String dragSourceId, String indicatorId, String dragLabel)
+ throws IOException {
+ TableDragDropRenderer.getInstance(context).renderDragSupport(column,
+ dragSourceId, indicatorId, dragLabel);
+ }// renderDragSupport
+
+ public void renderDropSupport(FacesContext context, UIColumn column,
+ String dropTargetId, boolean before) throws IOException {
+ TableDragDropRenderer renderer = TableDragDropRenderer
+ .getInstance(context);
+ renderer.setOnAjaxCompleteFunctionDef(getOnAjaxCompleteFunction(
+ context, (UIDataTable) column.getParent()));
+ renderer.setPreSendAjaxRequestFunction(getPreSendAjaxRequestFunction(
+ context, (UIDataTable) column.getParent()));
+ renderer.renderDropSupport(column, dropTargetId, before);
+ }// renderDropSupport
+
+ public static String getJavaScriptVarName(FacesContext context,
+ UIDataTable grid) {
+ String id = grid.getBaseClientId(context);
+ String name = "ExtendedDataTable.DataTable_"
+ + id.replaceAll("[^A-Za-z0-9_]", "_");
+ // String name = "Richfaces_ScrollableGrid";
+ return "window." + name;
+ }
+
+ protected String getScriptContributions(FacesContext context,
+ UIDataTable grid) {
+ return composite.getScriptContributions(getJavaScriptVarName(context,
+ grid), context, grid);
+ }
+
+ protected JSFunctionDefinition getOnAjaxCompleteFunction(
+ FacesContext context, UIDataTable table) {
+
+ return null;
+ // JSFunctionDefinition function = new JSFunctionDefinition("request",
+ // "event", "data");
+ // String varName = getJavaScriptVarName(context, table);
+ // function.addToBody(varName + ".update();");
+ // return function;
+ }
+
+ public void encodeTableMenu(FacesContext context, UIExtendedDataTable table)
+ throws IOException {
+ AjaxContext ajaxContext = AjaxContext.getCurrentInstance();
+ TableMenuRenderer menuRenderer = new RichTableMenuRenderer();
+ menuRenderer.setSortFunction(getSortFunction(context, table));
+ menuRenderer.setGroupFunction(getGroupFunction(context, table));
+ menuRenderer
+ .setChangeColumnVisibilityFunction(getChangeColumnVisibilityFunction(
+ context, table));
+ menuRenderer.setPrepareFunction(getPreSendAjaxRequestFunction(context,
+ table));
+ for (Iterator<UIColumn> colums = table.getSortedColumns(); colums
+ .hasNext();) {
+ UIColumn col = colums.next();
+ if (col instanceof UIColumn) {
+ UIColumn column = (UIColumn) col;
+ // if (column.isRendered()){
+ String menuId = menuRenderer.renderMenu(context, table, column);
+ ajaxContext.addRenderedArea(menuId);
+ // }
+ }
+ }// for
+ }
+
+ public void contributorsEncodeHere(FacesContext context, UIDataTable table)
+ throws IOException {
+ RendererContributor[] contribs = composite.getContributors();
+
+ if (contribs != null) {
+ for (int i = 0; i < contribs.length; i++) {
+ RendererContributor rendererContributor = contribs[i];
+
+ if (rendererContributor instanceof HTMLEncodingContributor) {
+ ((HTMLEncodingContributor) rendererContributor).encode(
+ context, table);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/ExtendedTableHolder.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/ExtendedTableHolder.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/ExtendedTableHolder.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,89 @@
+/**
+ *
+ */
+package org.richfaces.renderkit;
+
+import org.richfaces.component.UIColumn;
+import org.richfaces.component.UIExtendedDataTable;
+
+/**
+ * Extended table holder. It keeps additional information like last row key, last row
data
+ * and information about grouping.
+ * @author pawelgo
+ *
+ */
+public class ExtendedTableHolder extends TableHolder {
+
+ private Object lastData = null;
+ private Object lastKey = null;
+ //private int curRowId = -1;
+ private int groupRowCounter = -1;
+
+ private boolean groupingOn = false;
+ private UIColumn groupingColumn = null;
+ private String groupingColumnLabel = null;
+
+ /**
+ *
+ * @param table
+ */
+ public ExtendedTableHolder(UIExtendedDataTable table) {
+ super(table);
+ lastData = null;
+ lastKey = null;
+ groupRowCounter = 0;
+ groupingOn = table.isGroupingOn();
+ groupingColumnLabel = "";
+ if (groupingOn){
+ groupingColumn = table.getGroupingColumn();
+ if ((groupingColumn != null) && (groupingColumn instanceof UIColumn)){
+ groupingColumnLabel = ((UIColumn)groupingColumn).getColumnLabel();
+ }
+ }
+ }
+
+ public UIExtendedDataTable getTable() {
+ return (UIExtendedDataTable)super.getTable();
+ }
+
+ public Object getLastData() {
+ return lastData;
+ }
+
+ public void setLastData(Object lastData) {
+ this.lastData = lastData;
+ }
+
+ public Object getLastKey() {
+ return lastKey;
+ }
+
+ public void setLastKey(Object lastKey) {
+ this.lastKey = lastKey;
+ }
+
+ public int getGroupRowCounter() {
+ return groupRowCounter;
+ }
+
+ /**
+ * Get current rendered row number, and increment to next value.
+ * @return the rowCounter
+ */
+ public int nextGroupRow() {
+ return groupRowCounter++;
+ }
+
+ public String getGroupingColumnLabel() {
+ return groupingColumnLabel;
+ }
+
+ public boolean isGroupingOn() {
+ return groupingOn;
+ }
+
+ public UIColumn getGroupingColumn() {
+ return groupingColumn;
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/DraggableRendererContributor.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/DraggableRendererContributor.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/DraggableRendererContributor.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,112 @@
+/**
+ *
+ */
+package org.richfaces.renderkit.html;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+import org.richfaces.renderkit.CompositeRenderer;
+import org.richfaces.renderkit.RendererContributor;
+import org.richfaces.renderkit.ScriptOptions;
+
+/**
+ * Renderer contributor for drag support based on
+ * {@link org.richfaces.renderkit.DraggableRendererContributor}. Used only with
+ * {@link org.richfaces.component.UIExtendedDataTable} component. All
+ * functionality from wrapped
+ * {@link org.richfaces.renderkit.DraggableRendererContributor} are available
+ * and special method
+ * {@link DraggableRendererContributor#buildOptions(FacesContext, UIComponent, String,
String)}
+ * is added.
+ *
+ * @author pawelgo
+ *
+ */
+public class DraggableRendererContributor implements RendererContributor {
+
+ private static DraggableRendererContributor instance;
+
+ private static RendererContributor wrappedContributor;
+
+ private DraggableRendererContributor() {
+ super();
+ }
+
+ public static synchronized DraggableRendererContributor getInstance() {
+ if (instance == null) {
+ instance = new DraggableRendererContributor();
+ wrappedContributor = org.richfaces.renderkit.DraggableRendererContributor
+ .getInstance();
+ }
+ return instance;
+ }
+
+ public void decode(FacesContext context, UIComponent component,
+ CompositeRenderer compositeRenderer) {
+ wrappedContributor.decode(context, component, compositeRenderer);
+ }
+
+ public Class<?> getAcceptableClass() {
+ return wrappedContributor.getAcceptableClass();
+ }
+
+ public String getScriptContribution(FacesContext context,
+ UIComponent component) {
+ return wrappedContributor.getScriptContribution(context, component);
+ }
+
+ public String[] getScriptDependencies() {
+ return wrappedContributor.getScriptDependencies();
+ }
+
+ public String[] getStyleDependencies() {
+ return wrappedContributor.getStyleDependencies();
+ }
+
+ public ScriptOptions buildOptions(FacesContext context,
+ UIComponent component) {
+ return wrappedContributor.buildOptions(context, component);
+ }
+
+ /**
+ * Builds options for DnD.G3SimpleDraggable JavaScript object. These options
+ * are specialized for drag source used to start changing table columns
+ * order event.
+ *
+ * @param context
+ * faces context
+ * @param column
+ * table column
+ * @param dragSourceScriptId
+ * drag source HTML element id
+ * @param indicatorId
+ * drag indicator id
+ * @return all options needed for drag JavaScript object to work
+ */
+ public ScriptOptions buildOptions(FacesContext context, UIComponent column,
+ String dragSourceScriptId, String indicatorId) {
+
+ ScriptOptions options = new ScriptOptions(column);
+ options.addOption("dragType", "COLUMN_ORDER_"
+ + column.getParent().getClientId(context));
+
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ parameters
+ .put(
+
org.richfaces.renderkit.DraggableRendererContributor.DRAG_SOURCE_ID,
+ dragSourceScriptId);
+ parameters.put(dragSourceScriptId, dragSourceScriptId);
+ options.addOption("parameters", parameters);
+
+ if (indicatorId != null) {
+ options.addOption("dragIndicator", indicatorId);
+ }
+
+ return options;
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/DropzoneRendererContributor.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/DropzoneRendererContributor.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/DropzoneRendererContributor.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,145 @@
+/**
+ *
+ */
+package org.richfaces.renderkit.html;
+
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.JSReference;
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.ajax4jsf.renderkit.AjaxRendererUtils;
+import org.richfaces.renderkit.CompositeRenderer;
+import org.richfaces.renderkit.RendererContributor;
+import org.richfaces.renderkit.ScriptOptions;
+
+/**
+ * Renderer contributor for drop support based on {@link
org.richfaces.renderkit.DropzoneRendererContributor}.
+ * Used only with {@link org.richfaces.component.UIExtendedDataTable} component.
+ * All functionality from wrapped {@link
org.richfaces.renderkit.DropzoneRendererContributor} are available.
+ * Also special methods {@link DropzoneRendererContributor#buildOptions(FacesContext,
UIComponent)}
+ * and {@link DropzoneRendererContributor#getScriptContribution(FacesContext,
UIComponent, String, JSFunctionDefinition)}
+ * are added.
+ *
+ * @author pawelgo
+ *
+ */
+public class DropzoneRendererContributor implements RendererContributor {
+
+ private DropzoneRendererContributor() {
+ super();
+ }
+
+ private static DropzoneRendererContributor instance;
+
+ private static RendererContributor wrappedContributor;
+
+ public static synchronized DropzoneRendererContributor getInstance() {
+ if (instance == null) {
+ instance = new DropzoneRendererContributor();
+ wrappedContributor =
org.richfaces.renderkit.DropzoneRendererContributor.getInstance();
+ }
+
+ return instance;
+ }
+
+ public void decode(FacesContext context, UIComponent component, CompositeRenderer
compositeRenderer) {
+ wrappedContributor.decode(context, component, compositeRenderer);
+ }
+
+ public Class<?> getAcceptableClass() {
+ return wrappedContributor.getAcceptableClass();
+ }
+
+ public String getScriptContribution(FacesContext context, UIComponent component) {
+ return wrappedContributor.getScriptContribution(context, component);
+ }
+
+ /**
+ * Build JavaScript code for drag'n drop support specialized for change table column
order event.
+ * @param context faces context
+ * @param column table column
+ * @param dropTargetScriptId id of HTML script element that contains defined
DnD.G3SimpleDropZone object
+ * @param onAjaxCompleteFunction JavaScript function to be called on AJAX request
complete
+ * @return JavaScript code
+ */
+ public String getScriptContribution(FacesContext context, UIComponent column, String
dropTargetScriptId, JSFunction preSendAjaxRequestFunction, JSFunctionDefinition
onAjaxCompleteFunction) {
+ StringBuffer result = new StringBuffer();
+
+ result.append(".drop = ");
+
+ JSFunctionDefinition definition = new JSFunctionDefinition();
+ definition.addParameter("event");
+ definition.addParameter("drag");
+
+ Map<String, Object> requestOpts = AjaxRendererUtils.buildEventOptions(context,
column);
+ //replace parameters
+ String clientId = column.getClientId(context);
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>)
requestOpts.get("parameters");
+ if (parameters != null){
+ if (parameters.containsKey(clientId)){
+ parameters.remove(clientId);
+ parameters.put(dropTargetScriptId, dropTargetScriptId);
+ }
+ }
+
+ if (preSendAjaxRequestFunction != null){
+ definition.addToBody(preSendAjaxRequestFunction.toScript()).addToBody(";");
+ }
+ definition.addToBody("var options =
").addToBody(ScriptUtils.toScript(requestOpts)).addToBody(";");
+ definition.addToBody("options.parameters['" +
org.richfaces.renderkit.DropzoneRendererContributor.DROP_TARGET_ID + "'] =
'" + dropTargetScriptId + "';");
+
+ if (onAjaxCompleteFunction != null)
+ definition.addToBody("options['" +
AjaxRendererUtils.ONCOMPLETE_ATTR_NAME + "'] = " +
onAjaxCompleteFunction.toScript() + ";");
+ //TODO nick - remove as legacy
+ definition.addToBody("Object.extend(options.parameters,drag.getParameters());");
+ definition.addToBody("var dzOptions = this.getDropzoneOptions(); if
(dzOptions.ondrop) { if (!dzOptions.ondrop.call(this, event)) return; };");
+
+ JSFunction dropFunction = AjaxRendererUtils.buildAjaxFunction(column, context);
+ dropFunction.addParameter(new JSReference("options"));
+
+ definition.addToBody(dropFunction.toScript()).addToBody(";");
+ definition.appendScript(result);
+ result.append(";");
+
+ return result.toString();
+ }
+
+ /**
+ * Build JavaScript code for drag'n drop support specialized for change table column
order event.
+ * @param context faces context
+ * @param column table column
+ * @param dropTargetScriptId id of HTML script element that contains defined
DnD.G3SimpleDropZone object
+ * @return JavaScript code
+ */
+ public String getScriptContribution(FacesContext context, UIComponent column, String
dropTargetScriptId) {
+ return getScriptContribution(context, column, dropTargetScriptId, null, null);
+ }
+
+ public String[] getScriptDependencies() {
+ return wrappedContributor.getScriptDependencies();
+ }
+
+ public String[] getStyleDependencies() {
+ return wrappedContributor.getStyleDependencies();
+ }
+
+ /**
+ * Builds options for DnD.G3SimpleDropZone JavaScript object.
+ * These options are specialized for drop target used to end changing table columns
order event.
+ * @param context faces context
+ * @param column table column
+ * @return all options needed for drop JavaScript object to work
+ */
+ public ScriptOptions buildOptions(FacesContext context, UIComponent column) {
+ ScriptOptions options = new ScriptOptions(column);
+ options.addOption("acceptedTypes",
"COLUMN_ORDER_"+column.getParent().getClientId(context));
+ return options;
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/RichTableMenuRenderer.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/RichTableMenuRenderer.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/RichTableMenuRenderer.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,390 @@
+/**
+ *
+ */
+package org.richfaces.renderkit.html;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.faces.component.UIComponent;
+
+import org.ajax4jsf.Messages;
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.JSReference;
+import org.richfaces.component.UIColumn;
+import org.richfaces.component.UIContextMenu;
+import org.richfaces.component.UIMenuGroup;
+import org.richfaces.component.UIMenuItem;
+import org.richfaces.component.UIMenuSeparator;
+import org.richfaces.component.html.ContextMenu;
+import org.richfaces.component.html.HtmlMenuGroup;
+import org.richfaces.component.html.HtmlMenuItem;
+import org.richfaces.messages.SandboxMessageUtil;
+
+/**
+ * Renderer class for table menu.
+ *
+ * @author pawelgo
+ *
+ */
+public class RichTableMenuRenderer extends TableMenuRenderer {
+
+ private static final long serialVersionUID = -6812995542681604002L;
+
+ /*
+ * Message key constants
+ */
+ private static final String MSG_COLUMNS =
"org.richfaces.component.UIExtendedDataTable.Menu.Columns";
+ private static final String MSG_SORT_ASC =
"org.richfaces.component.UIExtendedDataTable.Menu.SortAscending";
+ private static final String MSG_SORT_DESC =
"org.richfaces.component.UIExtendedDataTable.Menu.SortDescending";
+ private static final String MSG_GROUP_ON =
"org.richfaces.component.UIExtendedDataTable.Menu.GroupByColumn";
+ private static final String MSG_GROUP_OFF =
"org.richfaces.component.UIExtendedDataTable.Menu.DisableGrouping";
+
+ private int visibleColumnsCount;
+
+ private UIContextMenu menu;
+
+ /*
+ * Icon URIs
+ */
+ private static String iconColumnsURI;
+ private static String iconSortAscURI;
+ private static String iconSortDescURI;
+ private static String iconGroupURI;
+ private static String iconCheckedURI;
+ private static String iconUncheckedURI;
+
+ /**
+ * Initializes resources if they are not initialized yet. Each icon URI is
+ * kept in class field to ensure that resource URI is build only once.
+ */
+ private void initResources() {
+ if (context == null) {
+ throw new NullPointerException(Messages.getMessage(
+ Messages.CONTEXT_NULL_ERROR, "initResources"));
+ }
+
+ if (iconColumnsURI == null) {
+ iconColumnsURI = getUri(
+
getResource("/org/richfaces/renderkit/html/images/columns.png"),
+ context);
+ }
+ if (iconSortAscURI == null) {
+ iconSortAscURI = getUri(
+
getResource("/org/richfaces/renderkit/html/images/menu-sort-asc.png"),
+ context);
+ }
+ if (iconSortDescURI == null) {
+ iconSortDescURI = getUri(
+
getResource("/org/richfaces/renderkit/html/images/menu-sort-desc.png"),
+ context);
+ }
+ if (iconGroupURI == null) {
+ iconGroupURI = getUri(
+
getResource("/org/richfaces/renderkit/html/images/group-by.png"),
+ context);
+ }
+ if (iconCheckedURI == null) {
+ iconCheckedURI = getUri(
+
getResource("/org/richfaces/renderkit/html/images/checked.gif"),
+ context);
+ }
+ if (iconUncheckedURI == null) {
+ iconUncheckedURI = getUri(
+
getResource("/org/richfaces/renderkit/html/images/unchecked.gif"),
+ context);
+ }
+ }// initResources
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.renderkit.html.TableMenuRenderer#render()
+ */
+ public String render() throws IOException {
+ initResources();
+ ensureMenuBuilt();
+ String menuId = menu.getClientId(context);
+ // render menu
+ menu.encodeAll(context);
+ return menuId;
+ }// render
+
+ /**
+ *
+ * @throws IOException
+ */
+ protected void ensureMenuBuilt() throws IOException {
+ menu = null;
+ // try to get menu from children components
+ for (UIComponent comp : table.getChildren()) {
+ if ((comp.getId().equals(buildMenuId()))
+ && (comp instanceof UIContextMenu)) {
+ menu = (UIContextMenu) comp;
+ break;
+ }
+ }
+ buildMenu();
+ }
+
+ /**
+ * Builds menu id base on column for which menu is built.
+ *
+ * @return menu id
+ */
+ protected String buildMenuId() {
+ return column.getId() + "menu";
+ }
+
+ /**
+ * Creates menu and ands it to table as child.
+ *
+ * @throws IOException
+ */
+ protected void createMenu() throws IOException {
+ menu = (UIContextMenu) context.getApplication().createComponent(
+ UIContextMenu.COMPONENT_TYPE);
+ menu.setId(buildMenuId());
+ menu.setAttached(false);
+ menu.setSubmitMode("none");
+ menu.setEvent("onclick");
+ menu.setDisableDefaultMenu(false);
+
+ if (menu instanceof ContextMenu) {
+ ((ContextMenu) menu)
+ .setStyle("z-index: 100; text-align: left; font-weight:
normal;");
+
+ }
+ table.getChildren().add(menu);
+ }
+
+ /**
+ * Builds menu for current column. Creates menu if not exist yet and adds
+ * items.
+ *
+ * @throws IOException
+ */
+ protected void buildMenu() throws IOException {
+ if (menu == null) {// menu does not exist yet
+ // create menu
+ createMenu();
+ } else {// menu already exists
+ // clear menu children
+ menu.getChildren().clear();
+ }
+
+ // add menu items for sorting
+ buildSortMenuItem(menu, true);
+ buildSortMenuItem(menu, false);
+
+ UIMenuSeparator sep = (UIMenuSeparator) context.getApplication()
+ .createComponent(UIMenuSeparator.COMPONENT_TYPE);
+ menu.getChildren().add(sep);
+
+ // add menu item for grouping
+ buildGroupMenuItem(menu);
+
+ sep = (UIMenuSeparator) context.getApplication().createComponent(
+ UIMenuSeparator.COMPONENT_TYPE);
+ menu.getChildren().add(sep);
+
+ // add menu items for changing column visibility
+ UIMenuGroup group = (HtmlMenuGroup) context.getApplication()
+ .createComponent(UIMenuGroup.COMPONENT_TYPE);
+ group.setValue(SandboxMessageUtil.getMessage(context, MSG_COLUMNS,
+ new Object[] {}).getSummary());
+ group.setIcon(iconColumnsURI);
+ menu.getChildren().add(group);
+
+ Iterator<UIColumn> columns = table.getSortedColumns();
+ visibleColumnsCount = table.getVisibleColumnsCount();
+
+ while (columns.hasNext()) {
+ buildMenuItem(group, columns.next());
+ }// while
+ }// buildMenu
+
+ /**
+ * Builds menu item for sorting.
+ *
+ * @param parent
+ * parent component for created item
+ * @param asc
+ * sort direction
+ * @throws IOException
+ */
+ protected void buildSortMenuItem(UIComponent parent, boolean asc)
+ throws IOException {
+ UIMenuItem menuItem = (UIMenuItem) context.getApplication()
+ .createComponent(UIMenuItem.COMPONENT_TYPE);
+
+ menuItem.setSubmitMode("none");
+ String actionScript = null;
+ StringBuilder actionScriptBuilder = new StringBuilder();
+ if ((Boolean) column.getAttributes().get("sortable")) {
+ if (sortFunction != null) {
+ if (prepareFunction != null) {
+ actionScriptBuilder.append(prepareFunction.toScript())
+ .append("; ");
+ }
+
+ actionScriptBuilder.append(sortFunction.toScript());
+ actionScript = actionScriptBuilder.toString();
+ if (actionScript.contains("{columnId}")) {
+ String columnClientId = (String) column.getAttributes()
+ .get("columnClientId");
+ if (columnClientId == null)
+ columnClientId = column.getClientId(context);
+ actionScript = actionScript.replace("{columnId}",
+ columnClientId);
+ }
+ if (actionScript.contains("{sortDirection}"))
+ actionScript = actionScript.replace("{sortDirection}",
+ asc ? "asc" : "desc");
+ }
+ } else {
+ menuItem.setDisabled(true);
+ }
+ menuItem.setValue(SandboxMessageUtil.getMessage(context,
+ (asc ? MSG_SORT_ASC : MSG_SORT_DESC), new Object[] {})
+ .getSummary());
+ menuItem.setIcon((asc ? iconSortAscURI : iconSortDescURI));
+ if (menuItem instanceof HtmlMenuItem) {
+ ((HtmlMenuItem) menuItem)
+ .setOnclick(actionScript == null ? "return false;"
+ : actionScript);
+ }
+
+ // add item to parent
+ parent.getChildren().add(menuItem);
+ }// buildSortMenuItem
+
+ /**
+ * Builds menu item for sorting.
+ *
+ * @param parent
+ * parent component for created item
+ * @throws IOException
+ */
+ protected void buildGroupMenuItem(UIComponent parent) throws IOException {
+ UIMenuItem menuItem = (UIMenuItem) context.getApplication()
+ .createComponent(UIMenuItem.COMPONENT_TYPE);
+
+ menuItem.setSubmitMode("none");
+ String actionScript = null;
+ StringBuilder actionScriptBuilder = new StringBuilder();
+ boolean isGroupingColumn = column.getId().equalsIgnoreCase(
+ table.getGroupingColumnId());
+ if ((Boolean) column.getAttributes().get("sortable")) {
+ if (sortFunction != null) {
+ if (prepareFunction != null) {
+ actionScriptBuilder.append(prepareFunction.toScript())
+ .append("; ");
+ }
+ actionScriptBuilder.append(groupFunction.toScript());
+ actionScript = actionScriptBuilder.toString();
+ if (actionScript.contains("{columnId}")) {
+ String columnClientId = (String) column.getAttributes()
+ .get("columnClientId");
+ if (columnClientId == null)
+ columnClientId = column.getClientId(context);
+ if (isGroupingColumn) {
+ columnClientId = "";
+ }
+ actionScript = actionScript.replace("{columnId}",
+ columnClientId);
+ }
+ }
+ } else {
+ menuItem.setDisabled(true);
+ }
+
+ menuItem.setValue(SandboxMessageUtil.getMessage(context,
+ (isGroupingColumn ? MSG_GROUP_OFF : MSG_GROUP_ON),
+ new Object[] {}).getSummary());
+ menuItem.setIcon(iconGroupURI);
+ if (menuItem instanceof HtmlMenuItem) {
+ ((HtmlMenuItem) menuItem)
+ .setOnclick(actionScript == null ? "return false;"
+ : actionScript);
+ }
+
+ // add item to menu
+ parent.getChildren().add(menuItem);
+ }// buildSortMenuItem
+
+ /**
+ * Builds menu items for changing column visibility.
+ *
+ * @param parent
+ * parent component for created item
+ * @param col
+ * column component correspond to created item
+ * @throws IOException
+ */
+ protected void buildMenuItem(UIComponent parent, UIColumn col)
+ throws IOException {
+ if (col instanceof UIColumn) {
+ UIColumn dataColumn = (UIColumn) col;
+ UIMenuItem menuItem = (UIMenuItem) context.getApplication()
+ .createComponent(UIMenuItem.COMPONENT_TYPE);
+
+ menuItem.setSubmitMode("none");
+ Boolean v = dataColumn.isVisible();
+ boolean columnVisible = (v == null ? Boolean.TRUE : v);
+ String actionScript = null;
+ StringBuilder actionScriptBuilder = new StringBuilder();
+
+ menuItem.setStyle("text-align: left;");
+
+ if ((!columnVisible) || (visibleColumnsCount > 1)) {
+ if (changeColumnVisibilityFunction != null) {
+ if (prepareFunction != null) {
+ actionScriptBuilder.append(prepareFunction.toScript())
+ .append("; ");
+ }
+ actionScriptBuilder.append(changeColumnVisibilityFunction
+ .toScript());
+ actionScript = actionScriptBuilder.toString();
+ if (actionScript.contains("{columnId}"))
+ actionScript = actionScript.replace("{columnId}",
+ dataColumn.getId());
+ }
+ }// if
+ menuItem.setValue(dataColumn.getColumnLabel());
+ menuItem.setIcon(columnVisible ? iconCheckedURI : iconUncheckedURI);
+ if (menuItem instanceof HtmlMenuItem) {
+ ((HtmlMenuItem) menuItem)
+ .setOnclick(actionScript == null ? "return false;"
+ : actionScript);
+ }
+
+ // add item to menu
+ parent.getChildren().add(menuItem);
+ }
+ }// buildMenuItem
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.renderkit.html.TableMenuRenderer#createShowMenuEventFunction()
+ */
+ public JSFunctionDefinition createShowMenuEventFunction() {
+ JSFunctionDefinition definition = new JSFunctionDefinition();
+ definition.addParameter("event");
+ definition.addParameter("columnId");
+ definition.addParameter("menuId");
+ JSFunction invocation = new JSFunction(
+ "Richfaces.componentControl.performOperation");
+ invocation.addParameter(new JSReference("event"));
+ invocation.addParameter(new JSReference("menuId"));
+ invocation.addParameter("show");
+ // invocation.addParameter(new
JSReference("{'columnId':columnId}"));
+ invocation.addParameter(new JSReference("{}"));
+ invocation.addParameter(Boolean.FALSE);
+ definition.addToBody(invocation.toScript()).addToBody(";\n");
+ return definition;
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/SimpleTableMenuRenderer.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/SimpleTableMenuRenderer.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/SimpleTableMenuRenderer.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,132 @@
+/**
+ *
+ */
+package org.richfaces.renderkit.html;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.faces.context.ResponseWriter;
+
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.JSReference;
+import org.ajax4jsf.renderkit.AjaxRendererUtils;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.richfaces.component.UIColumn;
+
+/**
+ * @author pawelgo
+ *
+ */
+public class SimpleTableMenuRenderer extends TableMenuRenderer {
+
+ private static final long serialVersionUID = -3907452284006250197L;
+
+ private int visibleColumnsCount;
+ private ResponseWriter writer;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.renderkit.html.TableMenuRenderer#render()
+ */
+ public String render() throws IOException {
+
+ String menuId = table.getClientId(context) + ":tm";
+
+ Iterator<UIColumn> columns = table.getSortedColumns();
+ visibleColumnsCount = table.getVisibleColumnsCount();
+
+ writer = context.getResponseWriter();
+ // print main menu DIV element
+ writer.startElement(HTML.DIV_ELEM, table);
+
+ writer.writeAttribute(HTML.id_ATTRIBUTE, menuId, null);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "dt-menu", null);
+ writer.writeAttribute(HTML.style_ATTRIBUTE,
+ "z-index: 15005; visibility: visible; left: 0px; top: 0px;",
+ null);
+ // writer.writeAttribute(HTML.style_ATTRIBUTE, "position: absolute;
+ // z-index: 15005; visibility: visible; left: 0px; top: 0px;", null);
+ writer.startElement("ul", table);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "dt-menu-list", null);
+ for (; columns.hasNext();) {
+ renderMenuItem(columns.next());
+ }// for
+ writer.endElement("ul");
+ writer.endElement(HTML.DIV_ELEM);
+ return menuId;
+ }// render
+
+ protected void renderMenuItem(UIColumn column) throws IOException {
+ if (column instanceof UIColumn) {
+ UIColumn dataColumn = (UIColumn) column;
+ Boolean v = dataColumn.isVisible();
+ boolean columnVisible = (v == null ? Boolean.TRUE : v);
+ String actionScript = null;
+ if ((!columnVisible) || (visibleColumnsCount > 1)) {
+ boolean ajaxSingle = true;
+ Map<String, Object> requestOpts = AjaxRendererUtils
+ .buildEventOptions(context, dataColumn);
+
+ if (onAjaxCompleteFunction != null)
+ requestOpts.put(AjaxRendererUtils.ONCOMPLETE_ATTR_NAME,
+ onAjaxCompleteFunction);
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> parameters = (Map<String, Object>)
requestOpts
+ .get("parameters");
+ if (parameters == null) {
+ parameters = new HashMap<String, Object>();
+ requestOpts.put("parameters", parameters);
+ }
+ if (ajaxSingle) {
+ if (!parameters
+ .containsKey(AjaxRendererUtils.AJAX_SINGLE_PARAMETER_NAME))
+ parameters.put(
+ AjaxRendererUtils.AJAX_SINGLE_PARAMETER_NAME,
+ dataColumn.getParent().getClientId(context));
+ if (!requestOpts.containsKey("control"))
+ requestOpts.put("control", JSReference.THIS);
+ }
+ parameters.put(dataColumn.getParent().getClientId(context)
+ + ":" + CHANGE_COL_VISIBILITY, dataColumn.getId());
+
+ JSFunction dropFunction = AjaxRendererUtils.buildAjaxFunction(
+ dataColumn, context);
+ dropFunction.addParameter(requestOpts);
+ actionScript = dropFunction.toScript();
+ }// if
+
+ writer.startElement("li", dataColumn);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "dt-menu-list-item"
+ + (columnVisible ? " dt-menu-item-checked" : ""),
null);
+
+ writer.startElement(HTML.a_ELEMENT, dataColumn);
+ writer.writeAttribute(HTML.HREF_ATTR, "#", null);
+ writer.writeAttribute(HTML.class_ATTRIBUTE,
+ "dt-menu-item dt-menu-check-item", null);
+ actionScript = (actionScript == null ? "return false;"
+ : actionScript + ";return false;");
+ writer.writeAttribute(HTML.onclick_ATTRIBUTE, actionScript, null);
+ writer.startElement(HTML.IMG_ELEMENT, dataColumn);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "dt-menu-item-icon",
+ null);
+ writer.writeAttribute(HTML.src_ATTRIBUTE, getResource(
+ "/org/richfaces/renderkit/html/images/s.gif").getUri(
+ context, null), null);
+ writer.endElement(HTML.IMG_ELEMENT);
+ writer.writeText(dataColumn.getColumnLabel(), null);
+ writer.endElement(HTML.a_ELEMENT);
+ writer.endElement("li");
+ }
+ }// encodeMenuItem
+
+ public JSFunctionDefinition createShowMenuEventFunction() {
+ return new JSFunctionDefinition();
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableDragDropRenderer.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableDragDropRenderer.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableDragDropRenderer.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,238 @@
+/**
+ *
+ */
+package org.richfaces.renderkit.html;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.org.w3c.tidy.EntityTable;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.richfaces.component.UIColumn;
+import org.richfaces.json.JSONException;
+import org.richfaces.json.JSONObject;
+import org.richfaces.renderkit.DragIndicatorRendererBase;
+import org.richfaces.renderkit.ScriptOptions;
+
+/**
+ * Renderer for support drag'n drop for
+ * {@link org.richfaces.component.UIExtendedDataTable} component specialized for
+ * changing table columns order event.
+ *
+ * @author pawelgo
+ *
+ */
+public class TableDragDropRenderer implements Serializable {
+
+ private static final long serialVersionUID = -8059307641808179967L;
+
+ public final static String DRAG_SOURCE_SCRIPT_ID = "dnd_drag_script";
+
+ public final static String DROP_TARGET_SCRIPT_ID = "dnd_drop_script";
+
+ public final static String DROP_TARGET_BEFORE = "_left";
+
+ public final static String DROP_TARGET_AFTER = "_right";
+
+ private FacesContext context;
+
+ private JSFunctionDefinition onAjaxCompleteFunctionDef;
+
+ private JSFunction preSendAjaxRequestFunction;
+
+ private TableDragDropRenderer(FacesContext context) {
+ super();
+ this.context = context;
+ }
+
+ /**
+ * Creates new instance.
+ *
+ * @param context
+ * faces context
+ * @return instance object
+ */
+ public static TableDragDropRenderer getInstance(FacesContext context) {
+ return new TableDragDropRenderer(context);
+ }
+
+ /**
+ * Encodes child scripts. It uses
+ * {@link org.richfaces.renderkit.DragIndicatorRendererBase} renderer and
+ * overwrites marker for DEFAULT drag indicator state. Drag indicator image
+ * is the same in DEFAULT and REJECT states.
+ *
+ * @param context
+ * faces context
+ * @param component
+ * table component
+ * @throws IOException
+ */
+ public void encodeChildScripts(FacesContext context, UIComponent component)
+ throws IOException {
+ // new DragIndicatorRendererBase().encodeChildScripts(context,
+ // component);
+ new DragIndicatorRendererBase() {
+ public void encodeChildScripts(FacesContext context,
+ UIComponent component) throws IOException {
+ super.encodeChildScripts(context, component);
+ // redefine DEFAULT marker to be like REJECT marker
+ ResponseWriter responseWriter = context.getResponseWriter();
+ responseWriter.write("elt.markers['" + DEFAULT +
"'] = \"");
+ responseWriter.write(getPredefinedMarker(context, REJECT));
+ responseWriter.write("\";\n");
+ }
+ }.encodeChildScripts(context, component);
+ }
+
+ /**
+ * Renders support for drag operation specialized for changing table columns
+ * order event.
+ *
+ * @param column
+ * table column
+ * @param dragSourceId
+ * drag source HTML element id
+ * @param indicatorId
+ * drag indicator id
+ * @param dragLabel
+ * label to be displayed in indicator
+ * @throws IOException
+ */
+ public void renderDragSupport(UIColumn column, String dragSourceId,
+ String indicatorId, String dragLabel) throws IOException {
+ StringBuffer buffer = new StringBuffer();
+ JSFunction function = new JSFunction("new DnD.G3SimpleDraggable");
+ function.addParameter(dragSourceId);
+ String dragSourceScriptId = column.getClientId(context) + ":"
+ + DRAG_SOURCE_SCRIPT_ID;
+ DraggableRendererContributor contributor = DraggableRendererContributor
+ .getInstance();
+ ScriptOptions dragOptions = contributor.buildOptions(context, column,
+ dragSourceScriptId, indicatorId);
+
+ JSONObject dndParams = new JSONObject();
+ try {
+ dndParams.put("label", dragLabel == null ? "" :
dragLabel);
+ } catch (JSONException e) {
+ }
+ dragOptions.addOption("dndParams", dndParams.toString());
+
+ function.addParameter(dragOptions);
+ function.appendScript(buffer);
+
+ String scriptContribution = contributor.getScriptContribution(context,
+ column);
+ if (scriptContribution != null && scriptContribution.length() != 0) {
+ buffer.append(scriptContribution);
+ }
+
+ ResponseWriter writer = context.getResponseWriter();
+
+ writer.startElement(HTML.SCRIPT_ELEM, column);
+ writer.writeAttribute("id", dragSourceScriptId, "id");
+ writer.write(escapeHtmlEntities(buffer));
+ writer.endElement(HTML.SCRIPT_ELEM);
+ }// renderDragSupport
+
+ /**
+ * Renders support for drop operation specialized for changing table columns
+ * order event.
+ *
+ * @param column
+ * table column
+ * @param dropTargetId
+ * drop target HTML element id
+ * @param before
+ * true if target is positioned before column
+ * @throws IOException
+ */
+ public void renderDropSupport(UIColumn column, String dropTargetId,
+ boolean before) throws IOException {
+ // RendererContributor contributor =
+ // DropzoneRendererContributor.getInstance();
+ DropzoneRendererContributor contributor = DropzoneRendererContributor
+ .getInstance();
+ StringBuffer buffer = new StringBuffer();
+ JSFunction function = new JSFunction("new DnD.G3SimpleDropZone");
+ function.addParameter(dropTargetId);
+ ScriptOptions dropOptions = contributor.buildOptions(context, column);
+ JSONObject dndParams = new JSONObject();
+ dropOptions.addOption("dndParams", dndParams.toString());
+
+ function.addParameter(dropOptions);
+ function.appendScript(buffer);
+
+ String dropTargetScriptId = column.getClientId(context) + ":"
+ + DROP_TARGET_SCRIPT_ID
+ + (before ? DROP_TARGET_BEFORE : DROP_TARGET_AFTER);
+ String scriptContribution = contributor.getScriptContribution(context,
+ column, dropTargetScriptId, preSendAjaxRequestFunction,
+ onAjaxCompleteFunctionDef);
+ if (scriptContribution != null && scriptContribution.length() != 0) {
+ buffer.append(scriptContribution);
+ }
+
+ ResponseWriter writer = context.getResponseWriter();
+
+ writer.startElement(HTML.SCRIPT_ELEM, column);
+ writer.writeAttribute("id", dropTargetScriptId, "id");
+ writer.write(escapeHtmlEntities(buffer));
+ writer.endElement(HTML.SCRIPT_ELEM);
+ }// renderDropSupport
+
+ /**
+ * Help method for escaping HTML entities.
+ *
+ * @param orig
+ * string to escape
+ * @return string with escaped HTML entities
+ */
+ protected String escapeHtmlEntities(CharSequence orig) {
+ StringBuffer buff = new StringBuffer(orig);
+ EntityTable defaultEntityTable = EntityTable.getDefaultEntityTable();
+ Matcher matcher = Pattern.compile("\\&\\w+\\;").matcher(orig);
+ int delta = 0;
+ while (matcher.find()) {
+ String name = matcher.group().substring(0,
+ matcher.group().length() - 1);
+ int code = defaultEntityTable.entityCode(name);
+ if (0 != code) {
+ String replacement = "&#" + code + ";";
+ buff.replace(matcher.start() - delta, matcher.end() - delta,
+ replacement);
+ delta = delta + matcher.group().length() - replacement.length();
+ }
+ }
+ return buff.toString();
+ }
+
+ public JSFunctionDefinition getOnAjaxCompleteFunctionDef() {
+ return onAjaxCompleteFunctionDef;
+ }
+
+ /**
+ * Set JavaScript function to be called on AJAX request complete.
+ *
+ * @param onAjaxCompleteFunction
+ * JavaScriot function to set
+ */
+ public void setOnAjaxCompleteFunctionDef(
+ JSFunctionDefinition onAjaxCompleteFunctionDef) {
+ this.onAjaxCompleteFunctionDef = onAjaxCompleteFunctionDef;
+ }
+
+ public void setPreSendAjaxRequestFunction(
+ JSFunction preSendAjaxRequestFunction) {
+ this.preSendAjaxRequestFunction = preSendAjaxRequestFunction;
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableMenuRenderer.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableMenuRenderer.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableMenuRenderer.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,177 @@
+/**
+ *
+ */
+package org.richfaces.renderkit.html;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.resource.InternetResource;
+import org.ajax4jsf.resource.InternetResourceBuilder;
+import org.ajax4jsf.resource.ResourceNotFoundException;
+import org.ajax4jsf.webapp.WebXml;
+import org.richfaces.component.UIColumn;
+import org.richfaces.component.UIExtendedDataTable;
+
+/**
+ * Abstract renderer class for table menu.
+ *
+ * @author pawelgo
+ *
+ */
+public abstract class TableMenuRenderer implements Serializable {
+
+ public final static String CHANGE_COL_VISIBILITY = "change_col_v";
+
+ protected FacesContext context;
+ protected UIExtendedDataTable table;
+ protected UIColumn column;
+
+ protected JSFunction changeColumnVisibilityFunction;
+ protected JSFunction sortFunction;
+ protected JSFunction groupFunction;
+ protected JSFunction prepareFunction;
+ protected JSFunctionDefinition onAjaxCompleteFunction;
+
+ protected static InternetResourceBuilder resourceBuilder;
+
+ /**
+ * Performs initial operations and renders table menu.
+ *
+ * @param context
+ * faces context
+ * @param table
+ * table component
+ * @param column
+ * current column
+ * @return created menu (DOM element) id
+ * @throws IOException
+ */
+ public String renderMenu(FacesContext context, UIExtendedDataTable table,
+ UIColumn column) throws IOException {
+ this.context = context;
+ this.table = table;
+ this.column = column;
+ return render();
+ }
+
+ /**
+ * Renders table menu.
+ *
+ * @return created menu (DOM element) id
+ * @throws IOException
+ */
+ protected abstract String render() throws IOException;
+
+ /**
+ * Creates JavaScript code to be executed in order to show menu on some
+ * event.
+ *
+ * @return JavaScript code causes showing menu
+ */
+ public abstract JSFunctionDefinition createShowMenuEventFunction();
+
+ /**
+ * Base stub method for produce Internet resource ( image, script ... )
+ * since resources must be implemented in "lightweight" pattern, it
+ * instances put in internal map to caching.
+ *
+ * @param resourceURI -
+ * relative ( to renderer class ) URI to resource in jar or key
+ * for generate ( in Java2D , for example ).
+ * @return - resource instance for this URI.
+ * @throws ResourceNotFoundException -
+ * if requested resource not instantiated.
+ */
+ public InternetResource getResource(String resourceURI)
+ throws FacesException {
+ return getResourceBuilder().createResource(null, resourceURI);
+ }
+
+ protected static InternetResourceBuilder getResourceBuilder() {
+ if (resourceBuilder == null) {
+ resourceBuilder = InternetResourceBuilder.getInstance();
+ }
+ return resourceBuilder;
+ }
+
+ protected String getUri(InternetResource resource, FacesContext context) {
+ return getFacesResourceURL(context, resource.getKey());
+ }// getUri
+
+ protected String getFacesResourceURL(FacesContext context, String Url) {
+ WebXml webXml = WebXml.getInstance(context);
+ StringBuffer buf = new StringBuffer();
+ buf.append(webXml.getResourcePrefix()).append(Url);
+ // Insert suffix mapping
+ if (webXml.isPrefixMapping()) {
+ buf.insert(0, webXml.getFacesFilterPrefix());
+ } else {
+ int index;
+ if ((index = buf.indexOf("?")) >= 0) {
+ buf.insert(index, webXml.getFacesFilterSuffix());
+ } else {
+ buf.append(webXml.getFacesFilterSuffix());
+ }
+ }
+ return buf.toString();
+ }// getFacesResourceURL
+
+ /**
+ * Sets function to be called on complete AJAX request fired by menu action
+ *
+ * @param functionDefinition
+ * function to be called on complete AJAX request
+ */
+ public void setOnAjaxCompleteFunction(
+ JSFunctionDefinition functionDefinition) {
+ this.onAjaxCompleteFunction = functionDefinition;
+ }
+
+ /**
+ * Set JavaScript function for change column visibility.
+ *
+ * @param changeColumnVisibilityFunction
+ * JavaScript function
+ */
+ public void setChangeColumnVisibilityFunction(
+ JSFunction changeColumnVisibilityFunction) {
+ this.changeColumnVisibilityFunction = changeColumnVisibilityFunction;
+ }
+
+ /**
+ * Set JavaScript function for sort table.
+ *
+ * @param sortFunction
+ * JavaScript function
+ */
+ public void setSortFunction(JSFunction sortFunction) {
+ this.sortFunction = sortFunction;
+ }
+
+ /**
+ * Set JavaScript function for group table.
+ *
+ * @param groupFunction
+ * JavaScript function
+ */
+ public void setGroupFunction(JSFunction groupFunction) {
+ this.groupFunction = groupFunction;
+ }
+
+ /**
+ * Set JavaScript function called before send AJAX request.
+ *
+ * @param prepareFunction
+ * JavaScript function
+ */
+ public void setPrepareFunction(JSFunction prepareFunction) {
+ this.prepareFunction = prepareFunction;
+ }
+
+}
Added:
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableSelectionRendererContributor.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableSelectionRendererContributor.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/java/org/richfaces/renderkit/html/TableSelectionRendererContributor.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,325 @@
+/**
+ *
+ */
+package org.richfaces.renderkit.html;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.component.UIComponent;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.Converter;
+
+import org.ajax4jsf.context.AjaxContext;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.richfaces.model.selection.ClientSelection;
+import org.richfaces.model.selection.Selection;
+import org.richfaces.model.selection.SimpleSelection;
+import org.richfaces.renderkit.CompositeRenderer;
+import org.richfaces.renderkit.RendererContributor;
+import org.richfaces.renderkit.ScriptOptions;
+import org.richfaces.renderkit.TableHolder;
+import org.richfaces.renderkit.html.HTMLEncodingContributor;
+
+import org.richfaces.component.UIExtendedDataTable;
+
+/**
+ * Renderer contributor based on
+ * {@link org.richfaces.renderkit.html.SelectionRendererContributor}} adapted
+ * for {@link org.richfaces.component.UIExtendedDataTable} component.
+ *
+ * @author pawelgo
+ *
+ */
+public class TableSelectionRendererContributor implements RendererContributor,
+ HTMLEncodingContributor {
+
+ public static final String CLIENT_SELECTION = "clientSelection";
+
+ public static final String getSelectionInputName(FacesContext context,
+ UIExtendedDataTable table) {
+ String id = table.getBaseClientId(context) + ":s";
+ return id;
+ }
+
+ public static final String getGridId(FacesContext context,
+ UIExtendedDataTable table) {
+ return table.getBaseClientId(context);
+ }
+
+ public void decode(FacesContext context, UIComponent component,
+ CompositeRenderer compositeRenderer) {
+
+ final UIExtendedDataTable table = (UIExtendedDataTable) component;
+
+ ExternalContext externalContext = context.getExternalContext();
+ Map<String, String> requestParamMap = externalContext
+ .getRequestParameterMap();
+ Application application = context.getApplication();
+
+ String id = getSelectionInputName(context, table);
+
+ String value = (String) requestParamMap.get(id);
+ if (value != null) {
+
+ Converter converter = application
+ .createConverter(ClientSelection.class);
+
+ ClientSelection _oldClientSelection = (ClientSelection) table
+ .getAttributes().get(CLIENT_SELECTION);
+
+ final ClientSelection oldClientSelection = _oldClientSelection == null ? new
ClientSelection()
+ : _oldClientSelection;
+
+ final ClientSelection clientSelection = (ClientSelection) converter
+ .getAsObject(context, table, value);
+
+ // final ScrollableDataTableRendererState state =
+ // ScrollableDataTableRendererState.createState(context, grid);
+ // state.setRowIndex(ScrollableDataTableUtils.getClientRowIndex(grid));
+
+ final TableHolder holder = new TableHolder(table);
+
+ final SimpleSelection simpleSelection = table.getSelection() == null ? new
SimpleSelection()
+ : (SimpleSelection) table.getSelection();
+
+ if (clientSelection.isReset() || clientSelection.isSelectAll()) {
+ simpleSelection.clear();
+ }
+
+ try {
+ table.walk(context, new DataVisitor() {
+ public void process(FacesContext context, Object rowKey,
+ Object argument) throws IOException {
+
+ // TableHolder holder = (TableHolder) argument;
+ // int i = state.getRowIndex();
+ int i = holder.getRowCounter();
+
+ if (shouldAddToSelection(i, oldClientSelection,
+ clientSelection)) {
+
+ simpleSelection.addKey(rowKey);
+
+ } else if (shouldRemoveFromSelection(i,
+ oldClientSelection, clientSelection)) {
+
+ simpleSelection.removeKey(rowKey);
+
+ }
+
+ if (i == clientSelection.getActiveRowIndex()) {
+ table.setActiveRowKey(rowKey);
+ }
+ holder.nextRow();
+
+ }
+ }, holder);
+ } catch (IOException e) {
+ throw new FacesException(e);
+ }
+
+ table.setSelection(simpleSelection);
+
+ ValueExpression selectionBinding = table
+ .getValueExpression("selection");
+ if (selectionBinding != null) {
+ selectionBinding.setValue(context.getELContext(),
+ simpleSelection);
+ }
+ }
+
+ // ScrollableDataTableRendererState.restoreState(context);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.renderkit.RendererContributor#getAcceptableClass()
+ */
+ public Class<?> getAcceptableClass() {
+ return UIExtendedDataTable.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
org.richfaces.renderkit.RendererContributor#getScriptContribution(javax.faces.context.FacesContext,
+ * javax.faces.component.UIComponent)
+ */
+ public String getScriptContribution(FacesContext context,
+ UIComponent component) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.renderkit.RendererContributor#getScriptDependencies()
+ */
+ public String[] getScriptDependencies() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.renderkit.RendererContributor#getStyleDependencies()
+ */
+ public String[] getStyleDependencies() {
+ return null;
+ }
+
+ public ScriptOptions buildOptions(FacesContext context,
+ UIComponent component) {
+ ScriptOptions scriptOptions = new ScriptOptions(component);
+ scriptOptions.addOption("selectionInput", getSelectionInputName(
+ context, (UIExtendedDataTable) component));
+ scriptOptions.addOption("gridId", getGridId(context,
+ (UIExtendedDataTable) component));
+ Map<String, Object> 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);
+
+ attribut = attributes.get("selectionMode");
+ if (attribut == null) {
+ attribut = "";
+ }
+ scriptOptions.addOption("selectionMode", attribut);
+
+ attribut = attributes.get("onselectionchange");
+ if (attribut == null) {
+ attribut = "";
+ }
+ JSFunctionDefinition function = new JSFunctionDefinition();
+ function.addToBody(attribut);
+ scriptOptions.addEventHandler("onselectionchange", function);
+ return scriptOptions;
+ }
+
+ public void encode(FacesContext context, UIComponent component)
+ throws IOException {
+ UIExtendedDataTable grid = (UIExtendedDataTable) component;
+ encodeSelection(context, grid);
+ writeSelection(context, grid);
+ }
+
+ // Decide whether to add new row to selection based on comparison with old
+ // one
+ public boolean shouldAddToSelection(int i, ClientSelection oldSelection,
+ ClientSelection newSelection) {
+
+ return newSelection.isSelectAll()
+ || (newSelection.isSelected(i) && (!oldSelection.isSelected(i) ||
newSelection
+ .isReset()));
+ }
+
+ // Decide whether to remove new row to selection based on comparison with
+ // old one
+ public boolean shouldRemoveFromSelection(int i,
+ ClientSelection oldSelection, ClientSelection newSelection) {
+ return !newSelection.isReset()
+ && (!newSelection.isSelectAll() &&
(!newSelection.isSelected(i) && oldSelection
+ .isSelected(i)));
+ }
+
+ private void encodeSelection(FacesContext context,
+ final UIExtendedDataTable table) throws IOException {
+
+ // final ScrollableDataTableRendererState state =
+ // ScrollableDataTableRendererState.createState(context, grid);
+ // state.setRowIndex(ScrollableDataTableUtils.getClientRowIndex(grid));
+
+ final TableHolder holder = new TableHolder(table);
+
+ final Selection gridSelection = table.getSelection() == null ? new
SimpleSelection()
+ : table.getSelection();
+ final ClientSelection clientSelection = new ClientSelection();
+
+ table.walk(context, new DataVisitor() {
+ public void process(FacesContext context, Object rowKey,
+ Object argument) throws IOException {
+
+ // TableHolder holder = (TableHolder) argument;
+
+ if (gridSelection.isSelected(rowKey)) {
+
+ int i = holder.getRowCounter();
+
+ clientSelection.addIndex(i);
+ }
+
+ if (rowKey.equals(table.getActiveRowKey())) {
+ clientSelection.setActiveRowIndex(holder.getRowCounter());
+ }
+
+ holder.nextRow();
+
+ }
+ }, holder);
+
+ // ScrollableDataTableRendererState.restoreState(context);
+ table.getAttributes().put(CLIENT_SELECTION, clientSelection);
+ }
+
+ /**
+ * Get client selection from the component, transform it into string form,
+ * and write it as hidden input
+ *
+ * @param context
+ * faces context
+ * @param table
+ * table component
+ * @throws IOException
+ */
+ public void writeSelection(FacesContext context, UIExtendedDataTable table)
+ throws IOException {
+
+ Application application = context.getApplication();
+
+ Converter converter = application
+ .createConverter(ClientSelection.class);
+
+ ClientSelection selection = (ClientSelection) table.getAttributes()
+ .get(CLIENT_SELECTION);
+ String string = converter.getAsString(context, table, selection);
+
+ if (string == null) {
+ string = "";
+ }
+
+ string += selection.getActiveRowIndex();
+
+ String id = getSelectionInputName(context, table);
+
+ ResponseWriter writer = context.getResponseWriter();
+ writer.startElement(HTML.INPUT_ELEM, table);
+ 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, string, null);
+ writer.endElement(HTML.INPUT_ELEM);
+
+ AjaxContext ajaxContext = AjaxContext.getCurrentInstance(context);
+
+ if (ajaxContext.isAjaxRequest()) {
+ ajaxContext.addRenderedArea(id);
+ }
+
+ }
+}
Added: trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/box/Box.js
===================================================================
--- trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/box/Box.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/box/Box.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,250 @@
+/**
+ * Box.js Date created: 6.04.2007
+ * Copyright (c) 2007 Exadel Inc.
+ * @author Denis Morozov <dmorozov(a)exadel.com>
+ */
+ClientUILib.declarePackage("ClientUI.common.box.Box");
+
+
+/*
+ * Base class for all ui controls
+ *
+ * TODO: description of control
+ *
+ * TODO: usage description
+ * Usage:
+ * ClientUILib.declarePackage("ClientUI.common");
+ * ClientUILib.requireClass("ClientUI.common.box.Box");
+ * var ClientUI.MyControl = Class.create({
+ * CLASSDEF : {
+ * name: 'ClientUI.MyControl',
+ * parent: ClientUI.common.box.Box
+ * },
+ * initialize:function() {
+ * this.parentClass().constructor().call(this)
+ * alert("A new " + this.getClass().className + " was created")
+ * }
+ * })
+ */
+ClientUI.common.box.Box = Class.create({
+
+ initialize: function(element, parentElement, dontUpdateStyles) {
+ this.element = $(element);
+ if(!this.element) {
+ this.element = $(document.createElement("div"));
+ if($(parentElement)) {
+ $(parentElement).appendChild(this.element);
+ }
+ else {
+ document.body.appendChild(this.element);
+ }
+ }
+ //http://jira.jboss.com/jira/browse/RF-2068
+ //this.element.wrapper = this;
+ if(!this.element.parentNode && $(parentElement)) {
+ $(parentElement).appendChild(this.element);
+ }
+
+ if(!this.element.id) {
+ this.element.id = "ClientUI_Box" + ClientUI_common_box_Box_idGenerator++;
+ }
+ if(!dontUpdateStyles) {
+ this.element.setStyle({overflow: 'hidden'});
+ this.element.setStyle({whiteSpace: 'nowrap'});
+ }
+ },
+
+ setParent: function(newParent) {
+ if(this.element.parentNode) {
+ this.element.parentNode.removeChild(this.element);
+ }
+ if(newParent) {
+ if(newParent.getElement) {
+ newParent = newParent.getElement();
+ }
+ $(newParent).appendChild(this.element);
+ }
+ return this;
+ },
+ getElement: function() {
+ return this.element;
+ },
+ getHeight: function() {
+ var el = this.getElement();
+ if(el.tagName.toLowerCase() != "body") {
+ var h = el.offsetHeight;
+ return h>0 ? h : (this.element.boxHeight ? parseInt(this.element.boxHeight) : 0);
+ }
+
+ if (self.innerHeight) { // all except Explorer
+ return self.innerHeight;
+ }
+ else if (document.documentElement && document.documentElement.clientHeight) {
+ // Explorer 6 Strict Mode
+ return document.documentElement.clientHeight;
+ }
+ else if (document.body) { // other Explorers
+ return document.body.clientHeight;
+ }
+ },
+ isModified: false,
+ setHeight: function(newHeight) {
+ this.element.boxHeight = newHeight;
+ if(Validators.IsNumber(newHeight)) {
+ if(newHeight<0) newHeight = 0;
+ newHeight += "px";
+ }
+ this.element.setStyle({height: newHeight});
+ isModified = true;
+ return this;
+ },
+ getWidth: function() {
+ var el = this.getElement();
+ if(el.tagName.toLowerCase() != "body") {
+ var w = el.offsetWidth;
+ return w>0 ? w : (this.element.boxWidth ? parseInt(this.element.boxWidth) : 0);
+ }
+
+ if (self.innerHeight) {// all except Explorer
+ return self.innerWidth;
+ }
+ else if (document.documentElement && document.documentElement.clientHeight) {
+ // Explorer 6 Strict Mode
+ return document.documentElement.clientWidth;
+ }
+ else if (document.body) { // other Explorers
+ return document.body.clientWidth;
+ }
+ },
+ setWidth: function(newWidth) {
+ this.element.boxWidth = newWidth;
+ if(Validators.IsNumber(newWidth)) {
+ if(newWidth<0) newWidth = 0;
+ newWidth += "px";
+ }
+ this.element.setStyle({width: newWidth});
+ isModified = true;
+ return this;
+ },
+ moveToX: function(x) {
+ if(Validators.IsNumber(x)) {x += "px";}
+ this.getElement().setStyle({left: x});
+ isModified = true;
+ return this;
+ },
+ moveToY: function(y) {
+ if(Validators.IsNumber(y)) {y += "px";}
+ this.getElement().setStyle({top: y});
+ isModified = true;
+ return this;
+ },
+ moveTo: function(x, y) {
+ this.moveToX(x);
+ this.moveToY(y);
+ return this;
+ },
+ hide: function() {
+ Element.hide(this.element);
+ isModified = true;
+ return this;
+ },
+ show: function() {
+ Element.show(this.element);
+ isModified = true;
+ return this;
+ },
+ updateLayout: function() {
+ isModified = false;
+ return this;
+ },
+ getViewportWidth: function() {
+ if(this.getElement().tagName.toLowerCase() != "body") {
+ var width = 0;
+ if( this.getElement().clientWidth ) {
+ width = this.getElement().clientWidth;
+ }
+ else if( this.getElement().innerWidth ) {
+ width = this.getElement().innerWidth - getScrollerWidth();
+ }
+
+ if(ClientUILib.isGecko) {
+ width -= this.getPadding("lr");
+ }
+ return width;
+ }
+
+ return this.getWidth();
+ },
+ getViewportHeight: function() {
+ if(this.getElement().tagName.toLowerCase() != "body") {
+ var height = 0;
+ if( this.getElement().clientHeight ) {
+ height = this.getElement().clientHeight;
+ }
+ else if( this.getElement().innerHeight ) {
+ height = this.getElement().innerHeight - getScrollerWidth();
+ }
+
+ if(ClientUILib.isGecko) {
+ height -= this.getPadding("tb");
+ }
+ return height;
+ }
+ return this.getHeight();
+ },
+ /**
+ * Gets the width of the border(s) for the specified side(s)
+ * @param {String} side Can be t, l, r, b or any combination of those to add multiple
values. For example,
+ * passing lr would get the border (l)eft width + the border (r)ight width.
+ * @return {Number} The width of the sides passed added together
+ */
+ getBorderWidth : function(side){
+ return this.getStyles(side, this.borders);
+ },
+
+ /**
+ * Gets the width of the padding(s) for the specified side(s)
+ * @param {String} side Can be t, l, r, b or any combination of those to add multiple
values. For example,
+ * passing lr would get the padding (l)eft + the padding (r)ight.
+ * @return {Number} The padding of the sides passed added together
+ */
+ getPadding : function(side){
+ return this.getStyles(side, this.paddings);
+ },
+ getStyles : function(sides, styles){
+ var val = 0;
+ for(var i = 0, len = sides.length; i < len; i++){
+ var w = parseInt(this.getElement().getStyle(styles[sides.charAt(i)]), 10);
+ if(!isNaN(w)) val += w;
+ }
+ return val;
+ },
+ makeAbsolute: function(keepPos) {
+ if(keepPos) {
+ Position.absolutize(this.getElement());
+ }
+ else {
+ this.getElement().setStyle({position: 'absolute'});
+ }
+ return this;
+ },
+ getX: function() {
+ return this.getElement().offsetLeft;
+ },
+ getY: function() {
+ return this.getElement().offsetTop;
+ },
+ setStyle: function(style) {
+ this.getElement().setStyle(style);
+ return this;
+ },
+
+ borders: {l: 'border-left-width', r: 'border-right-width', t:
'border-top-width', b: 'border-bottom-width'},
+ paddings: {l: 'padding-left', r: 'padding-right', t:
'padding-top', b: 'padding-bottom'},
+ margins: {l: 'margin-left', r: 'margin-right', t: 'margin-top',
b: 'margin-bottom'}
+
+});
+
+if(!ClientUI_common_box_Box_idGenerator) {
+var ClientUI_common_box_Box_idGenerator = 0;
+};
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/StringBuilder.js
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/StringBuilder.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/StringBuilder.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,63 @@
+/*
+ * TODO: Copyright (c) 2007 Denis Morozov <dmorozov(a)exadel.com>
+ *
+ * ...
+ */
+ClientUILib.declarePackage("ClientUI.common.utils.StringBuilder");
+
+/*
+/* sbuilder.js - Helper class to improve strings concatenation perfomance
+ * by Denis Morozov <dmorozov(a)exadel.com> distributed under the BSD license.
+ *
+ * Usage:
+ * var sb = new StringBuilder();
+ * sb.append("String 1").append("String 2");
+ * sb.append("String 3");
+ * var str = sb.toString();
+ */
+StringBuilder = Class.create({
+
+ initialize: function(str) {
+ this._string = null;
+ this._current = 0;
+ this._parts = [];
+ this.length = 0;
+
+ if(str != null)
+ this.append(str);
+ },
+ append: function (str) {
+ // append argument
+ //this.length += (this._parts[this._current++] = String(str)).length;
+ this._parts.push(String(str));
+
+ // reset cache
+ this._string = null;
+ return this;
+ },
+
+ toString: function () {
+ if (this._string != null)
+ return this._string;
+
+ var s = this._parts.join("");
+ this._parts = [s];
+ this._current = 1;
+ this.length = s.length;
+
+ return this._string = s;
+ },
+
+ clean: function(str) {
+ this.initialize();
+ }
+});
+
+Object.extend(StringBuilder.prototype, {
+ length: 0,
+
+ // private
+ _current: 0,
+ _parts: [],
+ _string: null // used to cache the string
+});
Added:
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/Utils.js
===================================================================
--- trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/Utils.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/Utils.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,313 @@
+var Utils = {
+
+ DOM: {
+ copyAttributes : function(target, source, opts) {
+
+ //LOG.debug("copyAttributes");
+ var attrs = source.attributes;
+
+ var exclusions = (opts && opts.exclude) ? opts.exclude : [];
+
+ for(var i = 0 ; i < attrs.length; i++) {
+
+ var attributeNode = attrs[i];
+ var nodeName = attributeNode.nodeName;
+ var nodeValue = attributeNode.nodeValue;
+
+ var shouldCheckAttribute =
+ nodeValue &&
+ nodeValue.length > 0 &&
+ exclusions.indexOf(nodeName) < 0;
+
+ if (ClientUILib.isIE) {
+ shouldCheckAttribute &= attributeNode.specified;
+ }
+
+ if(shouldCheckAttribute) {
+
+ //LOG.debug("Copying attribute " + attributeNode.nodeName + "="
+ attributeNode.nodeValue);
+
+ var newAttributeNode =
+ document.createAttribute(nodeName);
+
+ newAttributeNode.nodeValue = attributeNode.nodeValue;
+ target.setAttributeNode(newAttributeNode);
+ }
+
+ }
+ //LOG.debug("/copyAttributes");
+ },
+
+ replaceNode : function(id, request) {
+ var target = document.getElementById(id);
+ var src = request.getElementById(id);
+
+ if(target && src) {
+ var cells = target.cells;
+ for(var i = 0; i < cells.length; i++) {
+ Utils.DOM.Event.removeListeners(cells[i]);
+ }
+
+ if (ClientUILib.isIE) {
+
+ var s = String();
+ var newOuterXml = "<table><tbody>" + src.xml +
"</tbody></table>";
+ var newNode = document.createElement("DIV");
+
+ newNode.innerHTML = newOuterXml;
+
+ var imported = newNode.firstChild.firstChild.firstChild;
+ target.parentNode.replaceChild(imported, target);;
+ return imported;
+
+// } else if (ClientUILib.isGecko){
+// //Mozill family
+// var theDoc = document;
+//
+// Utils.DOM._clearAttributes(target);
+// Utils.DOM.copyAttributes(target, src);
+//
+// target.innerHTML = src.innerHTML;//nnerHTML.join("");
+// return target;
+ } else {
+ //Fall back to DOM, and cross the fingers
+ src = document.importNode(src, true);
+ target.parentNode.replaceChild(src, target);
+ return src;
+ }
+ }
+ else {
+ if(!target)
+ ClientUILib.log(ClientUILogger.ERROR, "DOM Element with id " + id + "
not found for update.");
+ if(!src) {
+ ClientUILib.log(ClientUILogger.ERROR, "RESPONSE Element with id " + id +
" not found for update.");
+
+ // cleanup destination
+ if(target) {
+ for(var i=0; i<target.cells.length; i++) {
+ target.cells[i].innerHTML = "";
+ }
+ }
+ }
+ }
+ },
+
+ _clearAttributes : function(node) {
+
+ var attrs = node.attributes;
+ if (node.clearAttributes) {
+ node.clearAttributes();
+ } else {
+ while(node.attributes.length > 0) {
+ node.removeAttributeNode(node.attributes[0]);
+ }
+ }
+ },
+
+ _formatNode : function(node) {
+
+ var sb = new StringBuilder();
+
+ sb.append("<").append(node.nodeName);
+ for (var i = 0; i < node.attributes.length; i++) {
+ var attr = node.attributes[i];
+ if (attr.specified) {
+ sb
+ .append(" ")
+ .append(attr.nodeName)
+ .append("=\"")
+ .append(attr.nodeValue)
+ .append("\" ");
+ }
+ }
+
+ sb.append("/>");
+
+ return sb.toString();
+
+ },
+
+ Event: {
+
+ /**
+ * cache listeners in element to kill them all on element ajax replace
+ * @param {Object} element
+ * @param {Object} event
+ * @param {Object} handler
+ * @param {Object} useCapture
+ */
+ observe : function (element, event, handler, useCapture) {
+ if (true) {
+ if (!element._listeners) {
+ element._listeners = [];
+ }
+
+ element._listeners[element._listeners.length] =
+ {
+ event: event,
+ handler: handler,
+ useCapture: useCapture
+ };
+ }
+ Event.observe(element, event, handler, useCapture);
+ },
+
+ stopObserving : function(element, event, handler, useCapture) {
+
+ if(element._listeners) {
+ element._listeners =
+ element._listeners.reject(
+ function(obj) {
+ return obj.event == event
+ && obj.handler == handler
+ && obj.useCapture == useCapture;
+ }
+ );
+ }
+
+ Event.stopObserving(element, event, handler, useCapture);
+
+ },
+
+ removeListeners : function(element) {
+ if (element._listeners) {
+ var l = element._listeners.length;
+ for(var i = 0; i < l; i++) {
+ var listener = element._listeners[i];
+ Event.stopObserving(
+ element,
+ listener.event,
+ listener.handler,
+ listener.useCapture);
+ }
+
+ element._listeners = null;
+ }
+ }
+ }
+ },
+
+ AJAX : {
+ updateRows: function(options,request,grid,clientid, callbacks, callbacksPost){
+ var localOptions = options;
+ var rowCount = grid.getBody().templFrozen.getElement().rows.length;
+ var startRow = localOptions.startRow;
+ var count = localOptions.count;
+ var rowindex, i, el;
+ var dataModel = grid.dataModel;
+ var baseid = clientid;
+
+ var countForUpdate = 0;
+ var rowsForUpdate = [];
+
+ for(i=0; i<count; i++) {
+ rowindex = startRow + i;
+ if(rowindex >= rowCount){
+ rowindex -= rowCount;
+ }
+ [":f:", ":n:"].unbreakableEach(
+ function(suffix) {
+ var id = [baseid,suffix,rowindex].join("");
+ var row = Utils.DOM.replaceNode(id, request);
+
+ if (callbacks) {
+ // just suspend operation for future
+ if(!rowsForUpdate[i]) rowsForUpdate[i] = {};
+ rowsForUpdate[i][suffix] = {index : rowindex, row : row};
+ countForUpdate++;
+ }
+ }
+ );
+ }
+ if (ClientUILib.isIE7) {
+ setTimeout(function() {
+ var body = grid.getBody();
+ ["fTable", "nTable"].unbreakableEach(
+ function(prop) {
+ body[prop].hide();
+ body[prop].show();
+ }
+ );
+ }
+ ,50);
+ }
+
+ if (callbacks && countForUpdate>0) {
+ // process suspended processing
+ setTimeout(function(){
+ for(var i=0; i<count; i++) {
+ callbacks.unbreakableEach(
+ function(callback) {
+ if(rowsForUpdate[i]) {
+ //if(rowsForUpdate[i][":f:"].row) callback.call(grid,
rowsForUpdate[i][":f:"]);
+ if(rowsForUpdate[i][":n:"].row) callback.call(grid,
rowsForUpdate[i][":n:"]);
+ }
+ }
+ );
+ }
+
+ if(callbacksPost) {
+ callbacksPost.unbreakableEach(
+ function(callback) {
+ callback.call(grid);
+ }
+ );
+ }
+ }, 100);
+ }
+
+ grid.getBody()._onDataReady(localOptions);
+ }
+ }
+};
+/*
+var _cAtt = Utils.DOM._clearAttributes;
+Utils.DOM._clearAttributes = function() {
+ return;
+ var d1 = new Date().getTime();
+ _cAtt.apply(Utils.DOM, arguments);
+ var d2 = new Date().getTime();
+ ClientUILib.log(ClientUILogger.INFO, "Utils.DOM._clearAttributes " + (d2 - d1)
+ "ms");
+};
+var cAtt = Utils.DOM._clearAttributes;
+Utils.DOM.copyAttributes = function() {
+ return;
+ var d1 = new Date().getTime();
+ cAtt.apply(Utils.DOM, arguments);
+ var d2 = new Date().getTime();
+ ClientUILib.log(ClientUILogger.INFO, "Utils.DOM.copyAttributes " + (d2 - d1) +
"ms");
+};
+*/
+Utils.execOnLoad = function(func, condition, timeout) {
+
+ if (condition()) {
+ func();
+ } else {
+ window.setTimeout(
+ function() {
+ Utils.execOnLoad(func, condition, timeout);
+ },
+ timeout
+ );
+ }
+};
+Utils.Condition = {
+ ElementPresent : function(element) {
+ return function () {
+ var el = $(element);
+ return el && el.offsetHeight > 0;
+ };
+ }
+};
+
+Utils.trace = function(s) {
+ LOG.info(s + ": " + (new Date().getTime()- this._d) + " ");
+ //window.status = s + ": " + (new Date().getTime()- this._d) + "
" + window.status;
+ this._d = new Date().getTime();
+};
+
+Array.prototype.unbreakableEach = function(f) {
+ for (var i = 0; i < this.length; i++) {
+ f(this[i], i);
+ }
+};
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/Validators.js
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/Validators.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/common/utils/Validators.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,122 @@
+/**
+ * Validators.js Date created: 14.04.2007
+ * Copyright (c) 2007 Exadel Inc.
+ * @author Denis Morozov <dmorozov(a)exadel.com>
+ */
+
+var Validators = {
+ /**
+ * Internet Explorer holds references to objects that are not actually javascript
objects. So if we use the
+ * objects in javascript it will give error. But the typeof operator identifies them as
javascript objects( problem!!!).
+ * Here we can use the isIEObject() function to identify those objects.
+ */
+ isIEObject: function(a) {
+ return this.isObject(a) && typeof a.constructor != 'function';
+ },
+
+ /**
+ * This function returns true if a is an array, meaning that it was produced by the
Array constructor or by
+ * the [ ] array literal notation.
+ */
+ isArray: function(a) {
+ return this.isObject(a) && a.constructor == Array;
+ },
+
+ /**
+ * This function returns true if a is one of the Boolean values, true or false.
+ */
+ isBoolean: function(a) {
+ return typeof a == 'boolean';
+ },
+
+ getBoolean: function(val, defVal) {
+ if(this.isBoolean(val))
+ return val;
+ if(val == "true") return true;
+ else if(val == "false") return false;
+
+ return defVal;
+ },
+
+ /**
+ * This function returns true if a is an object or array or function containing no
enumerable members.
+ */
+ isEmpty: function(o) {
+ if (this.isObject(o)) {
+ for (var i in o) {
+ return false;
+ }
+ }
+ else if(this.isString(o) && o.length > 0) {
+ return false;
+ }
+
+ return !this.IsNumber(o);
+ },
+
+ /**
+ * This function returns true if a is a function. Beware that some native functions in
IE were made to look
+ * like objects instead of functions. This function does not detect that.Netscape is
better behaved in this regard.
+ */
+ isFunction: function(a) {
+ return typeof a == 'function';
+ },
+
+ /**
+ * This function returns true if a is the null value.
+ */
+ isNull: function(a) {
+ return typeof a == 'object' && !a;
+ },
+
+ /**
+ * This function returns true if <code>data</code> is a finite number. It
returns false if <code>data</code> is NaN or Infinite.
+ */
+ IsNumber: function(data) {
+ if(typeof data == 'number' && isFinite(data)) {
+ return true;
+ }
+
+ // if it is a string that contains a number
+ var re = /(^-?[1-9](\d{1,2}(\,\d{3})*|\d*)|^0{1})$/;
+ if ( re.test(data) ) {
+ return true;
+ }
+ return false;
+ },
+ IsFormattedNumber: function(data) {
+ // Regular expression should match number with commas or not
+ //1. ^-? <-- '-' is optional at the beginning
+ //2. \d{1,3} <-- with or without comma, first 3 digits
+ //3. \d{1,3}(\,\d{3})* <-- with comma, at least one digit with max of three before
repeating like ',ddd'
+ //4. \d+ <-- without comma, match any number of integer(shouldn't be though)
+ var re = /^-?(\d{1,3}|\d{1,3}(\,\d{3})*|\d*)$/g;
+ if ( ! re.test(data) ) {
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * This function returns true if a is an object, array, or function. It returns false if
a is a string,
+ * number, Boolean, null, or undefined.
+ */
+ isObject: function(a) {
+ return (typeof a == 'object' && !!a) || this.isFunction(a);
+ },
+
+ /**
+ * This function returns true if a is a string.
+ */
+ isString: function(a) {
+ return typeof a == 'string';
+ },
+
+ /**
+ * This function returns true if a is the undefined value. You can get the undefined
value from an uninitialized
+ * variable or from an object's missing member.
+ */
+ isUndefined: function(a) {
+ return typeof a == 'undefined';
+ }
+};
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTable.js
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTable.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTable.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,312 @@
+if (!window.ExtendedDataTable) window.ExtendedDataTable = {};
+
+ExtendedDataTable.DataTable = Class.create({
+ initialize : function(id, options) {
+ this.id = id;
+ this.groups = [];
+
+ // register event handlers
+ this.options = options;
+ this.selectionManager = new ExtendedDataTable.SelectionManager(options, this);
+
+ if (this.options.sortFunction) {
+ this.sortFct = this.options.sortFunction;
+ this.eventCellClicked = this.OnCellMouseClicked.bindAsEventListener(this);
+ }
+ this.onGroupToggleFct = this.options.onGroupToggleFunction;
+ if (this.options.onColumnResize != null){
+ this.onColumnResize = this.options.onColumnResize;
+ this.columnWidths = "";
+ }
+ this.eventContainerResize = this.OnWindowResize.bindAsEventListener(this);
+ this.eventGroupRowClicked = this.OnGroupRowMouseClicked.bindAsEventListener(this);
+ ClientUILib.log(ClientUILogger.INFO, "[observe] resize");
+ Event.observe(window, "resize", this.eventContainerResize);
+ this.minColumnWidth = this.options.minColumnWidth;
+
+ var grid = this;
+
+ Utils.execOnLoad(
+ function(){
+ grid.update(true);
+ },
+ Utils.Condition.ElementPresent(id+':header'), 5);
+ },
+
+ _findParentElement: function(event, element) {
+ var el = null;
+ if(ClientUILib.isSafari) {
+ var targetCell = event.currentTarget;
+ if(targetCell && targetCell.tagName.toLowerCase() == element) {
+ el = targetCell;
+ } else {
+ var e = (event.target || event.srcElement);
+ while((e != null) && (e.tagName.toLowerCase() != element) && (e !=
document)){
+ e = e.parentNode;
+ }//while
+ if ((e) && (e.tagName.toLowerCase() == element)){
+ el = e;
+ }
+ }
+ } else {
+ el = Event.findElement(event, element);
+ }
+ return el;
+ },
+
+ OnCellMouseClicked: function(event) {
+ ClientUILib.log(ClientUILogger.EVENT, "OnCellMouseClicked");
+ //this.showSplashScreen();
+ //get column id
+ var el = this._findParentElement(event, "th");
+ var columnId = (el) ? el.id : null;
+
+ ClientUILib.log(ClientUILogger.INFO, "columnId: " + columnId);
+
+ if (columnId && (columnId != "")){
+ this.showSplashScreen();
+ this.sortFct(event, columnId);
+ }
+ Event.stop(event);
+ },
+
+ preSendAjaxRequest: function(){
+ ClientUILib.log(ClientUILogger.INFO, "preSendAjaxReqest");
+ //remove listeners
+ Event.stopObserving(window, 'resize', this.eventContainerResize);
+ Event.stopObserving(document, 'mousemove', this.header.eventSepMouseMove);
+ Event.stopObserving(document, 'mouseup', this.header.eventSepMouseUp);
+ //show splash screen
+ this.showSplashScreen();
+ },
+
+ showSplashScreen: function(){
+ this.table.setStyle('visibility:hidden;');
+ this.mainDiv.getElement().removeClassName('extdt-splscr-hddn');
+ this.mainDiv.getElement().addClassName('extdt-splscr-vsbl');
+ },
+
+ hideSplashScreen: function(){
+ this.table.setStyle('visibility:visible;');
+ this.mainDiv.getElement().removeClassName('extdt-splscr-vsbl');
+ this.mainDiv.getElement().addClassName('extdt-splscr-hddn');
+ },
+
+ OnWindowResize: function(event) {
+ ClientUILib.log(ClientUILogger.EVENT, "OnWindowResize.");
+ this.updateLayout();
+ },
+ getColumnsNumber: function() {
+ return this.columnsNumber;
+ },
+ getColWidth: function(columnNumber) {
+
+ },
+ getColumns: function() {
+ return this.cols;
+ },
+ OnGroupRowMouseClicked: function(event) {
+
+ ClientUILib.log(ClientUILogger.EVENT, "OnGroupRowMouseClicked.");
+ var groupRow = this._findParentElement(event, "tr");
+ var bExpanded = !(groupRow.getAttribute('expanded') == 'true');
+ var sExpanded = bExpanded ? 'true' : 'false';
+ var groupIndex = parseInt(groupRow.getAttribute('groupindex'));
+ if (this.onGroupToggleFct){
+ this.onGroupToggleFct(event, groupIndex);
+ }
+ groupRow.setAttribute('expanded', sExpanded);
+ var imageDiv = groupRow.firstChild.firstChild.firstChild;
+ this.toggleImageSource(imageDiv);
+ this.setGroupExpanded(groupIndex, bExpanded);
+ Event.stop(event);
+ },
+
+ toggleImageSource: function(imageDiv) {
+ var src = imageDiv.getAttribute('src');
+ var alternateSrc = imageDiv.getAttribute('alternatesrc');
+ imageDiv.setAttribute('src', alternateSrc);
+ imageDiv.setAttribute('alternatesrc', src);
+ },
+
+ setGroupExpanded: function(iGroupIndex, bValue) {
+ var group = this.groups[iGroupIndex];
+
+ var sVisibility;
+ var sBorder;
+ var sEmptyCells;
+
+ if (bValue) {
+ sVisibility = '';
+ sBorderColor = '';
+ }else{
+ sVisibility = 'none';
+ sBorderColor = 'transparent';
+ }
+ var size = group.size();
+ for (var i=0; i<size; i++) {
+ group[i].style.display = sVisibility;
+ if (ClientUILib.isIE7){
+ //prevent IE from showing borders of cells
+ //which parents have been hidden :|
+ var cells = group[i].childNodes;
+ for (var j=0; j<cells.length; j++) {
+ cells[j].style.borderColor = sBorderColor;
+ }
+ }
+ }
+ },
+
+ createControls: function() {
+ var id = this.id;
+ this.table = new ClientUI.common.box.Box(this.id +":tu",null,true);
+ this.mainDiv = new ClientUI.common.box.Box(this.id,null,true);
+ this.outerDiv = new ClientUI.common.box.Box(this.id +":od",null,true);
+ this.tableB = new ClientUI.common.box.Box(this.id +":n",null,true);
+ this.fakeIeRow = $(this.id +":fakeIeRow");
+ this.fakeIeBodyRow = $(this.id +":body:fakeIeRow");
+ this.header = new ExtendedDataTable.DataTable.header(this.id
+":header",this);
+ this.header.minColumnWidth = this.minColumnWidth;
+ this.cols = this.table.getElement().getElementsByTagName("col");
+ this.columnsNumber = this.cols.length/2;
+ this.scrollingDiv = new ClientUI.common.box.Box(this.id +":sd",null,true);
+ this.groupRows = [];
+
+ if (ClientUILib.isOpera) {
+ //no overflow-x nor overflow-y in Opera
+ this.scrollingDiv.setStyle({overflow: 'scroll',
+ width: this.mainDiv.getWidth()
+ });
+ this.table.setStyle({width: this.mainDiv.getWidth()});
+ };
+
+ var i = 0;
+ var groupRow = $(id+':group-row:'+i);
+ while (groupRow != null) {
+ this.groupRows[i] = groupRow;
+ Utils.DOM.Event.removeListeners(groupRow);
+ Utils.DOM.Event.observe(groupRow,'click',this.eventGroupRowClicked);
+ i++;
+ groupRow = $(id+':group-row:'+i);
+ }
+ },
+ getScrollbarWidth: function() {
+ var sd = this.scrollingDiv.getElement();
+ return sd.offsetWidth - sd.clientWidth;
+ },
+ validateColumnsWidth: function(columns,excessWidth) {
+ var i=1;
+ var endIndex = columns.length/2-1;
+ while ((i < endIndex) && (excessWidth > 0)) {
+ var col = columns[columns.length-i-1];
+ var spareWidth = col.offsetWidth - this.minColumnWidth;
+ if (spareWidth > excessWidth) {
+ col.width = col.offsetWidth - excessWidth;
+ columns[endIndex - i].width = col.width;
+ excessWidth = 0;
+ }else{
+ col.width = col.offsetWidth - spareWidth;
+ columns[endIndex - i].width = col.width;
+ excessWidth -= spareWidth;
+ }
+ i++;
+ }
+ },
+ updateLayout: function() {
+ var table = this.table.getElement();
+ this.grid = table;
+ var outerDiv = this.outerDiv.getElement();
+ var cols = this.getColumns();
+ var header = this.header;
+ var scrollingDiv = this.scrollingDiv;
+ var mainDivHeight = this.mainDiv.getHeight();
+ var mainDivWidth = this.mainDiv.getWidth();
+ var headerChildren = header.getColumnCells();
+
+ var footers = table.getElementsBySelector('tfoot');
+ var footerHeight = 0;
+ if (footers.size() > 0) {
+ footerHeight = footers[0].offsetHeight;
+ }
+ ClientUILib.log(ClientUILogger.INFO,
+ "[updateLayout] footerHeight = "+
+ footerHeight+";"
+ );
+ ClientUILib.log(ClientUILogger.INFO,
+ "[updateLayout] mainDivHeight = "+
+ mainDivHeight+";"
+ );
+ var columnsNumber = this.getColumnsNumber();
+
+ var visibleHeaderWidth = this.header.getVisibleWidth();
+ var excessWidth = this.header.getVisibleWidth() - this.mainDiv.getWidth();
+ ClientUILib.log(ClientUILogger.INFO,
+ "[updateLayout] getVisibleHeaderWidth() = "+
+ visibleHeaderWidth+";"
+ );
+ ClientUILib.log(ClientUILogger.INFO,
+ "[updateLayout] mainDiv.getWidth() = "+
+ this.mainDiv.getWidth()+";"
+ );
+ ClientUILib.log(ClientUILogger.INFO,
+ "[updateLayout] excessWidth1 = "+
+ excessWidth+";"
+ );
+ if (excessWidth > 0) {
+ var scrollbarExcess = scrollingDiv.getElement().offsetWidth -
scrollingDiv.getElement().clientWidth;
+ excessWidth += scrollbarExcess;
+ this.validateColumnsWidth(cols,excessWidth);
+ }else{
+ var excessWidth = visibleHeaderWidth - scrollingDiv.getElement().clientWidth;
+ ClientUILib.log(ClientUILogger.INFO,
+ "[updateLayout] excessWidth2 = "+
+ excessWidth+";"
+ );
+ if (excessWidth>0) {
+ this.validateColumnsWidth(cols,excessWidth);
+ }
+ }
+ ClientUILib.log(ClientUILogger.INFO,
+ "scrollbarWidth = "+
+ this.getScrollbarWidth()+";"
+ );
+ if (ClientUILib.isOpera) {
+ var newWidth = mainDivWidth - visibleHeaderWidth;
+ cols[columnsNumber-1].width = newWidth;
+ cols[cols.length-1].width = newWidth - this.getScrollbarWidth();
+ }else{
+ cols[columnsNumber-1].width = null;
+ cols[cols.length-1].width = null;
+ }
+
+ scrollingDiv.setStyle('height:'+(mainDivHeight - header.getHeight() -
footerHeight - 2) +'px;');
+
+ for (var i=0; i<headerChildren.length-1; i++) {
+ var headerChild = headerChildren[i];
+ var isSortable = headerChild.getAttribute('sortable');
+ if ((isSortable) && (isSortable.indexOf('true') == 0)) {
+ Utils.DOM.Event.removeListeners(headerChild);
+ Utils.DOM.Event.observe(headerChild, 'click', this.eventCellClicked);
+ }
+ };
+ header.adjustSeparators();
+ this.hideSplashScreen();
+ },
+ update: function(refreshEvents) {
+ this.createControls();
+ if ( !ClientUILib.isIE7 ) {
+ if (this.fakeIeRow) {
+ this.table.getElement().deleteRow(this.fakeIeRow);
+ this.fakeIeRow = null;
+ }
+ if (this.fakeIeBodyRow) {
+ this.tableB.getElement().deleteRow(this.fakeIeBodyRow);
+ this.fakeIeBodyRow = null;
+ }
+ }
+ this.selectionManager.refreshEvents();
+ this.updateLayout();
+ this.selectionManager.restoreState();
+ }
+
+});
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTableHeader.js
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTableHeader.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTableHeader.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,308 @@
+ExtendedDataTable.DataTable.header = Class.create(ClientUI.common.box.Box, {
+ // constructor
+ initialize: function($super, elementId, extDt) {
+ this.extDt = extDt;
+ this.extDtId = this.extDt.id;
+ $super(elementId,extDt,true);
+
+ //register events
+ this.eventSepClick = this.OnSepClick.bindAsEventListener(this);
+ this.eventSepMouseDown = this.OnSepMouseDown.bindAsEventListener(this);
+ this.eventSepMouseMove = this.OnSepMouseMove.bindAsEventListener(this);
+ this.eventSepMouseUp = this.OnSepMouseUp.bindAsEventListener(this);
+
+ var showMenuFct = this.extDt.options.showMenuFunction;
+ if (showMenuFct) {
+ this.showMenuFct = showMenuFct;
+ this.menuImageMouseDown = this.OnMenuImageMouseDown.bindAsEventListener(this);
+ };
+
+ this.createControl(elementId);
+ },
+ getVisibleWidth: function() {
+ var sum = 0;
+ var cols = this.getColumns();
+ for(var i=0; i<this.getColumnsNumber()-1; i++){
+ sum += parseInt(cols[i].width);
+ }
+ return sum;
+ },
+ createControl: function(elementId) {
+ if(!elementId) {
+ errMsg = "Invalid id specified for ExtendedDataTableGridHeader.";
+ throw(errMsg);
+ }
+
+ if(!this.parseTemplate(elementId)) {
+ //TODO insert comment about header structure here
+ errMsg = "TODO insert commnet about header structure here";
+ throw(errMsg);
+ }
+ this.adjustSeparators();
+ },
+ parseTemplate: function(template) {
+ if(!template) {
+ return false;
+ }
+ this.headerRow = new ClientUI.common.box.Box(this.extDtId
+":headerRow",this.getElement(),true);
+ this.filterRow = new ClientUI.common.box.Box(this.extDtId
+":filterRow",this.getElement(),true);
+ this.cols = this.extDt.table.getElement().getElementsByTagName("col");
+ this.columnCells = this.headerRow.getElement().childElements();
+ this.columnsNumber = this.columnCells.length;
+ return true;
+ },
+ getColumns: function() {
+ return this.cols;
+ },
+ getColumnCells: function() {
+ return this.columnCells;
+ },
+ getColumnsNumber: function() {
+ return this.columnsNumber;
+ },
+
+ getColumnWidth: function(columnNumber) {
+ if ((columnNumber < this.getColumnsNumber()) && (columnNumber >=0)) {
+ var col = this.columnCells[columnNumber];
+ if (col.offsetWidth) {
+ return col.offsetWidth;
+ }else{
+ //cols don't have offsetWidth in Opera
+ return parseInt(col.width);
+ }
+ }else{
+ return null;
+ }
+ },
+ getHeightWithoutFacets: function() {
+ return this.headerRow.getHeight() + this.filterRow.getHeight();
+ },
+ OnMenuImageMouseDown: function(event) {
+ ClientUILib.log(ClientUILogger.EVENT, "OnMenuImageMouseDown.");
+
+ var el = this.extDt._findParentElement(event, "th");
+ var columnId = (el) ? el.id : null;
+
+ if (columnId && (columnId != "")){
+ var menuId = "#" + columnId + "menu";
+ menuId = menuId.replace(/:/g,"\\:");
+ this.showMenuFct(event, columnId, menuId);
+ }
+ Event.stop(event);
+ },
+
+ adjustSeparators: function() {
+ var columnCells = this.getColumnCells();
+ this._redrawTable(this.extDt.table.getElement());
+ this._redrawTable(this.extDt.tableB.getElement());
+ for (var i=0; i<columnCells.length-1; i++) {
+ var headerChild = columnCells[i];
+ var headerNextChild = columnCells[i+1];
+ var headerChildChildren = headerChild.childElements();
+ var sepSpan = headerChildChildren[2];
+ var headerRowHeight = this.headerRow.getHeight();
+ var headerRowY = this.headerRow.getY();
+ sepSpan.columnIndex = i;
+ var sd = sepSpan.getWidth()/2 + 1;
+ var dropSpanLeft = headerChildChildren[3];
+ var dropSpanRight = headerChildChildren[5];
+ var menuImage = headerChildChildren[7];
+
+ //remove listeners
+ Utils.DOM.Event.removeListeners(menuImage);
+ Utils.DOM.Event.removeListeners(sepSpan);
+ //add listeners
+ Utils.DOM.Event.observe(menuImage,'click',this.menuImageMouseDown);
+ Utils.DOM.Event.observe(sepSpan, 'click', this.eventSepClick);
+ Utils.DOM.Event.observe(sepSpan, 'mousedown', this.eventSepMouseDown);
+ Utils.DOM.Event.observe(sepSpan, 'mousemove', this.eventSepMouseMove, true);
+ Utils.DOM.Event.observe(sepSpan, 'mouseup', this.eventSepMouseUp, true);
+
+ var spanLeft = headerNextChild.offsetLeft - sd;
+ sepSpan.setStyle('height:'+headerRowHeight+'px');
+ sepSpan.setStyle('top:'+headerRowY+'px');
+ sepSpan.setStyle('left:'+spanLeft+'px');
+ menuImage.setStyle('top:' + headerRowY + 'px');
+ menuImage.setStyle('left:'+(spanLeft-menuImage.offsetWidth)+'px');
+ dropSpanLeft.setStyle('top:'+headerRowY+'px');
+ var w = headerChild.getWidth();
+ dropSpanLeft.setStyle('left:'+ (headerChild.offsetLeft) +'px');
+ dropSpanLeft.setStyle('height:'+headerRowHeight+'px');
+ dropSpanLeft.setStyle('width:'+(w/2)+'px');
+ dropSpanRight.setStyle('top:'+headerRowY+'px');
+ dropSpanRight.setStyle('left:'+ (headerChild.offsetLeft + w/2)
+'px');
+ dropSpanRight.setStyle('height:'+headerRowHeight+'px');
+ dropSpanRight.setStyle('width:'+(w/2)+'px');
+ }
+ this.lastColWidth = this.getColumnWidth(this.getColumnsNumber()-1);
+ ClientUILib.log(ClientUILogger.INFO,
+ "[adjustSeparators] lastColWidth = "+
+ this.lastColWidth+";"
+ );
+ if (ClientUILib.isIE7){
+ this.lastColWidth -= 15;
+ }
+ },
+
+ OnSepClick: function(event) {
+ ClientUILib.log(ClientUILogger.EVENT, "OnSepClick.");
+ Event.stop(event);
+ },
+
+ OnSepMouseDown: function(event) {
+ ClientUILib.log(ClientUILogger.EVENT, "OnSepMouseDown.");
+ Event.stop(event);
+ this.dragColumnInfo = {
+ srcElement: Event.element(event),
+ dragStarted: false,
+ mouseDown: true,
+ startX: Event.pointerX(event) - this.extDt.outerDiv.getX(),
+ originalX: 0
+ };
+ var srcElement = this.dragColumnInfo.srcElement;
+ this.maxDelta = this.getColumnWidth(this.getColumnsNumber()-1);
+ this.maxDelta -= this.extDt.getScrollbarWidth();
+ this.minDelta = this.minColumnWidth - this.getColumnWidth(srcElement.columnIndex);
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] minColumnWidth = "+this.minColumnWidth+";"
+// );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] minColumnWidth = "+this.minColumnWidth+";"
+// );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] columnWidth =
"+this.getColumnWidth(srcElement.columnIndex+1)+";"
+// );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] mindelta = "+this.minDelta+";"
+// );
+ //this.dragColumnInfo.object = this.getColumns()[srcElement.columnIndex];
+ Event.observe(document, 'mousemove', this.eventSepMouseMove, true);
+ Event.observe(document, 'mouseup', this.eventSepMouseUp, true);
+ },
+
+ _showSplitter: function(index) {
+ if(!this.columnSplitter) {
+ this._createSplitter();
+ }
+
+ var pos = this.dragColumnInfo.startX;
+ pos += 6; //6 stands for width of the separatorSpan
+ this.dragColumnInfo.originalX = pos;
+ this.columnSplitter.show();
+ this.columnSplitter.setHeight(this.extDt.scrollingDiv.getHeight()+
+ this.getHeightWithoutFacets()
+ );
+ this.columnSplitter.moveTo(pos, this.headerRow.getY());
+ },
+ _hideSplitter: function() {
+ if(this.columnSplitter) {
+ this.columnSplitter.hide();
+ }
+ },
+ _createSplitter: function() {
+ this.columnSplitter = new ClientUI.common.box.Box(this.extDtId +":cs",
this.extDt.grid);
+ this.columnSplitter.makeAbsolute();
+ this.columnSplitter.setWidth(this.minColumnWidth);
+ },
+
+ OnSepMouseUp: function(event) {
+ var colsNumber = this.getColumnsNumber();
+ ClientUILib.log(ClientUILogger.EVENT, "OnSepMouseUp.");
+ Event.stop(event);
+ Event.stopObserving(document, 'mousemove', this.eventSepMouseMove);
+ Event.stopObserving(document, 'mouseup', this.eventSepMouseUp);
+ var cols = this.getColumns();
+ if(this.dragColumnInfo && this.dragColumnInfo.dragStarted) {
+
+ this.dragColumnInfo.dragStarted = false;
+ this.dragColumnInfo.mouseDown = false;
+
+ var delta = Event.pointerX(event) -
+ this.dragColumnInfo.startX -
+ this.extDt.outerDiv.getX();
+ if (delta < this.minDelta) {
+ delta = this.minDelta;
+ }
+ if (delta > this.maxDelta) {
+ delta = this.maxDelta;
+ }
+ if (ClientUILib.isIE7) {
+ // sep span width
+ delta -= 6;
+ }
+ var columnIndex = this.dragColumnInfo.srcElement.columnIndex;
+ var newWidth = this.getColumnWidth(columnIndex) + delta;
+
+ cols[columnIndex].width = newWidth;
+ cols[columnIndex+this.getColumnsNumber()].width = newWidth;
+
+ this.extDt.updateLayout();
+ if (this.extDt.onColumnResize){
+ //set properly value to this.columnWidths
+ this.extDt.columnWidths = "";
+ for (i=0; i<this.columnsNumber; i++){
+ this.extDt.columnWidths += "" + this.cols[i].width + ";";
+ }//for
+ this.extDt.onColumnResize(event, this.extDt.columnWidths);
+ }
+ }
+ this._hideSplitter();
+ },
+
+ OnSepMouseMove: function(event) {
+ if(this.dragColumnInfo && this.dragColumnInfo.mouseDown) {
+ if(!this.dragColumnInfo.dragStarted) {
+ this.dragColumnInfo.dragStarted = true;
+ this._showSplitter(this.dragColumnInfo.srcElement.columnIndex);
+ }
+ var delta = Event.pointerX(event) -
+ this.dragColumnInfo.startX -
+ this.extDt.outerDiv.getX();
+ if (delta < this.minDelta) {
+ delta = this.minDelta;
+ }
+ if (delta > this.maxDelta) {
+ delta = this.maxDelta;
+ }
+ var x = this.dragColumnInfo.originalX + delta;
+ var finalX = x - this.minColumnWidth - 6;
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] maxDelta = "+this.maxDelta+";"
+// );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] originalX =
"+this.dragColumnInfo.originalX+";"
+// );
+ ClientUILib.log(ClientUILogger.INFO,
+ "[onSepMouseMove] delta = "+delta+";"
+ );
+ ClientUILib.log(ClientUILogger.INFO,
+ "[onSepMouseMove] mindelta = "+this.minDelta+";"
+ );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] object.offsetWidth = "+
+// parseInt(this.dragColumnInfo.object.width)+";"
+// );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] minColumnWidth = "+minColumnWidth+";"
+// );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] x = "+x+";"
+// );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] finalX = "+finalX+";"
+// );
+// ClientUILib.log(ClientUILogger.INFO,
+// "[onSepMouseMove] ----------------------------"
+// );
+ this.columnSplitter.moveToX(finalX);
+ Event.stop(event);
+ }
+ },
+ _redrawTable: function(table) {
+ var tr = table.insertRow(0);
+ var td = tr.insertCell(0);
+ td.setAttribute("colspan", 5);
+ td.innerHTML = "FU SAFARI!!!";
+ table.deleteRow(tr);
+ }
+});
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTableSelection.js
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTableSelection.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUI/controls/datatable/ExtendedDataTableSelection.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,594 @@
+/* Class taken from ScrollableDataTable - unmodified */
+ExtendedDataTable.Selection = Class.create({
+ initialize: function() {
+ this.ranges = [];
+ },
+
+ addId: function(id) {
+ id = parseInt(id);
+ if(this.isSelectedId(id))
+ return;
+ var i = 0;
+ while(i < this.ranges.length && id >= this.ranges[i++].indexes[1]);
+ i--;
+ if(this.ranges[i-1] && id==(this.ranges[i-1].indexes[1]+1) ) {
+ if(id==(this.ranges[i].indexes[0]-1)) {
+ this.ranges[i-1].indexes[1] = this.ranges[i].indexes[1];
+ this.removeRange(i);
+ } else {
+ this.ranges[i-1].indexes[1]++;
+ }
+ } else {
+ if(this.ranges[i]){
+ if(this.ranges[i] && id==(this.ranges[i].indexes[0]-1)) {
+ this.ranges[i].indexes[0]--;
+ } else {
+ if(id==(this.ranges[i].indexes[1]+1)){
+ this.ranges[i].indexes[1]++;
+ } else {
+ if(id<this.ranges[i].indexes[1]){
+ this.addRange(i, new ExtendedDataTable.Range(id, id));
+ } else {
+ this.addRange(i + 1, new ExtendedDataTable.Range(id, id));
+ }
+ }
+ }
+ } else {
+ this.addRange(i, new ExtendedDataTable.Range(id, id));
+ }
+ }
+ },
+
+ addRange: function(index, range) {
+ var i = this.ranges.push(range) - 2;
+ if(index >= 0) {
+ while(i>=index)
+ this.ranges[i+1] = this.ranges[i--];
+ this.ranges[i+1] = range;
+ }
+ },
+
+ removeRange: function(index) {
+ var i = index + 1;
+ while(i!=this.ranges.length)
+ this.ranges[i-1] = this.ranges[i++];
+ this.ranges.pop();
+ },
+
+ isSelectedId: function(id) {
+ var i = 0;
+ while(i < this.ranges.length && id >= this.ranges[i].indexes[0]) {
+ if(id >= this.ranges[i].indexes[0] && id <= this.ranges[i].indexes[1])
{
+ return true;
+ } else {
+ i++;
+ }
+ }
+ return false;
+ },
+
+ getSelectedIdsQuantity: function() {
+ var number = 0;
+ for (var i = 0; i < this.ranges.length; i++) {
+ number+= this.ranges[i].size();
+ }
+ return number;
+ },
+
+ size: function () {
+ return this.getSelectedIdsQuantity();
+ },
+
+ removeId: function(id) {
+ id = parseInt(id);
+ if(!this.isSelectedId(id))
+ return;
+ var i = 0;
+ while(i < this.ranges.length && id > this.ranges[i++].indexes[1]);
+ i--;
+ if(this.ranges[i]) {
+ if(id==(this.ranges[i].indexes[1]) ) {
+ if(id==(this.ranges[i].indexes[0])){
+ this.removeRange(i);
+ } else {
+ this.ranges[i].indexes[1]--;
+ }
+ } else {
+ if(id==(this.ranges[i].indexes[0])){
+ this.ranges[i].indexes[0]++;
+ } else {
+ this.addRange(i+1, new ExtendedDataTable.Range(id+1, this.ranges[i].indexes[1]));
+ this.ranges[i].indexes[1] = id-1;
+ }
+ }
+ }
+ },
+
+ getState: function() {
+ var s = this.clone();
+ return {
+ size: function() {
+ return s.size();
+ },
+
+ each: function(iterator) {
+ s.each(iterator);
+ },
+
+ isSelected: function(id) {
+ return s.isSelectedId(id);
+ }
+ };
+ },
+
+ clone: function() {
+ var ret = Object.extend(new Object(),this);
+ ret.ranges = new Array(ret.ranges.length);
+ for (var i = 0; i < ret.ranges.length; i++) {
+ ret.ranges[i] = this.ranges[i].clone();
+ }
+ return ret;
+ },
+
+ each: function(iterator) {
+ for (var i = 0; i < this.ranges.length; i++) {
+ this.ranges[i].each(iterator);
+ }
+ },
+
+ getRanges: function() {
+ return this.ranges;
+ },
+
+ setRanges: function(ranges) {
+ this.ranges = ranges;
+ },
+
+ initRanges: function(rangeStrRArray) {
+ if(rangeStrRArray.length == 0) {
+ this.ranges = [];
+ return;
+ }
+ this.ranges = new Array(rangeStrRArray.length);
+ var indexStrRArray;
+ for(var i = 0; i < this.ranges.length; i++) {
+ indexStrRArray = rangeStrRArray[i].split(",");
+ this.ranges[i] = new ExtendedDataTable.Range(parseInt(indexStrRArray[0]),
parseInt(indexStrRArray[1]));
+ }
+
+ },
+
+ inspectRanges: function() {
+ var ranges = this.getRanges();
+ var ret = "";
+ ranges.each( function(r) { ret += r.inspect(); } );
+ return ret;
+ }
+});
+
+
+/* Class taken from ScrollableDataTable - unmodified */
+ExtendedDataTable.Range = Class.create({
+ initialize: function(startIndex, endIndex) {
+ this.indexes = [startIndex, endIndex];
+ },
+
+ inspect: function() {
+ return this.indexes[0] + "," + this.indexes[1] + ";";
+ },
+ toString: function() {
+ return this.inspect();
+ },
+
+ size: function() {
+ return this.indexes[1] - this.indexes[0] + 1;;
+ },
+
+ each: function(iterator) {
+ var j = this.indexes[0];
+ while(j <= this.indexes[1]) {
+ iterator(j++);
+ }
+ },
+
+ clone: function() {
+ var ret = Object.extend(new Object(),this);
+ ret.indexes = this.indexes.clone();
+ return ret;
+ }
+});
+
+/* Modified class from ScrollableDataTable */
+ExtendedDataTable.SelectionManager = Class.create({
+ initialize: function(options, owner) {
+ this.dataTable = owner;
+ this.options = options;
+ this.selectionFlag;
+ this.firstIndex;
+ this.activeRow = -1;
+ var element = options.gridId;
+ this.gridElement = document.getElementById(element + ":n");
+
+ this.prefix = options.gridId;
+ this.selection = new ExtendedDataTable.Selection();
+
+ this.inputElement = options.selectionInput;
+ this.onselectionchange = options.onselectionchange;
+ this.selectedClass = options.selectedClass;
+ this.activeClass = options.activeClass;
+
+
+ },
+
+ refreshEvents: function() {
+ this.setListeners();
+ this.eventKeyPress = this.processKeyDown.bindAsEventListener(this);
+ Event.observe(document, "keydown", this.eventKeyPress);
+ A4J.AJAX.AddListener({
+ onafterajax: function(req, event, data) {
+ if(!$(this.prefix + ":n")) {
+ Event.stopObserving(document, "keydown", this.eventKeyPress);
+ }
+ }.bind(this)
+ });
+ if (document.selection) {
+ Event.observe(this.gridElement, "click",
this.resetSelection.bindAsEventListener(this));
+ }
+
+ this.eventLostFocus = this.processLostFocus.bindAsEventListener(this);
+ Event.observe(document, "click", this.eventLostFocus);
+
+ this.eventPreventLostFocus = this.processPreventLostFocus.bindAsEventListener(this);
+ Event.observe(this.gridElement, "click", this.eventPreventLostFocus);
+ },
+
+ restoreState: function() {
+ this.selectionFlag = null;
+ var selStrAr = $(this.inputElement).value.split(";");
+ var activeRow = NaN;
+ while (selStrAr.length != 0 && selStrAr[selStrAr.length -
1].indexOf(",") == -1 &&
+ isNaN(activeRow = Number(selStrAr.pop())));
+ if (!isNaN(activeRow)) {
+ this.setActiveRow(activeRow);
+ }
+ this.selection.initRanges(selStrAr);
+ var i = 0;
+ var j;
+ while(i < this.selection.ranges.length) {
+ j = this.selection.ranges[i].indexes[0];
+ while(j <= this.selection.ranges[i].indexes[1]) {
+ var nElement = $(this.prefix + ":n:" + j);
+ Element.addClassName(nElement, "extdt-row-selected");
+ Element.addClassName(nElement, "rich-sdt-row-selected");
+ Element.addClassName(nElement, this.selectedClass);
+ j++;
+ }
+ i++;
+ }
+ this.oldState = this.selection.getState();
+ },
+
+ setListeners: function() {
+ //May need optimization by attaching listeners to whole rows instead of all cells
+ var nrows = $(this.prefix + ":n").rows;
+ this.rowCount = nrows.length;
+ var rowIndex;
+ var groupingExists = $(this.prefix + ":group-row:0") != null;
+ if(!groupingExists) { //simple listener binding
+ for(var i = 0; i < this.rowCount; i++) {
+ rowIndex = Number(nrows[i].id.split(this.prefix)[1].split(":")[2]);
+ this.addListener(nrows[i], rowIndex);
+ }
+ } else { //extended listener binding with grouping
+ var groupRow;
+ var lastGroupId = 0;
+ var bGroupExpanded;
+ if (!ClientUILib.isIE7) {
+ //make first fake row visible to ensure proper rendering
+ bGroupExpanded = true;
+ }else{
+ bGroupExpanded = false;
+ }
+ var groupId;
+ var groupItems = [];
+ var groupItem = 0;
+ var groups = [];
+ var groupRows = this.dataTable.groupRows;
+ for(var i = 0; i < this.rowCount; i++) {
+ tempo = nrows[i].id.split(this.prefix)[1];
+ var tempArr = tempo.split(":")
+ groupRow = tempArr[1] == "group-row";
+ groupId = Number(tempArr[2]);
+ if(groupRow) {
+ groups[lastGroupId] = groupItems;
+ bGroupExpanded = (groupRows[groupId].getAttribute('expanded') ==
'true');
+ var textSpan = groupRows[lastGroupId].lastChild.lastChild;
+ var txtNode = document.createTextNode("(" + groupItems.size() +
")");
+ if (textSpan.lastChild) {
+ textSpan.replaceChild(txtNode, textSpan.lastChild);
+ }else{
+ textSpan.appendChild(txtNode);
+ }
+ groupItem = 0;
+ groupItems = [];
+ lastGroupId = groupId;
+ } else {
+ rowIndex = Number(nrows[i].id.split(this.prefix)[1].split(":")[2]);
+ this.addListener(nrows[i], rowIndex);
+ groupItems[groupItem++] = nrows[i];
+ if (!bGroupExpanded) {
+ nrows[i].style.display = 'none';
+ if (ClientUILib.isIE7){
+ //prevent IE from showing borders of cells
+ //which parents have been hidden :|
+ var cells = nrows[i].childNodes;
+ for (var j=0; j<cells.length; j++) {
+ cells[j].style.borderColor = 'transparent';
+ }
+ }
+ }
+ }
+ }
+ groups[lastGroupId] = groupItems;
+ var textSpan = groupRows[lastGroupId].lastChild.lastChild;
+ var txtNode = document.createTextNode("(" + groupItems.size() +
")");
+ if (textSpan.lastChild) {
+ textSpan.replaceChild(txtNode, textSpan.lastChild);
+ }else{
+ textSpan.appendChild(txtNode);
+ }
+ this.dataTable.groups = groups;
+ }
+ },
+ /*
+ Modification: instead of providing listener for each cell,
+ one is provided for a whole row
+ */
+ addListener: function(tr, rowIndex) {
+ if (tr) {
+ var listener = this.processClick.bindAsEventListener(this, rowIndex);
+ Utils.DOM.Event.removeListeners(tr);
+ Utils.DOM.Event.observe(tr, "click", listener);
+ }
+ },
+
+/* getGridSelection: function() {
+ return this.selection.getRanges();
+ },*/
+
+ processPreventLostFocus: function() {
+ this.inFocus = true;
+ this.preventLostFocus = true;
+ },
+
+ processLostFocus: function() {
+ if (!this.preventLostFocus) {
+ this.lostFocus();
+ } else {
+ this.preventLostFocus = false;
+ }
+ },
+
+ lostFocus: function() {
+ this.inFocus = false;
+ },
+
+ processKeyDown: function(event) {
+ 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);
+ }
+ }
+ 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;
+ }
+ 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";
+ for (var i = 0; i < this.rowCount; i++) {
+ this.addRowToSelection(i);
+ }
+ noDefault = true;
+ }
+ 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);
+ }
+ }
+ },
+
+ /*
+ Modified method:
+ Component supports three selection modes:
+ none - no selection allowed
+ single - only one row can be selected at a time (no ctrl or shift)
+ multi - normal full-featured selection mode
+ */
+ processClick: function(event, rowIndex) {
+ if (this.options.selectionMode == "none") {
+ return;
+ }
+
+ var bSingleSelection = this.options.selectionMode == "single";
+
+ if(!event.shiftKey) {
+ this.shiftRow = null;
+ }
+ var range;
+
+ if ( event.shiftKey && !event.ctrlKey && !bSingleSelection &&
!event.altKey) {
+ this.firstIndex = Number($(this.prefix +
":n").rows[0].id.split(this.prefix)[1].split(":")[2]);;
+ this.selectionFlag = "x";
+ if(!this.shiftRow) {
+ this.shiftRow = this.activeRow;
+ }
+ this.startRow = this.shiftRow;
+ if (((this.startRow <= rowIndex) && (this.firstIndex <= this.startRow ||
rowIndex < this.firstIndex))
+ || (this.startRow > rowIndex && this.firstIndex < this.startRow
&& rowIndex <= this.firstIndex)) {
+ this.endRow = rowIndex;
+ } else {
+ this.endRow = this.startRow;
+ this.startRow = rowIndex;
+ }
+ if(this.startRow > this.endRow) { //bugfix
+ //without this selection of first row with shift was broken
+ var t = this.startRow;
+ this.startRow = this.endRow;
+ this.endRow = t;
+ }
+ range = [this.startRow, this.endRow];
+ this.setSelection(range);
+ } else if (!event.shiftKey && event.ctrlKey && !event.altKey) {
+ if (this.selection.isSelectedId(rowIndex)) {
+ this.removeRowFromSelection(rowIndex);
+ } else {
+ if (!bSingleSelection || this.selection.size() == 0) {
+ this.addRowToSelection(rowIndex);
+ }
+ }
+ } else if (!event.shiftKey && !event.ctrlKey && !event.altKey) {
+ this.selectionFlag = "x";
+ range = [rowIndex, rowIndex];
+ this.setSelection(range);
+ }
+ this.setActiveRow(rowIndex);
+ if (event.shiftKey) {
+ if (window.getSelection) {
+ window.getSelection().removeAllRanges();
+ } else if (document.selection) {
+ document.selection.empty();
+ }
+ }
+ this.selectionChanged(event);
+ },
+
+ selectionChanged: function(event) {
+ $(this.inputElement).value = this.selection.inspectRanges() + this.activeRow +
";" + (this.selectionFlag ? this.selectionFlag : "") ;
+ var state = this.selection.getState();
+ event.oldSelection = this.oldState;
+ event.newSelection = state;
+ if(this.onselectionchange) this.onselectionchange(event);
+ this.oldState = state;
+ },
+
+ setShiftRow: function(event) {
+ if(event.shiftKey) {
+ if(!this.shiftRow) {
+ this.shiftRow = this.activeRow;
+ }
+ } else {
+ this.shiftRow = null;
+ }
+ },
+
+ setSelection: function(range) {
+ var i = range[0];
+ range[1] = (range[1] + 1) % this.rowCount;
+ while (i != range[1]) {
+ this.addRowToSelection(i);
+ i = (i + 1) % this.rowCount;
+ }
+ while (i != range[0]) {
+ this.removeRowFromSelection(i);
+ i = (i + 1) % this.rowCount;
+ }
+ },
+
+ resetSelection: function(e) {
+ if(e.shiftKey) {
+ document.selection.empty();
+ }
+ },
+
+ /*
+ Row selection modified because we don't support frozen columns
+ */
+
+ addRowToSelection: function(rowIndex) {
+ this.selection.addId(rowIndex);
+ var nElement = $(this.prefix + ":n:" + rowIndex);
+ Element.addClassName(nElement, "extdt-row-selected");
+ Element.addClassName(nElement, "rich-sdt-row-selected");
+ Element.addClassName(nElement, this.selectedClass);
+ },
+
+ removeRowFromSelection: function(rowIndex) {
+ this.selection.removeId(rowIndex);
+ var nElement = $(this.prefix + ":n:" + rowIndex);
+ Element.removeClassName(nElement, "extdt-row-selected");
+ Element.removeClassName(nElement, "rich-sdt-row-selected");
+ Element.removeClassName(nElement, this.selectedClass);
+ },
+
+ setActiveRow: function(rowIndex) {
+ var fElement, nElement;
+ if(this.activeRow != null) {
+ nElement = $(this.prefix + ":n:" + this.activeRow);
+ Element.removeClassName(nElement, "extdt-row-active");
+ Element.removeClassName(nElement, "rich-sdt-row-active");
+ Element.removeClassName(nElement, this.activeClass);
+ }
+ nElement = $(this.prefix + ":n:" + rowIndex);
+ Element.addClassName(nElement, "extdt-row-active");
+ Element.addClassName(nElement, "rich-sdt-row-active");
+ Element.addClassName(nElement, this.activeClass);
+ this.activeRow = rowIndex;
+ }
+});
Added: trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUILib.js
===================================================================
--- trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUILib.js
(rev 0)
+++ trunk/sandbox/ui/extendedDataTable/src/main/javascript/ClientUILib.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,350 @@
+// ClientUILib base.js v1.0.0, Fri Jan 19 19:16:36 CET 2007
+
+// TODO: Copyright (c) 2007, Denis Morozov (dmorozov(a)exadel.com)
+// ...
+
+if(!ClientUILib) {
+
+var ClientUILib = {
+ Version: '1.0.0',
+ Name: 'ClientUILib',
+ LibraryPath: './',
+ packages: [],
+ load: function(showLog) {
+ // Check for Prototype JavaScript framework
+
+ if((typeof Prototype=='undefined') ||
+ (typeof Element == 'undefined') ||
+ (typeof Element.Methods=='undefined') ||
+ parseFloat(Prototype.Version.split(".")[0] + "." +
+ Prototype.Version.split(".")[1]) < 1.5)
+ throw("ClientUILib requires the Prototype JavaScript framework >=
1.5.0");
+
+ // Check for Extend JavaScript library
+// if((typeof Extend=='undefined') ||
+// Extend.VERSION < 1.1)
+// throw("ClientUILib requires the Extend JavaScript library >= 1.1");
+
+ $A(document.getElementsByTagName("script")).findAll( function(s) {
+ return (s.src && s.src.match(/ClientUILib\.js(\?.*)?$/))
+ }).each( function(s) {
+ LibraryPath = s.src.replace(/ClientUILib\.js(\?.*)?$/,'');
+ });
+
+ if(showLog) {
+ ClientUILogger.create("ClientUILogger");
+ this.startTime = (new Date()).getTime();
+ }
+
+ this.initBrowser();
+ },
+ include: function(libraryPackageName) {
+ if(!this.packages)
+ this.packages=[];
+ if(!this.packages[libraryPackageName]) {
+ this.packages[libraryPackageName] = true;
+ var re = /\./g; // Replace all '.' in package name
+ var packagePath = LibraryPath + libraryPackageName.replace(re, "/");
+ document.write('<script type="text/javascript" src="' +
packagePath + '.js"></script>');
+ }
+ },
+ include2: function(libraryPackageName) {
+ if(!this.packages)
+ this.packages=[];
+ if(!this.packages[libraryPackageName]) {
+ this.packages[libraryPackageName] = true;
+ var re = /\./g; // Replace all '.' in package name
+ var packagePath = LibraryPath + libraryPackageName.replace(re, "/");
+ var e = document.createElement("script");
+ e.src = packagePath+".js";
+ e.type="text/javascript";
+ document.getElementsByTagName("head")[0].appendChild(e);
+ }
+ },
+ requireClass: function(libName) {
+ // required class not included before
+ if(!this.packages[libName]) {
+ //this.include2(libName);
+ ClientUILib.log(ClientUILogger.ERROR, "Library '" + libName +
"' required!!!");
+ throw("Package '" + libName + "' is required!");
+ }
+ },
+ declarePackage: function(libName) {
+ var pckg = null;
+ var packages = $A(libName.split("."));
+ packages.each( function(s) {
+ if(pckg == null)
+ pckg = eval(s);
+ else {
+ if(!pckg[s]) pckg[s] = {};
+ pckg = pckg[s];
+ }
+ });
+ this.packages[libName] = true;
+ },
+ log: function(level, infoText) {
+ if(ClientUILogger.isCreated){
+ ClientUILogger.log(level, infoText);
+ } else {
+ switch(level) {
+ case ClientUILogger.INFO: LOG.info(infoText); break;
+ case ClientUILogger.ERROR: LOG.error(infoText); break;
+ case ClientUILogger.WARNING: LOG.warn(infoText); break;
+ default: LOG.a4jDebug(infoText);;
+ }
+ }
+ },
+
+ initBrowser: function() {
+ var ua = navigator.userAgent.toLowerCase();
+ /** @type Boolean */
+ this.isOpera = (ua.indexOf('opera') > -1);
+ /** @type Boolean */
+ this.isSafari = (ua.indexOf('webkit') > -1);
+ /** @type Boolean */
+ this.isIE = (window.ActiveXObject);
+ /** @type Boolean */
+ this.isIE7 = (ua.indexOf('msie 7') > -1);
+ /** @type Boolean */
+ this.isGecko = !this.isSafari && (ua.indexOf('gecko') > -1);
+
+ if(ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1){
+ /** @type Boolean */
+ this.isWindows = true;
+ }else if(ua.indexOf("macintosh") != -1){
+ /** @type Boolean */
+ this.isMac = true;
+ }
+ if(this.isIE && !this.isIE7){
+ try{
+ document.execCommand("BackgroundImageCache", false, true);
+ }catch(e){}
+ }
+ }
+};
+
+var ClientUILogger = {
+ // log level
+ INFO: 1,
+ WARNING: 2,
+ ERROR: 3,
+ EVENT: 4, //KAW EVENT level added to trace events
+ ALERT: 5, //KAW ALERT level to stop executing script
+ hEnabledLevels: {
+ 1: true,
+ 2: true,
+ 3: true,
+ 4: true,
+ 5: false
+ },
+ // flag logger is initialized
+ isCreated: false,
+ width: 460,
+ height: 600,
+ top: 0,
+ left: 750,
+ bLoggingEnabled: true,
+ create: function() {
+ this.mainDiv = $(document.createElement("div"));
+ this.mainDiv.setStyle({border: '1px black solid',
+ position: 'absolute',padding: '1px'});
+ this.logElement = $(document.createElement("div"));
+ this.logElement.setStyle({overflow: 'auto', whiteSpace: 'nowrap'});
+ this.buttonsContainer = $(document.createElement("div"));
+
+ var clearDiv = this.buttonClear = $(document.createElement('div'));
+ clearDiv.setStyle({width: 120 + 'px', height: 25 + 'px',
+ border: '1px black solid'});
+ clearDiv.innerHTML = 'Clear';
+
+ var toggleLoggingDiv = this.buttonToggleLogging =
$(document.createElement('div'));
+ toggleLoggingDiv.setStyle({width: 120 + 'px', height: 25 + 'px',
+ border: '1px black solid', position: 'relative',
+ top: '-27px', left: '122px'
+ });
+ toggleLoggingDiv.innerHTML = 'Logging '+this.isLoggingEnabled();
+
+ var toggleAlertDiv = this.buttonToggleAlert =
$(document.createElement('div'));
+ toggleAlertDiv.setStyle({width: 120 + 'px', height: 25 + 'px',
+ border: '1px black solid', position: 'relative',
+ top: '-54px', left: '244px'
+ });
+ toggleAlertDiv.innerHTML = 'Alert
'+this.isLevelEnabled(ClientUILogger.ALERT);
+
+ this.buttonsContainer.appendChild(clearDiv);
+ this.buttonsContainer.appendChild(toggleLoggingDiv);
+ this.buttonsContainer.appendChild(toggleAlertDiv);
+ this.mainDiv.appendChild(this.logElement);
+ this.mainDiv.appendChild(this.buttonsContainer);
+
+ this.eventClearClicked = this.onClearClick.bindAsEventListener(this);
+ this.eventToggleLoggingClicked = this.onToggleLoggingClick.bindAsEventListener(this);
+ this.eventToggleAlertClicked = this.onToggleAlertClick.bindAsEventListener(this);
+ Event.observe(toggleLoggingDiv, 'click',
ClientUILogger.eventToggleLoggingClicked);
+ Event.observe(toggleAlertDiv, 'click',
ClientUILogger.eventToggleAlertClicked);
+ Event.observe(clearDiv, 'click', ClientUILogger.eventClearClicked);
+ Event.observe(window, 'load', ClientUILogger.init);
+ Event.observe(window, 'resize', ClientUILogger.resizeWindow);
+
+ this.isCreated = true;
+ },
+ onToggleAlertClick: function() {
+ this.toggleLevel(ClientUILogger.ALERT);
+ this.buttonToggleAlert.innerHTML = 'Alert
'+this.isLevelEnabled(ClientUILogger.ALERT);
+ },
+ onToggleLoggingClick: function(event) {
+ this.toggleLogging();
+ this.buttonToggleLogging.innerHTML = 'Logging '+this.isLoggingEnabled();
+ },
+ onClearClick: function(event) {
+ Event.stop(event);
+ this.logElement.innerHTML = '';
+ },
+ init: function() {
+ if(ClientUILogger.mainDiv)
+ document.body.appendChild(ClientUILogger.mainDiv);
+ ClientUILogger.show();
+ },
+ resizeWindow: function() {
+ ClientUILogger.show();
+ },
+ show: function() {
+ if(this.logElement) {
+ Element.show(this.mainDiv);
+ this.mainDiv.setStyle({width: this.width + 'px',
+ height: this.height + 'px',
+ top: this.top + 'px',
+ left: this.left+ 'px',
+ zIndex: '1000'});
+ this.logElement.setStyle({width: '100%', height: '90%'});
+ this.buttonsContainer.setStyle({width: '100%', height: '10%'});
+ //this.logElement.setStyle({top: (this.getWindowHeight() - this.height - 10) +
'px'});
+ //this.logElement.setStyle({top: 10 + 'px'});
+ //this.logElement.setStyle({left: (this.getWindowWidth() - this.width - 10) +
'px'});
+ //KAW changed logger display place
+ }
+ },
+ isLevelEnabled: function(level) {
+ return this.hEnabledLevels[level];
+ },
+ isLoggingEnabled: function() {
+ return this.bLoggingEnabled;
+ },
+ toggleLogging: function() {
+ this.bLoggingEnabled = !this.bLoggingEnabled;
+ },
+ toggleLevel: function(level) {
+ this.hEnabledLevels[level] = !this.hEnabledLevels[level];
+ },
+ log: function(level, infoText) {
+ var bIgnoreLog = !this.isLoggingEnabled() || !this.isLevelEnabled(level);
+ if (bIgnoreLog) {
+ //PREMATURE RETURN no logging required
+ return;
+ }
+ var msg = $(document.createElement("div"));
+ this.logElement.appendChild(msg);
+ msg.setStyle({width: '100%'});
+
+ var font = "bold normal bold 10pt Arial";
+ var fontColor = "red";
+
+ if (level == ClientUILogger.ALERT) {
+ alert(infoText);
+ }else{
+ switch(level) {
+ case ClientUILogger.INFO:
+ fontColor = "black";
+ font = "normal normal normal 10pt Arial";
+ break;
+ case ClientUILogger.WARNING:
+ fontColor = "blue";
+ font = "italic normal normal 10pt Arial";
+ break;
+ case ClientUILogger.ERROR:
+ fontColor = "red";
+ font = "normal normal bold 10pt Arial";
+ break;
+ case ClientUILogger.EVENT:
+ fontColor = "green";
+ font = "normal normal bold 10pt Arial";
+ break;
+ default:
+ infoText = "UNRESOLVED: level=" + level + ", msg=" + infoText;
+ }
+ msg.setStyle({font: font});
+ msg.setStyle({color: fontColor});
+ msg.appendChild(document.createTextNode("> " + infoText));
+
+ this.logElement.scrollTop = this.logElement.scrollHeight;
+ }
+ },
+ getWindowWidth: function(){
+ var innerWidth;
+ if (navigator.appVersion.indexOf('MSIE')>0) {
+ innerWidth = document.body.clientWidth;
+ } else {
+ innerWidth = window.innerWidth;
+ }
+ return innerWidth;
+ },
+ getWindowHeight: function(){
+ var innerHeight;
+ if (navigator.appVersion.indexOf('MSIE')>0) {
+ innerHeight = document.body.clientHeight;
+ } else {
+ innerHeight = window.innerHeight;
+ }
+ return innerHeight;
+ }
+};
+
+ClientUILib.load(true); //KAW debugging ON
+
+// declare predefined packages
+var ClientUI = {
+ controls: {},
+ layouts: {}
+};
+
+// Some helper functions\
+if(!ClientUILib.isIE){
+ HTMLElement.prototype.click = function() {
+ var evt = this.ownerDocument.createEvent('MouseEvents');
+ evt.initMouseEvent('click', true, true, this.ownerDocument.defaultView, 1, 0,
0, 0, 0, false, false, false, false, 0, null);
+ this.dispatchEvent(evt);
+ }
+};
+
+// Usage: Event.onReady(callbackFunction);
+Object.extend(Event, {
+ _domReady : function() {
+ if (arguments.callee.done) return;
+ arguments.callee.done = true;
+
+ if (Event._timer) clearInterval(Event._timer);
+
+ Event._readyCallbacks.each(function(f) { f() });
+ Event._readyCallbacks = null;
+ },
+ onReady : function(f) {
+ if (!this._readyCallbacks) {
+ var domReady = this._domReady;
+
+ if (domReady.done) return f();
+
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", domReady, false);
+ if (/WebKit/i.test(navigator.userAgent)) {
+ this._timer = setInterval(function() {
+ if (/loaded|complete/.test(document.readyState)) domReady();
+ }, 10);
+ }
+ Event.observe(window, 'load', domReady);
+ Event._readyCallbacks = [];
+ }
+ Event._readyCallbacks.push(f);
+ }
+});
+
+};
Added:
trunk/sandbox/ui/extendedDataTable/src/main/javascript/common/prototype/ext/extend.js
===================================================================
--- trunk/sandbox/ui/extendedDataTable/src/main/javascript/common/prototype/ext/extend.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/javascript/common/prototype/ext/extend.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,189 @@
+// vim: tw=80 ts=4 sw=4 noet
+// ----------------------------------------------------------------------------
+// Project : Extend - Prototype OOP extension
+// URL : <
http://www.ivy.fr/js/extend>
+// ----------------------------------------------------------------------------
+// Author : Sebastien Pierre <sebastien(a)ivy.fr>
+// License : Revised BSD License
+// ----------------------------------------------------------------------------
+// Creation : 08-Sep-2006
+// Last mod : 17-Nov-2006
+// ----------------------------------------------------------------------------
+
+// The Extend object holds all the information required to implement the
+// inheritance and other OO-goodness.
+if(!window.Extend) {
+
+Extend = {
+ VERSION: 1.1,
+ CLASSDEF: "CLASSDEF",
+ DELETE: "DELETE",
+ // These are a list of methods of class instances that are reserved by the
+ // OO layer (see the reparent method for more info)
+ INSTANCE_RESERVED: {
+ CLASSDEF: true,
+ getClass: true,
+ parentClass: true
+ },
+
+ // Sets up a class
+ setupClass: function( _class, declaration )
+ {
+ // We create an empty prototype if the user did not provide one
+ declaration = declaration || {}
+ _class.prototype = declaration
+ // We clone the given method definition, because they will be augmented
+ // with the ones defined in the parent class
+ _class.methods = {}
+ for ( var key in declaration ) { _class.methods[key] = declaration[key] }
+ _class.inherited = {}
+ _class.parentClass = undefined
+ if ( declaration[Extend.CLASSDEF] )
+ { _class.className = declaration[Extend.CLASSDEF].name }
+ else
+ { _class.className = undefined }
+ _class.subclasses = _class.subclasses || []
+ _class.constructor = Extend.Operations.constructor
+ _class.reparent = Extend.Operations.reparent
+ _class.method = Extend.Operations.method
+ _class.update = Extend.Operations.update
+ if ( declaration[Extend.CLASSDEF] )
+ { _class.reparent(declaration[Extend.CLASSDEF].parent) }
+ // We update the class methods with an `ofClass` method that returns the
+ // class, so that instances will have a proper
+ declaration.getClass = function() {return _class}
+ declaration.parentClass = function() {return this.getClass().parentClass}
+ declaration.parentCall = function() {
+ var new_args = []
+ for ( var i=1;i<arguments.length;i++ ) {new_args.push(arguments[i])}
+ return this.parentClass().method(arguments[0]).apply(this, new_args)
+ }
+ declaration.setClass = function(newClass) {
+ return this.getClass().parentClass
+ }
+ // We reparent the subclasses if any
+ for ( var i=0 ; i<_class.subclasses ; i++ ) {
+ _class.subclasses[i].reparent(_class)
+ }
+ return _class
+ },
+ // These are operations that will be "mixed-in" with the new classes
+ Operations: {
+ constructor: function() {
+ return this.prototype.initialize || function() {}
+ },
+ // Reparents this class
+ reparent: function( newParentClass )
+ {
+ if ( this.parentClass )
+ {
+ var this_index = this.subclasses.indexOf(this)
+ this.parentClass.subclasses.splice(this_index, 1)
+ for ( var method_name in this.inherited ) {
+ this.method(method_name, null, this.parentClass)
+ }
+ }
+ this.parentClass = newParentClass
+ if ( !newParentClass ) return
+ var parent_methods = newParentClass.prototype
+ // We iterate on all the parent methods
+ for ( parent_method_name in parent_methods ) {
+ // If the method is a reserved one, we skip it
+ if ( Extend.INSTANCE_RESERVED[parent_method_name] == true ) { continue }
+ // If the method is not directly defined in the current class, we add it
+ if ( this.methods[parent_method_name] == undefined )
+ {
+ this.method( parent_method_name,
+ parent_methods[parent_method_name],
+ newParentClass.inherited[parent_method_name] || newParentClass
+ )
+ }
+ }
+ newParentClass.subclasses.push(this)
+ },
+ update: function(newPrototype) {
+ Extend.setupClass(this, newPrototype||this.prototype)
+ },
+ // Returns, sets or deletes a method in this class
+ method: function( name, body, declaredIn ) {
+ if ( body == undefined )
+ {
+ var method = this.prototype[name]
+ if ( name == undefined ) throw new Error("Method not found: "+name)
+ return method
+ }
+ else
+ {
+ declaredIn = declaredIn || this
+ // If the method is declared in this class
+ if ( declaredIn == this )
+ {
+ if ( body == Extend.DELETE ) {
+ delete this.methods[name]
+ delete this.inherited[name]
+ delete this.prototype[name]
+ // If the method is defined in the parent we set it
+ if ( this.parentClass ) {
+ var parent_method = this.parentClass.method(name)
+ if ( parent_method ) {
+ this.method(name, parent_method, this.parentClass.inherited[name] ||
this.parentClass)
+ }
+ }
+ } else {
+ this.methods[name] = body
+ this.prototype[name] = body
+ delete this.inherited[name]
+ }
+ }
+ // Or if its declared in another class
+ else
+ {
+ if ( body == Extend.DELETE ) {
+ delete this.inherited[name]
+ delete this.methods[name]
+ delete this.prototype[name]
+ // If the method is defined in the parent we set it
+ if ( this.parentClass ) {
+ var parent_method = this.parentClass.method(name)
+ if ( parent_method ) {
+ this.method(name, parent_method, this.parentClass.inherited[name] ||
this.parentClass)
+ }
+ }
+ }
+ else {
+ if ( this.methods[name] == undefined ) {
+ this.inherited[name] = declaredIn
+ this.prototype[name] = body
+ }
+ }
+ }
+ for ( var i=0 ; i<this.subclasses.length ; i++ )
+ {
+ this.subclasses[i].method(name,body,declaredIn)
+ }
+ }
+ }
+ }
+}
+
+// In case prototype is not available, we use this instead
+try {
+ Class = Class
+} catch ( Error ) {
+ Class = {create:function() {return function() {this.initialize.apply(this,
arguments)}}}
+}
+Class._create = Class.create
+Class.create = function( declaration ) {
+ var new_class = Extend.setupClass(Class._create(declaration), declaration)
+ // The following only works on FireFox
+ /*
+ new_class.watch("prototype", function(id,oldval,newval) {
+ new_class.prototype = newval
+ Extend.setupClass(new_class, newval)
+ return newval
+ })*/
+ return new_class
+};
+
+};
+// EOF
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/css/extendedDataTable.xcss
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/css/extendedDataTable.xcss
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/css/extendedDataTable.xcss 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,632 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<f:template
xmlns:f='http:/jsf.exadel.com/template'
+
xmlns:u='http:/jsf.exadel.com/template/util'
+
xmlns="http://www.w3.org/1999/xhtml" >
+
+
+ <f:verbatim>
+
+ ul,ol,li{
+ margin: 0;
+ padding: 0;
+ }
+ ol,ul{
+ list-style: none;
+ }
+
+ /**
+ * Body cell declaration
+ * dr-sdt-bc - reqired
+ * dr-sdt-bcDef - default, used if no custom styles defined in body template
+ */
+ .dt-sdt-bc {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -moz-outline: none;
+ -moz-user-focus: normal;
+ cursor: default;
+ border-right: 1px solid;
+ border-bottom: 1px solid;
+ }
+
+ .extdt-dr-table {
+ table-layout: fixed;
+ }
+
+ .extdt-table-filterrow{
+ }
+
+ .dt-sdt-rb {
+ font-weight: normal;
+ white-space: nowrap;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ }
+
+ .extdt-subheadercell {
+ overflow: hidden;
+ }
+
+ .dt-sdt-bcbody {
+ cursor: default;
+ font-weight: normal;
+ white-space: nowrap;
+ overflow: hidden;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ -moz-box-sizing: border-box;
+ -moz-outline: none;
+ width: 100%;
+ height: 20px;
+ }
+
+ .extdt-dr-menucell{
+ }
+
+ .extdt-dr-menucell: hover{
+ background-position: center right;
+ background-repeat: no-repeat;
+ }
+
+ .extdt-maindiv {
+ background-repeat:no-repeat;
+ background-position:center;
+ }
+
+ .extdt-menu-div {
+ height: 23px;
+ position: absolute;
+ width: 20px;
+ }
+
+ .extdt-group-row {
+ height: 15px;
+ }
+
+ .extdt-group-text {
+ font-family: Arial,Verdana,sans-serif;
+ font-size: 11px;
+ margin-left: 10px;
+ }
+
+ .extdt-group-cell {
+ height: 15px;
+ background-color: #eeeeee;
+ border-bottom: 1px #c0c0c0 solid;
+ border-top: 1px #c0c0c0 solid;
+ padding: 0px;
+ }
+
+ .extdt-group-image-expanded {
+ height: 10px;
+ width: 10px;
+ background-repeat:no-repeat;
+ background-position:center;
+ }
+
+ .extdt-group-image-folded {
+ height: 10px;
+ width: 10px;
+ background-repeat:no-repeat;
+ background-position:center;
+ }
+
+ .dr-sdt-hsplit {
+ width:1px;
+ border-right: 1px dashed;
+ cursor: e-resize;
+ z-index: 100;
+ }
+
+ .dt-menu{
+ border: 1px solid #718bb7;
+ z-index: 15000;
+ zoom: 1;
+ /*background: #f0f0f0 url(menu.gif) repeat-y;*/
+ background-color: #f0f0f0;
+ background-repeat: repeat-y;
+ padding: 2px;
+ position: absolute;
+ }
+ .dt-menu a{
+ text-decoration:none!important;
+ }
+ .dt-menu-list{
+ background: transparent none repeat scroll 0% 50%;
+ border: 0 none;
+ }
+ .dt-menu-list-item{
+ font: normal 11px tahoma,arial,sans-serif;
+ white-space: nowrap;
+ -moz-user-select: none;
+ -khtml-user-select: none;
+ display: block;
+ padding: 1px;
+ }
+ .dt-menu a.dt-menu-item{
+ display: block;
+ line-height: 16px;
+ padding: 3px 21px 3px 3px;
+ white-space: nowrap;
+ text-decoration: none;
+ color: #222;
+ -moz-outline: 0 none;
+ outline: 0 none;
+ cursor: pointer;
+ }
+ .dt-menu-item-icon{
+ border: 0 none;
+ height: 16px;
+ padding: 0;
+ vertical-align: top;
+ width: 16px;
+ margin:0 8px 0 0;
+ background-position: center;
+ }
+ .dt-menu-check-item .dt-menu-item-icon{
+ /*background: transparent url(unchecked.gif) no-repeat center;*/
+ background-color: transparent;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
+ .dt-menu-item-checked .dt-menu-item-icon{
+ /*background-image: url(checked.gif);*/
+ }
+
+ /**
+ * Header cells drop target
+ */
+ .dt-sdt-hdrop {
+ cursor: pointer;
+ font-size: 1px;
+ width: 10px;
+ height: 13px;
+ top: 0;
+ /*overflow: hidden;*/
+ position: absolute;
+ display: block;
+ white-space: nowrap;
+ z-index: 61;
+ }
+
+ .dt-sdt-hdrop-top {
+ /*background-image: url(col-move-top.gif);*/
+ background-repeat: no-repeat;
+ /*background-position: top center;*/
+ display: block;
+ width:100%;
+ height:50%;
+ position: relative;
+ top: -9px;
+ }
+
+ .dt-sdt-hdrop-top-left{
+ background-position: top left;
+ left: -5px;
+ }
+
+ .dt-sdt-hdrop-top-right{
+ background-position: top right;
+ right: -4px;
+ }
+
+ .dt-sdt-hdrop-bottom {
+ /*background-image: url(col-move-top.gif);*/
+ background-repeat: no-repeat;
+ /*background-position: bottom center;*/
+ display: block;
+ width:100%;
+ height:50%;
+ position: relative;
+ top: 9px;
+ }
+
+ .dt-sdt-hdrop-bottom-left{
+ background-position: bottom left;
+ left: -5px;
+ }
+
+ .dt-sdt-hdrop-bottom-right{
+ background-position: bottom right;
+ right: -4px;
+ }
+
+ .dt-cell-div {
+ cursor: default;
+ font-weight: normal;
+ white-space: nowrap;
+ overflow: hidden;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ -moz-box-sizing: border-box;
+ -moz-outline: none;
+ width: 100%;
+ }
+
+ .extdt-innerdiv{
+ top: 0px;
+ left: 0px;
+ position: absolute;
+ }
+
+ .extdt-outerdiv{
+ position:relative;
+ padding: 1px;
+ width: 100%;
+ }
+
+ /**
+ * Header cells separator
+ */
+ .dt-sdt-hsep {
+ /* background-image: url(grid-split.gif);*/
+ background-position: center;
+ background-repeat: repeat-y;
+ cursor: e-resize;
+ font-size: 1px;
+ width: 6px;
+ height: 13px;
+ overflow: hidden;
+ top: 0;
+ position: absolute;
+ display: block;
+ white-space: nowrap;
+ z-index: 60;
+ }
+
+ .extdt-content{
+ overflow-x:hidden;
+ overflow-y:auto;
+ }
+
+ .extdt-splscr-hddn{
+ }
+
+ .extdt-splscr-vsbl{
+ }
+
+ </f:verbatim>
+
+<u:selector name=".extdt-menu-div" >
+ <u:style name="background-image">
+ <f:resource f:key="/org/richfaces/renderkit/html/images/s.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dr-sdt-hsplit" >
+ <u:style name="background-image">
+ <f:resource f:key="/org/richfaces/renderkit/html/images/s.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dt-sdt-hdrop" >
+ <u:style name="background-image">
+ <f:resource f:key="/org/richfaces/renderkit/html/images/s.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".extdt-splscr-vsbl" >
+ <u:style name="border" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+</u:selector>
+
+<u:selector name=".extdt-dr-table" >
+ <u:style name="background-color" skin="tableBackgroundColor"
/> <!--tableBackgroundColor-->
+ <!-- <u:style name="border-collapse" value="inherit" /> fix
RF-535 -->
+ <u:style name="empty-cells" value="show" />
+ <u:style name="border-collapse" value="collapse" />
+</u:selector>
+
+<u:selector name=".extdt-dr-menucell: hover">
+ <u:style name="background-image">
+ <f:resource
f:key="/org/richfaces/renderkit/html/images/menuHover.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".extdt-maindiv">
+ <u:style name="border" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="background-image">
+ <f:resource f:key="/org/richfaces/renderkit/html/images/loading.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".extdt-group-image-expanded">
+ <u:style name="background-image">
+ <f:resource
f:key="/org/richfaces/renderkit/html/images/minusIcon.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".extdt-group-image-folded">
+ <u:style name="background-image">
+ <f:resource
f:key="/org/richfaces/renderkit/html/images/plusIcon.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dt-menu">
+ <u:style name="background-image">
+ <f:resource f:key="/org/richfaces/renderkit/html/images/menu.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dt-menu-check-item .dt-menu-item-icon">
+ <u:style name="background-image">
+ <f:resource
f:key="/org/richfaces/renderkit/html/images/unchecked.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dt-menu-item-checked .dt-menu-item-icon">
+ <u:style name="background-image">
+ <f:resource f:key="/org/richfaces/renderkit/html/images/checked.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dt-sdt-hdrop-top">
+ <u:style name="background-image">
+ <f:resource
f:key="/org/richfaces/renderkit/html/images/col-move-top.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dt-sdt-hdrop-bottom">
+ <u:style name="background-image">
+ <f:resource
f:key="/org/richfaces/renderkit/html/images/col-move-bottom.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dt-sdt-hsep">
+ <u:style name="background-image">
+ <f:resource
f:key="/org/richfaces/renderkit/html/images/sep-span.gif"/>
+ </u:style>
+</u:selector>
+
+<u:selector name=".dr-table" >
+ <u:style name="border-top" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-left" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="background-color" skin="tableBackgroundColor"
/> <!--tableBackgroundColor-->
+ <!-- <u:style name="border-collapse" value="inherit" /> fix
RF-535 -->
+ <u:style name="empty-cells" value="show" />
+ <u:style name="border-collapse" value="collapse" />
+</u:selector>
+
+<u:selector name=".dr-table-cell" >
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="padding" value="4px 4px 4px 4px"/>
+ <u:style name="font-size" skin="generalSizeFont"/>
<!--generalSizeFont-->
+ <u:style name="color" skin="generalTextColor"/>
<!--generalTextColor-->
+ <u:style name="font-family" skin="generalFamilyFont"/>
<!--generalFamilyFont-->
+</u:selector>
+
+<u:selector name=".dr-subtable-cell" >
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="padding" value="4px 4px 4px 4px"/>
+ <u:style name="font-size" skin="generalSizeFont"/>
<!--generalSizeFont-->
+ <u:style name="color" skin="generalTextColor"/>
<!--generalTextColor-->
+ <u:style name="font-family" skin="generalFamilyFont"/>
<!--generalFamilyFont-->
+</u:selector>
+
+<u:selector name=".dr-table-header" >
+ <u:style name="background-color"
skin="headerBackgroundColor"/> <!--headerBackgroundColor-->
+ <u:style name="background-image" > <!--from headerGradientColor to
headerBackgroundColor-->
+ <f:resource f:key="org.richfaces.renderkit.html.GradientA"/>
+ </u:style>
+ <u:style name="background-position" value="top left"/>
+ <u:style name="background-repeat" value="repeat-x"/>
+</u:selector>
+
+<u:selector name=".dr-table-header-continue" >
+ <u:style name="background-color"
skin="headerBackgroundColor"/> <!--headerBackgroundColor-->
+</u:selector>
+
+<u:selector name=".dr-table-headercell" >
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="padding" value="4px 4px 4px 4px"/>
+ <u:style name="color" skin="headerTextColor"/>
<!--headerTextColor-->
+ <u:style name="text-align" value="center"/>
+ <u:style name="font-weight" skin="headerWeightFont"/>
+ <u:style name="font-size" skin="generalSizeFont"/>
<!--generalSizeFont-->
+ <u:style name="font-family" skin="generalFamilyFont"/>
<!--generalFamilyFont-->
+</u:selector>
+
+<u:selector name=".dr-table-subheader" >
+ <u:style name="background-color"
skin="additionalBackgroundColor"/> <!--additionalBackgroundColor-->
+</u:selector>
+
+<u:selector name=".extdt-table-filterrow" >
+ <u:style name="background-color"
skin="additionalBackgroundColor"/> <!--additionalBackgroundColor-->
+ <u:style name="border-top" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+</u:selector>
+
+<u:selector name=".dr-table-thead" >
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+</u:selector>
+
+<u:selector name=".extdt-subheadercell" >
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="padding" value="4px 4px 4px 4px"/>
+ <u:style name="text-align" value="center"/>
+ <u:style name="font-size" skin="generalSizeFont"/>
<!--generalSizeFont-->
+ <u:style name="color" skin="generalTextColor"/>
<!--generalTextColor-->
+ <u:style name="font-family" skin="generalFamilyFont"/>
<!--generalFamilyFont-->
+ <u:style name="white-space" value="nowrap"/>
+</u:selector>
+
+<f:verbatim>
+ .dr-table-sortable-header {
+ background-position: right center;
+ background-repeat: no-repeat;
+ white-space : nowrap;
+ }
+
+ .dr-table-cursor-pointer {
+ cursor: pointer;
+ }
+
+ .rich-inplace-edit, .rich-inplace-view {
+ cursor: default;
+ }
+
+ .dr-table-header-sort-img {
+ vertical-align: middle;
+ }
+</f:verbatim>
+
+<u:selector name=".dr-table-footer" >
+ <u:style name="background-color"
skin="tableFooterBackgroundColor"/> <!--tableFooterBackgroundColor-->
+</u:selector>
+
+
+<u:selector name=".dr-table-footer-continue" >
+ <u:style name="background-color"
skin="tableFooterBackgroundColor"/> <!--tableFooterBackgroundColor-->
+</u:selector>
+
+<u:selector name=".dr-table-footercell" >
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="padding" value="4px 4px 4px 4px"/>
+ <u:style name="color" skin="generalTextColor"/>
<!--headerTextColor-->
+ <u:style name="text-align" value="left"/>
+ <u:style name="font-weight" skin="headerWeightFont"/>
+ <u:style name="font-size" skin="generalSizeFont"/>
<!--generalSizeFont-->
+ <u:style name="font-family" skin="generalFamilyFont"/>
<!--generalFamilyFont-->
+</u:selector>
+
+<u:selector name=".dr-table-subfooter" >
+ <u:style name="background-color"
skin="tableSubfooterBackgroundColor"/>
<!--tableSubfooterBackgroundColor-->
+</u:selector>
+
+<u:selector name=".dr-table-subfootercell" >
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="padding" value="4px 4px 4px 4px"/>
+ <u:style name="text-align" value="left"/>
+ <u:style name="font-size" skin="generalSizeFont"/>
<!--generalSizeFont-->
+ <u:style name="color" skin="generalTextColor"/>
<!--generalTextColor-->
+ <u:style name="font-family" skin="generalFamilyFont"/>
<!--generalFamilyFont-->
+</u:selector>
+
+<u:selector name=".dr-table-firstrow .dr-table-cell" >
+<!-- <u:style name="border-top" value="2px solid">
+ <f:verbatim skin="tableBorderColor" />
+ </u:style> -->
+</u:selector>
+
+<u:selector name=".dr-subtable-firstrow .dr-subtable-cell" >
+ <!-- <u:style name="border" value="2px solid
#c0c0c0"/>-->
+</u:selector>
+
+<u:selector name=".dr-subtable-header" >
+ <u:style name="background-color"
skin="additionalBackgroundColor"/> <!--additionalBackgroundColor-->
+</u:selector>
+
+<u:selector name=".dr-subtable-headercell" >
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="padding" value="4px 4px 4px 4px"/>
+ <u:style name="text-align" value="center"/>
+ <u:style name="font-size" skin="generalSizeFont"/>
<!--generalSizeFont-->
+ <u:style name="color" skin="generalTextColor"/>
<!--generalTextColor-->
+ <u:style name="font-family" skin="generalFamilyFont"/>
<!--generalFamilyFont-->
+</u:selector>
+
+
+<u:selector name=".dr-subtable-footer" >
+ <u:style name="background-color"
skin="tableSubfooterBackgroundColor"/>
<!--tableSubfooterBackgroundColor-->
+</u:selector>
+
+<u:selector name=".dr-subtable-footercell" >
+ <u:style name="border-right" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="border-bottom" value="solid">
<!--tableBorderColor-->
+ <f:verbatim skin="tableBorderWidth" />
+ <f:verbatim skin="tableBorderColor" />
+ </u:style>
+ <u:style name="padding" value="4px 4px 4px 4px"/>
+ <u:style name="text-align" value="left"/>
+</u:selector>
+
+<u:selector name=".rich-sort-asc">
+ <u:style name="background-image">
+ <f:resource
f:key="org.richfaces.renderkit.html.iconimages.DataTableIconSortAsc"/>
+ </u:style>
+</u:selector>
+<u:selector name=".rich-sort-desc">
+ <u:style name="background-image">
+ <f:resource
f:key="org.richfaces.renderkit.html.iconimages.DataTableIconSortDesc"/>
+ </u:style>
+</u:selector>
+<u:selector name=".extdt-row-selected">
+ <u:style name="background-color"
skin="additionalBackgroundColor" />
+</u:selector>
+<u:selector name=".dr-sdt-row-active">
+ <u:style name="color" skin="tabDisabledTextColor" />
+</u:selector>
+
+</f:template>
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/checked.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/checked.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/col-move-bottom.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/col-move-bottom.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/col-move-top.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/col-move-top.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/columns.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/columns.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/columns.png
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/columns.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/grid3-hd-btn.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/grid3-hd-btn.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/group-by.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/group-by.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/group-by.png
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/group-by.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/hmenu-asc.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/hmenu-asc.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/hmenu-desc.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/hmenu-desc.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/item-over.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/item-over.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/loading.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/loading.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu-sort-asc.png
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu-sort-asc.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu-sort-desc.png
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu-sort-desc.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menu.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menuHover.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/menuHover.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/minusIcon.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/minusIcon.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/plusIcon.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/plusIcon.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/s.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/s.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/sep-span.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/sep-span.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/unchecked.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/images/unchecked.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/dt-drag-indicator.js
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/dt-drag-indicator.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/dt-drag-indicator.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,209 @@
+DragIndicator = {
+
+ init: function(event) {
+ var ieVersion = RichFaces.getIEVersion();
+ DragIndicator.isIE6 = (ieVersion && ieVersion < 7);
+ },
+
+ setContent: function(name, single, params) {
+ Element.clearChildren(this);
+
+ var p = DnD.getDnDDefaultParams(this);
+
+ if (!p) {
+ p = {};
+ }
+
+ if (params) {
+ Object.extend(p, params);
+ }
+
+ if (!p['marker']) {
+ if (p[name]) {
+ p['marker'] = p[name];
+ } else {
+ p['marker'] = this.markers[name];
+ }
+ }
+
+ var parts;
+
+ if (single) {
+ parts = this.indicatorTemplates['single'];
+ } else {
+ parts = this.indicatorTemplates['multi'];
+ }
+
+ new Insertion.Top(this, parts.invoke('getContent', p).join(''));
+
+ if (DragIndicator.isIE6) {
+ this.initIFrame();
+ }
+ },
+
+ show: function() {
+ if (!this.floatedToBody) {
+ if (!this.realParent) {
+ this.realParent = this.parentNode;
+ this._nextSibling = this.nextSibling;
+ }
+ this.realParent.removeChild(this);
+ document.body.appendChild(this);
+ this.floatedToBody = true;
+ }
+ Element.show(this);
+ this.style.position = 'absolute';
+ },
+
+ hide: function() {
+ Element.hide(this);
+ this.style.position = '';
+ this.offsets = undefined;
+ this.leave();
+ if (this.floatedToBody && this.realParent) {
+ document.body.removeChild(this);
+ if (this._nextSibling) {
+ this.realParent.insertBefore(this, this._nextSibling);
+ } else {
+ this.realParent.appendChild(this);
+ }
+ this.floatedToBody = false;
+ }
+ },
+
+ position: function(x, y) {
+ if (!this.offsets) {
+ Element.show(this);
+ this.style.position = 'absolute';
+ }
+ Element.setStyle(this, {"left": x + "px", "top": y +
"px"});
+ },
+
+ accept: function() {
+ Element.removeClassName(this, 'drgind_default');
+ Element.removeClassName(this, 'drgind_reject');
+ Element.addClassName(this, 'drgind_accept');
+
+ var acceptClass = this.getAcceptClass();
+ if (acceptClass) {
+ Element.addClassName(this, acceptClass);
+ }
+ },
+
+ reject: function() {
+ Element.removeClassName(this, 'drgind_default');
+ Element.removeClassName(this, 'drgind_accept');
+ Element.addClassName(this, 'drgind_reject');
+
+ var rejectClass = this.getRejectClass();
+ if (rejectClass) {
+ Element.addClassName(this, rejectClass);
+ }
+ },
+
+ leave: function() {
+ Element.removeClassName(this, 'drgind_accept');
+ //Element.removeClassName(this, 'drgind_reject');
+ //Element.addClassName(this, 'drgind_default');
+ Element.removeClassName(this, 'drgind_default');
+ Element.addClassName(this, 'drgind_reject');
+
+ var acceptClass = this.getAcceptClass();
+ var rejectClass = this.getRejectClass();
+ if (acceptClass) {
+ Element.removeClassName(this, acceptClass);
+ }
+ if (rejectClass) {
+ Element.removeClassName(this, rejectClass);
+ }
+ },
+
+ getAcceptClass: function() {
+ return this.ils_acceptClass;
+ },
+
+ getRejectClass: function() {
+ return this.ils_rejectClass;
+ },
+
+ initIFrame: function() {
+ var iframe = document.createElement("iframe");
+ Element.addClassName(iframe, 'rich-dragindicator-iframe');
+ this.insertBefore(iframe, this.firstChild);
+ var table = iframe.nextSibling;
+ iframe.style.width = table.offsetWidth + "px";
+ iframe.style.height = table.offsetHeight + "px";
+ }
+};
+
+function createDragIndicator(elt, acceptClass, rejectClass) {
+ Object.extend(elt, DragIndicator);
+ elt.init();
+
+ elt.ils_acceptClass = acceptClass;
+ elt.ils_rejectClass = rejectClass;
+}
+
+// <table border="0" cellpadding="3" cellspacing="0"
class="drgind_internal" style="height : 100%">
+// <tr>
+// <td class="drgind_marker">
+// {marker}
+// </td>
+// <td class="drgind_text">
+// <div class="drgind_wordcut drgind_text_content">
+// {label}
+// </div>
+// </td>
+// </tr>
+// </table>
+// <div class="drgind_shadow" />
+DefaultDragIndicatorView =
+[
+ new E('table',
+ {
+ 'style':'height : 100%; z-index: 2;',
+ 'className':'drgind_internal',
+ 'cellspacing':'0',
+ 'cellpadding':'3',
+ 'border':'0'
+ },
+ [
+ new E('tbody',{},
+ [
+ new E('tr',{},
+ [
+ new E('td',
+ {
+ 'className':'drgind_marker'
+ },
+ [
+ new ET(function (context) { return Richfaces.eval("marker",
context)})
+ ]
+ ),
+ new E('td',
+ {
+ 'className':'drgind_text'
+ },
+ [
+ new E('div',
+ {
+ 'className':'drgind_wordcut drgind_text_content'
+ },
+ [
+ new ET(function (context) { return Richfaces.eval("label",
context)})
+ ]
+ )
+ ]
+ )
+ ]
+ )
+ ]
+ )
+ ]
+ ),
+ new E('div',
+ {
+ 'className':'drgind_shadow'
+ }
+ )
+];
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/simple-draggable.js
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/simple-draggable.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/simple-draggable.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,121 @@
+DnD.G3SimpleDraggable = Class.create();
+
+Object.extend(DnD.G3SimpleDraggable.prototype, DnD.Draggable.prototype);
+Object.extend(DnD.G3SimpleDraggable.prototype, {
+ initialize: function(id, options) {
+ this.id = $(id);
+
+ if (!this.id) {
+ alert("drag: Element with [" + id + "] ID was not found in the DOM
tree. Probably element has no client ID or client ID hasn't been written. DnD's
disabled. Check please!");
+ return ;
+ }
+
+ this.options = options;
+
+ this.dragIndicatorId = this.options.dragIndicator;
+
+ this.eventMouseDown = this.initDrag.bindAsEventListener(this);
+
+ Event.observe(this.id, "mousedown", this.eventMouseDown);
+
+ this.form = this.id;
+ while (this.form && !/^form$/i.test(this.form.tagName)) {
+ this.form = this.form.parentNode;
+ }
+
+ this.enableDraggableCursors(this.options.grab, this.options.grabbing);
+ },
+
+ getDnDDragParams: function() {
+ if (this.options.dndParams) {
+ return this.options.dndParams.parseJSON(EventHandlersWalk);
+ }
+
+ return null;
+ },
+
+ getIndicator: function() {
+ var dragIndicator = $(this.dragIndicatorId);
+ if (!dragIndicator) {
+ dragIndicator = this.getOrCreateDefaultIndicator();
+ }
+
+ return dragIndicator;
+ },
+
+ ondragstart : function(event, drag) {
+ this.showDropTargets();
+ drag.params = this.options.parameters;
+ drag.params[this.id] = this.id;
+
+ this.setIndicator(event);
+
+ this.getIndicator().leave();
+
+ //this.dragEnter(event);
+
+ if (this.form) {
+ drag.params[this.form.id] = this.form.id;
+ }
+ },
+
+ ondragend: function (event, drag) {
+ this.hideDropTargets();
+ },
+
+ getContentType: function() {
+ return this.options.dragType;
+ },
+
+ getDraggableOptions: function() {
+ return this.options;
+ },
+
+ initDrag: function(event) {
+ if (Event.isLeftClick(event)) {
+ var src = Event.element(event);
+ if(src.tagName && /^INPUT|SELECT|OPTION|BUTTON|TEXTAREA$/i.test(src.tagName))
+ return;
+
+ Event.stop(event);
+
+ this.startDrag(event);
+ //Event.observe(document, "mousemove", this.listenDragBound);
+ //Event.observe(document, "mouseup", this.stopListenDragBound);
+ }
+ },
+
+ showDropTargets: function(){
+ var idStr = this.id.id;
+ var ind = idStr.lastIndexOf('_');
+ var prefix = idStr.substring(0,ind).replace("hdrag", "hdrop");
+ var spans = document.getElementsByTagName("span");
+ for(i=0;i<spans.length;i++){
+ var s = spans[i];
+ if (s.id.indexOf(prefix) == 0){
+ //s.style.zIndex = '70';
+ s.style.visibility = "visible";
+ //change dropzone style
+ s.childNodes[0].style.visibility="hidden";//top element
+ s.childNodes[1].style.visibility="hidden";//bottom element
+ }
+ }//for
+ },
+
+ hideDropTargets: function(){
+ var idStr = this.id.id;
+ var ind = idStr.lastIndexOf('_');
+ var prefix = idStr.substring(0,ind).replace("hdrag", "hdrop");
+ var spans = document.getElementsByTagName("span");
+ for (i=0;i<spans.length;i++){
+ var s = spans[i];
+ if (s.id.indexOf(prefix) == 0){
+ //s.style.zIndex = '59';
+ s.style.visibility = "hidden";
+ //change dropzone style
+ s.childNodes[0].style.visibility="hidden";//top element
+ s.childNodes[1].style.visibility="hidden";//bottom element
+ }
+ }//for
+ }
+});
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/simple-dropzone.js
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/simple-dropzone.js
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/resources/org/richfaces/renderkit/html/scripts/simple-dropzone.js 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,99 @@
+DnD.G3SimpleDropZone = Class.create();
+Object.extend(DnD.G3SimpleDropZone.prototype, DnD.Dropzone.prototype);
+Object.extend(DnD.G3SimpleDropZone.prototype, {
+ initialize: function(id, options) {
+ this.id = id;
+ var element = $(id);
+
+ if (!element) {
+ alert("drop: Element with [" + id + "] ID was not found in the DOM
tree. Probably element has no client ID or client ID hasn't been written. DnD's
disabled. Check please!");
+ return ;
+ }
+
+ this.element = element;
+ if (options.acceptedTypes) {
+ this.acceptedTypes = options.acceptedTypes;
+ } else {
+ this.acceptedTypes = [];
+ }
+
+ if (options.typeMapping) {
+ this.typeMapping = options.typeMapping;
+ } else {
+ this.typeMapping = {};
+ }
+
+ if (options.cursorTypeMapping) {
+ this.cursorTypeMapping = options.cursorTypeMapping;
+ } else {
+ this.cursorTypeMapping = {};
+ }
+
+ this.mouseoverBound = this.mouseover.bindAsEventListener(this);
+ this.mouseoutBound = this.mouseout.bindAsEventListener(this);
+ this.mouseupBound = this.mouseup.bindAsEventListener(this);
+
+ Event.observe(element, "mouseover", this.mouseoverBound);
+ Event.observe(element, "mouseout", this.mouseoutBound);
+ Event.observe(element, "mouseup", this.mouseupBound);
+
+
+
+ this.options = options || {};
+ this.enableDropzoneCursors(options.acceptCursor,options.rejectCursor);
+
+ },
+
+ getDropzoneOptions: function() {
+ return this.options;
+ },
+
+ getDnDDropParams: function() {
+ if (this.options.dndParams) {
+ return this.options.dndParams.parseJSON(EventHandlersWalk);
+ }
+
+ return null;
+ },
+
+ mouseover: function(event) {
+ if (window.drag){
+ this.dragEnter(event);
+ //change dropzone style
+ this.element.childNodes[0].style.visibility="visible";//top element
+ this.element.childNodes[1].style.visibility="visible";//bottom element
+ }
+ },
+
+ mouseup: function(event) {
+ this.dragUp(event);
+ },
+
+ mouseout: function(event) {
+ if (window.drag){
+ this.dragLeave(event);
+ //change dropzone style
+ this.element.childNodes[0].style.visibility="hidden";//top element
+ this.element.childNodes[1].style.visibility="hidden";//bottom element
+ }
+ },
+ getAcceptedTypes: function() {
+ return this.acceptedTypes;
+ },
+ getTypeMapping: function() {
+ return this.typeMapping;
+ },
+
+ getCursorTypeMapping: function() {
+ return this.cursorTypeMapping;
+ },
+
+ drop: function(event, drag){
+ alert('I drop');
+ },
+ onafterdrag: function(drag) {
+ if (this.options.onafterdrag) {
+ this.options.onafterdrag.call(this, drag);
+ }
+ }
+});
\ No newline at end of file
Added: trunk/sandbox/ui/extendedDataTable/src/main/templates/README
===================================================================
Added:
trunk/sandbox/ui/extendedDataTable/src/main/templates/org/richfaces/htmlExtendedDataTable.jspx
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/main/templates/org/richfaces/htmlExtendedDataTable.jspx
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/main/templates/org/richfaces/htmlExtendedDataTable.jspx 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<f:root
+
xmlns:f="http://ajax4jsf.org/cdk/template"
+ xmlns:c="
http://java.sun.com/jsf/core"
+ xmlns:ui="
http://ajax4jsf.org/cdk/ui"
+ xmlns:u="
http://ajax4jsf.org/cdk/u"
+ xmlns:x="
http://ajax4jsf.org/cdk/x"
+
xmlns:h="http://jsf.exadel.com/header"
+
xmlns:vcp="http://ajax4jsf.org/cdk/vcp"
+
+ class="org.richfaces.renderkit.html.ExtendedDataTableRenderer"
+ baseclass="org.richfaces.renderkit.AbstractExtendedTableRenderer"
+ component="org.richfaces.component.UIExtendedDataTable"
+ >
+ <h:styles>
+ css/extendedDataTable.xcss,
+ /org/richfaces/renderkit/html/css/dragIndicator.xcss,
+ /org/richfaces/renderkit/html/css/menucomponents.xcss,
+ </h:styles>
+ <h:scripts>
+ new org.ajax4jsf.javascript.AjaxScript(),
+ new org.ajax4jsf.javascript.PrototypeScript(),
+ new org.ajax4jsf.javascript.DnDScript(),
+
+ /org/richfaces/renderkit/html/scripts/utils.js,
+ /org/richfaces/renderkit/html/scripts/json/json-dom.js,
+ /org/richfaces/renderkit/html/scripts/json/json-mini.js,
+ /org/richfaces/renderkit/html/scripts/dnd/dnd-common.js,
+ /org/richfaces/renderkit/html/scripts/dnd/dnd-draggable.js,
+ /org/richfaces/renderkit/html/scripts/dnd/dnd-dropzone.js,
+ /org/richfaces/renderkit/html/scripts/browser_info.js,
+
+ /org/richfaces/renderkit/html/scripts/menu.js,
+ /org/richfaces/renderkit/html/scripts/context-menu.js,
+ /org/ajax4jsf/javascript/scripts/form.js,
+ /org/richfaces/renderkit/html/scripts/form.js,
+
+ /org/richfaces/renderkit/html/scripts/jquery/jquery.js,
+ /org/richfaces/renderkit/html/script/controlUtils.js,
+
+ /org/richfaces/renderkit/html/scripts/extended-data-table.js,
+ /org/richfaces/renderkit/html/scripts/dt-drag-indicator.js,
+
+ /org/richfaces/renderkit/html/scripts/simple-draggable.js,
+ /org/richfaces/renderkit/html/scripts/simple-dropzone.js
+ </h:scripts>
+ <f:clientid var="clientId"/>
+
+ <jsp:scriptlet>
+ <![CDATA[
+ variables.setVariable("columnsCount", getColumnsCount(component)+1);
+ ]]>
+ </jsp:scriptlet>
+
+ <div id="#{clientId}:dataTable_indicator" class="drgind_fly
drgind_default drag_indicator" style="display: none;" >
+ <f:call name="encodeNamespace" />
+
+ <script type="text/javascript">
+ var elt = $("#{clientId}:dataTable_indicator");
+ elt.markers = {};
+ elt.indicatorTemplates = {};
+ <f:call name="encodeDragDropChildScripts" />
+ createDragIndicator(elt, '', '');
+ </script>
+ </div>
+ <span id="#{clientId}:dataTable_indicator_span" />
+
+ <div
+ id="#{clientId}"
+ class="extdt-maindiv extdt-splscr-vsbl"
+ style="width:#{component.attributes['width']};
height:#{component.attributes['height']}"
+ >
+
+ <div id="#{clientId}:od" class="extdt-outerdiv"
+ style="width:100%; height:100%;"
+ >
+ <div id="#{clientId}:innerd" class="extdt-innerdiv"
style="height:100%;width:100%;">
+ <div id="#{clientId}:cs" class="dr-sdt-hsplit"
style="display: none;"/>
+ <table id="#{clientId}:tu"
+ class="extdt-dr-table rich-table
#{component.attributes['styleClass']}"
+ style="visibility:hidden;"
+ width="100%"
+ >
+ <f:call name="encodeTableStructure"/>
+ <f:call name="encodeHeader"/>
+ <tbody>
+ <tr>
+ <td colspan="#{columnsCount}" style="padding: 0px;">
+ <div id="#{clientId}:sd" class="extdt-content"
style="height:50px;">
+ <table id="#{clientId}:n" width="100%"
+ class="extdt-dr-table rich-table
#{component.attributes['styleClass']}"
style="#{component.attributes['style']}"
+ >
+ <f:call name="utils.encodePassThruWithExclusions">
+ <f:parameter
value="height,value,name,type,id,class,rows,style,width" />
+ </f:call>
+ <f:call name="encodeTableStructure"/>
+ <tbody id="#{clientId}:tb">
+ <vcp:body>
+ <f:call name="encodeRows"/>
+ </vcp:body>
+ </tbody>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ <f:call name="encodeFooter"/>
+ </table>
+ <f:call name="contributorsEncodeHere" />
+ </div>
+ <script type="text/javascript">
+ //<![CDATA[
+ #{this:getJavaScriptVarName(context, component)} =
#{this:createClientDataTable(context, component)};
+ #{this:getScriptContributions(context, component)};
+ //]]>
+ </script>
+ </div>
+ <f:call name="encodeTableMenu"/>
+ </div>
+</f:root>
\ No newline at end of file
Added:
trunk/sandbox/ui/extendedDataTable/src/test/java/org/richfaces/component/JSFComponentTest.java
===================================================================
---
trunk/sandbox/ui/extendedDataTable/src/test/java/org/richfaces/component/JSFComponentTest.java
(rev 0)
+++
trunk/sandbox/ui/extendedDataTable/src/test/java/org/richfaces/component/JSFComponentTest.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -0,0 +1,53 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.component;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import javax.faces.component.UIComponent;
+
+/**
+ * Unit test for simple Component.
+ */
+public class JSFComponentTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public JSFComponentTest( String testName )
+ {
+ super( testName );
+ }
+
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testComponent()
+ {
+ assertTrue( true );
+ }
+}
Modified: trunk/sandbox/ui/pom.xml
===================================================================
--- trunk/sandbox/ui/pom.xml 2008-06-19 17:13:04 UTC (rev 9120)
+++ trunk/sandbox/ui/pom.xml 2008-06-19 19:21:31 UTC (rev 9121)
@@ -20,5 +20,6 @@
<!--module>rex-button</module-->
<module>sortableHeader</module>
<module>hotKey</module>
+ <module>extendedDataTable</module>
</modules>
</project>
\ No newline at end of file
Modified: trunk/ui/dataTable/src/main/config/component/columnAttributes.ent
===================================================================
--- trunk/ui/dataTable/src/main/config/component/columnAttributes.ent 2008-06-19 17:13:04
UTC (rev 9120)
+++ trunk/ui/dataTable/src/main/config/component/columnAttributes.ent 2008-06-19 19:21:31
UTC (rev 9121)
@@ -119,4 +119,16 @@
<name>sortIconDescending</name>
<classname>java.lang.String</classname>
<description>Defines sort icon in descending order</description>
+</property>
+<property>
+ <name>label</name>
+ <classname>java.lang.String</classname>
+ <description>Column label for drag indicator. Usable only for extendedDataTable
component</description>
+ <defaultvalue>""</defaultvalue>
+</property>
+<property>
+ <name>visible</name>
+ <classname>boolean</classname>
+ <description>TODO: </description>
+ <defaultvalue>true</defaultvalue>
</property>
\ No newline at end of file
Modified: trunk/ui/dataTable/src/main/java/org/richfaces/component/UIColumn.java
===================================================================
--- trunk/ui/dataTable/src/main/java/org/richfaces/component/UIColumn.java 2008-06-19
17:13:04 UTC (rev 9120)
+++ trunk/ui/dataTable/src/main/java/org/richfaces/component/UIColumn.java 2008-06-19
19:21:31 UTC (rev 9121)
@@ -27,6 +27,7 @@
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
+import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import org.ajax4jsf.component.AjaxSupport;
@@ -59,6 +60,46 @@
public abstract String getSortIconDescending();
public abstract void setSortIconDescending(String sortIcon);
+ public abstract boolean isVisible();
+ public abstract void setVisible(boolean visible);
+
+ //This code block adds support for visible attribute of the column component
+ @Override
+ public boolean isRendered() {
+ return super.isRendered() && isVisible();
+ }
+
+ @Override
+ public void setRendered(boolean rendered) {
+ super.setRendered(rendered);
+ }
+ //
+
+ //Extended data table supports label attribute also
+ /**
+ * Get label for column. If label attribute is set returns attribute value,
+ * otherwise try to get label from column header content.
+ * @return label for column
+ */
+ //TODO what about extra "label" facet?
+ public String getColumnLabel(){
+ String label = (String)getAttributes().get("label");
+ if ((label == null) || (label.length() == 0)){
+ //try get header name
+ UIComponent hFacet = getHeader();
+ if ((hFacet != null) && (hFacet.isRendered())
+ /* added check for rendered attribute */ && (hFacet instanceof UIOutput)) {
+ UIOutput output = (UIOutput)hFacet;
+
+ //TODO add conversion support here
+ label = (String)output.getValue();
+ }
+ }
+ return label;
+ }//getColumnLabel
+
+ //
+
public FilterField getFilterField(){
FilterField filterField = null;
MethodExpression filterMethod = getFilterMethod();