Hi,
since there is no reply to that message and a couple of changes where made to the sources I will post an updated patch file which should work with the current cvs state.
Please let me now if someone finds some time to integrate the component into the source tree or there is any reason not to do it.
Mathias
Mathias Broekelmann wrote:
Hi,
the attachment contains the patches and new files (based on the current cvs) for a new component to make cross tables work.
An example is also included ;)
Mathias
Index: conf/faces-config.xml
===================================================================
RCS file: /home/cvspublic/incubator-myfaces/conf/faces-config.xml,v
retrieving revision 1.115
diff -u -r1.115 faces-config.xml
--- conf/faces-config.xml 26 Mar 2005 20:31:36 -0000 1.115
+++ conf/faces-config.xml 28 Mar 2005 20:13:02 -0000
@@ -281,6 +281,10 @@
<component-class>org.apache.myfaces.custom.swapimage.HtmlSwapImage</component-class>
</component>
+ <component>
+ <component-type>org.apache.myfaces.Columns</component-type>
+
<component-class>org.apache.myfaces.component.UIColumns</component-class>
+ </component>
<!-- additional "by type" converters -->
Index: src/components/org/apache/myfaces/component/html/ext/HtmlDataTable.java
===================================================================
RCS file:
/home/cvspublic/incubator-myfaces/src/components/org/apache/myfaces/component/html/ext/HtmlDataTable.java,v
retrieving revision 1.19
diff -u -r1.19 HtmlDataTable.java
--- src/components/org/apache/myfaces/component/html/ext/HtmlDataTable.java
21 Mar 2005 12:33:46 -0000 1.19
+++ src/components/org/apache/myfaces/component/html/ext/HtmlDataTable.java
28 Mar 2005 20:13:04 -0000
@@ -17,6 +17,7 @@
import org.apache.myfaces.component.UserRoleAware;
import org.apache.myfaces.component.UserRoleUtils;
+import org.apache.myfaces.component.UIColumns;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -28,6 +29,7 @@
import javax.faces.event.FacesEvent;
import javax.faces.model.DataModel;
import javax.faces.render.Renderer;
+
import java.io.IOException;
import java.sql.ResultSet;
import java.util.Iterator;
@@ -94,6 +96,10 @@
{
private static final Log log = LogFactory.getLog(HtmlDataTable.class);
+ private static final int PROCESS_DECODES = 1;
+ private static final int PROCESS_VALIDATORS = 2;
+ private static final int PROCESS_UPDATES = 3;
+
private static final boolean DEFAULT_SORTASCENDING = true;
private static final Class OBJECT_ARRAY_CLASS = (new Object[0]).getClass();
@@ -186,12 +192,122 @@
public void processDecodes(FacesContext context)
{
+ if(!isRendered())
+ {
+ return;
+ }
super.processDecodes(context);
+ setRowIndex(-1);
+ processColumnsFacets(context, PROCESS_DECODES);
+ processColumnsChildren(context, PROCESS_DECODES);
+ setRowIndex(-1);
+ }
+
+ /**
+ * @param context
+ * @param processAction
+ */
+ private void processColumnsChildren(FacesContext context, int
processAction)
+ {
+ int first = getFirst();
+ int rows = getRows();
+ int last;
+ if (rows == 0)
+ {
+ last = getRowCount();
+ }
+ else
+ {
+ last = first + rows;
+ }
+ for (int rowIndex = first; rowIndex < last; rowIndex++)
+ {
+ setRowIndex(rowIndex);
+ if (isRowAvailable())
+ {
+ for (Iterator it = getChildren().iterator(); it.hasNext();)
+ {
+ UIComponent child = (UIComponent) it.next();
+ if (child instanceof UIColumns)
+ {
+ if (child.isRendered())
+ {
+ UIColumns columns = (UIColumns) child;
+ for (int colIndex = 0, size = columns.getRowCount(); colIndex
< size; colIndex++)
+ {
+ columns.setRowIndex(colIndex);
+ for (Iterator columnChildIter =
child.getChildren().iterator(); columnChildIter
+ .hasNext();)
+ {
+ UIComponent columnChild = (UIComponent)
columnChildIter.next();
+ process(context, columnChild, processAction);
+ }
+ }
+ columns.setRowIndex(-1);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * @param context
+ * @param processAction
+ */
+ private void processColumnsFacets(FacesContext context, int processAction)
+ {
+ for (Iterator childIter = getChildren().iterator(); childIter.hasNext();)
+ {
+ UIComponent child = (UIComponent) childIter.next();
+ if (child instanceof UIColumns)
+ {
+ if(child.isRendered())
+ {
+ UIColumns columns = (UIColumns) child;
+ for (int i = 0, size = columns.getRowCount(); i < size; i++)
+ {
+ columns.setRowIndex(i);
+ for (Iterator facetsIter =
child.getFacets().values().iterator(); facetsIter.hasNext();)
+ {
+ UIComponent facet = (UIComponent) facetsIter.next();
+ process(context, facet, processAction);
+ }
+ }
+ columns.setRowIndex(-1);
+ }
+ }
+ }
+ }
+
+ private void process(FacesContext context, UIComponent component, int
processAction)
+ {
+ switch (processAction)
+ {
+ case PROCESS_DECODES :
+ component.processDecodes(context);
+ break;
+ case PROCESS_VALIDATORS :
+ component.processValidators(context);
+ break;
+ case PROCESS_UPDATES :
+ component.processUpdates(context);
+ break;
+ }
}
public void processValidators(FacesContext context)
{
- super.processValidators(context);
+ if(!isRendered())
+ {
+ return;
+ }
+ super.processValidators(context);
+ setRowIndex(-1);
+ processColumnsFacets(context, PROCESS_VALIDATORS);
+ processColumnsChildren(context, PROCESS_VALIDATORS);
+ setRowIndex(-1);
}
public Object processSaveState(FacesContext context)
@@ -206,7 +322,15 @@
public void processUpdates(FacesContext context)
{
+ if(!isRendered())
+ {
+ return;
+ }
super.processUpdates(context);
+ setRowIndex(-1);
+ processColumnsFacets(context, PROCESS_UPDATES);
+ processColumnsChildren(context, PROCESS_UPDATES);
+ setRowIndex(-1);
if (_isDataModelRestored)
{
Index: src/share/org/apache/myfaces/renderkit/html/HtmlTableRendererBase.java
===================================================================
RCS file:
/home/cvspublic/incubator-myfaces/src/share/org/apache/myfaces/renderkit/html/HtmlTableRendererBase.java,v
retrieving revision 1.8
diff -u -r1.8 HtmlTableRendererBase.java
--- src/share/org/apache/myfaces/renderkit/html/HtmlTableRendererBase.java
11 Feb 2005 16:03:00 -0000 1.8
+++ src/share/org/apache/myfaces/renderkit/html/HtmlTableRendererBase.java
28 Mar 2005 20:13:09 -0000
@@ -19,6 +19,7 @@
import org.apache.myfaces.renderkit.RendererUtils;
import org.apache.myfaces.util.ArrayUtils;
import org.apache.myfaces.util.StringUtils;
+import org.apache.myfaces.component.UIColumns;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -148,10 +149,24 @@
for (int j = 0, size = component.getChildCount(); j < size; j++)
{
UIComponent child = (UIComponent) children.get(j);
- if (child instanceof UIColumn && ((UIColumn)
child).isRendered())
+ if(child.isRendered())
{
- String columnStyle = styles.getColumnStyle(j);
- renderColumnBody(facesContext, writer, uiData, (UIColumn)
child, columnStyle);
+ if (child instanceof UIColumn)
+ {
+ String columnStyle = styles.getColumnStyle(j);
+ renderColumnBody(facesContext, writer, uiData,
child, columnStyle);
+ }
+ else if (child instanceof UIColumns)
+ {
+ UIColumns columns = (UIColumns) child;
+ for (int k = 0, colSize = columns.getRowCount(); k <
colSize; k++)
+ {
+ columns.setRowIndex(k);
+ String columnStyle = styles.getColumnStyle(j);
+ renderColumnBody(facesContext, writer, uiData,
child, columnStyle);
+ }
+ columns.setRowIndex(-1);
+ }
}
}
renderRowEnd(facesContext, writer, uiData);
@@ -166,7 +181,7 @@
* @param facesContext the <code>FacesContext</code>.
* @param writer the <code>ResponseWriter</code>.
* @param uiData the <code>UIData</code> being rendered.
- * @param column the <code>UIColumn</code> to render.
+ * @param component the <code>UIComponent</code> to render.
* @param columnStyleClass the styleClass of the <code>UIColumn</code> or
<code>null</code> if
* there is none.
* @throws IOException if an exception occurs.
@@ -175,7 +190,7 @@
FacesContext facesContext,
ResponseWriter writer,
UIData uiData,
- UIColumn column,
+ UIComponent component,
String columnStyleClass) throws IOException
{
writer.startElement(HTML.TD_ELEM, uiData);
@@ -184,7 +199,7 @@
writer.writeAttribute(HTML.CLASS_ATTR,
columnStyleClass, null);
}
- RendererUtils.renderChild(facesContext, column);
+ RendererUtils.renderChild(facesContext, component);
writer.endElement(HTML.TD_ELEM);
}
@@ -291,14 +306,26 @@
for (Iterator it = component.getChildren().iterator(); it.hasNext();)
{
UIComponent uiComponent = (UIComponent) it.next();
- if (uiComponent instanceof UIColumn && ((UIColumn)
uiComponent).isRendered())
+ if(uiComponent.isRendered())
{
- colspan++;
- if (!hasColumnFacet)
- {
- hasColumnFacet = header ? ((UIColumn)
uiComponent).getHeader() != null : ((UIColumn) uiComponent)
- .getFooter() != null;
- }
+ if (uiComponent instanceof UIColumn)
+ {
+ colspan++;
+ if (!hasColumnFacet)
+ {
+ hasColumnFacet = header ? ((UIColumn)
uiComponent).getHeader() != null : ((UIColumn) uiComponent)
+ .getFooter() != null;
+ }
+ }
+ else if (uiComponent instanceof UIColumns)
+ {
+ UIColumns columns = (UIColumns) uiComponent;
+ colspan += columns.getRowCount();
+ if (!hasColumnFacet)
+ {
+ hasColumnFacet = header ? columns.getHeader() != null :
columns.getFooter() != null;
+ }
+ }
}
}
@@ -420,8 +447,8 @@
writer.endElement(HTML.TR_ELEM);
}
- private void renderColumnHeaderOrFooterRow(FacesContext facesContext,
ResponseWriter writer, UIComponent component,
- String styleClass, boolean header) throws IOException
+ private void renderColumnHeaderOrFooterRow(FacesContext facesContext,
ResponseWriter writer,
+ UIComponent component, String styleClass, boolean header) throws
IOException
{
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
@@ -429,35 +456,76 @@
for (Iterator it = component.getChildren().iterator(); it.hasNext();)
{
UIComponent uiComponent = (UIComponent) it.next();
- if (uiComponent instanceof UIColumn && ((UIColumn)
uiComponent).isRendered())
+ if(uiComponent.isRendered())
{
- if (header)
- {
- renderColumnHeaderCell(facesContext, writer, (UIColumn)
uiComponent, styleClass, 0);
- }
- else
- {
- renderColumnFooterCell(facesContext, writer, (UIColumn)
uiComponent, styleClass, 0);
- }
+ if (uiComponent instanceof UIColumn)
+ {
+ if (header)
+ {
+ renderColumnHeaderCell(facesContext, writer,
uiComponent,
+ ((UIColumn) uiComponent).getHeader(), styleClass, 0);
+ }
+ else
+ {
+ renderColumnFooterCell(facesContext, writer,
uiComponent,
+ ((UIColumn) uiComponent).getFooter(), styleClass, 0);
+ }
+ }
+ else if (uiComponent instanceof UIColumns)
+ {
+ UIColumns columns = (UIColumns) uiComponent;
+ for (int i = 0, size = columns.getRowCount(); i < size; i++)
+ {
+ columns.setRowIndex(i);
+ if (header)
+ {
+ renderColumnHeaderCell(facesContext, writer,
columns, columns.getHeader(),
+ styleClass, 0);
+ }
+ else
+ {
+ renderColumnFooterCell(facesContext, writer,
columns, columns.getFooter(),
+ styleClass, 0);
+ }
+ }
+ columns.setRowIndex(-1);
+ }
}
}
writer.endElement(HTML.TR_ELEM);
}
- /**
+ /**
+ * Renders the header facet for the given <code>UIColumn</code>.
+ * @param facesContext the <code>FacesContext</code>.
+ * @param writer the <code>ResponseWriter</code>.
+ * @param uiColumn the <code>UIColumn</code>.
+ * @param headerStyleClass the styleClass of the header facet.
+ * @param colspan the colspan for the tableData element in which the
header facet
+ * will be wrapped.
+ * @throws IOException
+ */
+ protected void renderColumnHeaderCell(FacesContext facesContext,
ResponseWriter writer, UIColumn uiColumn,
+ String headerStyleClass, int colspan) throws IOException
+ {
+ renderColumnHeaderCell(facesContext, writer, uiColumn,
uiColumn.getHeader(), headerStyleClass, colspan);
+ }
+
+ /**
* Renders the header facet for the given <code>UIColumn</code>.
* @param facesContext the <code>FacesContext</code>.
* @param writer the <code>ResponseWriter</code>.
- * @param uiColumn the <code>UIColumn</code>.
+ * @param uiComponent the <code>UIComponent</code> to render the facet
for.
+ * @param facet the <code>UIComponent</code> to render as facet.
* @param headerStyleClass the styleClass of the header facet.
* @param colspan the colspan for the tableData element in which the
header facet
* will be wrapped.
* @throws IOException
*/
- protected void renderColumnHeaderCell(FacesContext facesContext,
ResponseWriter writer, UIColumn uiColumn,
- String headerStyleClass, int colspan) throws IOException
+ protected void renderColumnHeaderCell(FacesContext facesContext,
ResponseWriter writer, UIComponent uiComponent,
+ UIComponent facet, String headerStyleClass, int colspan) throws
IOException
{
- writer.startElement(HTML.TH_ELEM, uiColumn);
+ writer.startElement(HTML.TH_ELEM, uiComponent);
if (colspan > 1)
{
writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(colspan),
null);
@@ -466,7 +534,6 @@
{
writer.writeAttribute(HTML.CLASS_ATTR, headerStyleClass, null);
}
- UIComponent facet = uiColumn.getHeader();
if (facet != null)
{
RendererUtils.renderChild(facesContext, facet);
@@ -474,20 +541,37 @@
writer.endElement(HTML.TH_ELEM);
}
+ /**
+ * Renders the footer facet for the given <code>UIColumn</code>.
+ * @param facesContext the <code>FacesContext</code>.
+ * @param writer the <code>ResponseWriter</code>.
+ * @param uiColumn the <code>UIComponent</code>.
+ * @param footerStyleClass the styleClass of the footer facet.
+ * @param colspan the colspan for the tableData element in which the
footer facet
+ * will be wrapped.
+ * @throws IOException
+ */
+ protected void renderColumnFooterCell(FacesContext facesContext,
ResponseWriter writer, UIColumn uiColumn,
+ String footerStyleClass, int colspan) throws IOException
+ {
+ renderColumnFooterCell(facesContext, writer, uiColumn,
uiColumn.getFooter(), footerStyleClass, colspan);
+ }
+
/**
* Renders the footer facet for the given <code>UIColumn</code>.
* @param facesContext the <code>FacesContext</code>.
* @param writer the <code>ResponseWriter</code>.
- * @param uiColumn the <code>UIColumn</code>.
+ * @param uiComponent the <code>UIComponent</code> to render the facet
for.
+ * @param facet the <code>UIComponent</code> to render as facet.
* @param footerStyleClass the styleClass of the footer facet.
* @param colspan the colspan for the tableData element in which the
footer facet
* will be wrapped.
* @throws IOException
*/
- protected void renderColumnFooterCell(FacesContext facesContext,
ResponseWriter writer, UIColumn uiColumn,
- String footerStyleClass, int colspan) throws IOException
+ protected void renderColumnFooterCell(FacesContext facesContext,
ResponseWriter writer, UIComponent uiComponent,
+ UIComponent facet, String footerStyleClass, int colspan) throws
IOException
{
- writer.startElement(HTML.TD_ELEM, uiColumn);
+ writer.startElement(HTML.TD_ELEM, uiComponent);
if (colspan > 1)
{
writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(colspan),
null);
@@ -496,7 +580,6 @@
{
writer.writeAttribute(HTML.CLASS_ATTR, footerStyleClass, null);
}
- UIComponent facet = uiColumn.getFooter();
if (facet != null)
{
RendererUtils.renderChild(facesContext, facet);
Index: tlds/myfaces_ext.tld
===================================================================
RCS file: /home/cvspublic/incubator-myfaces/tlds/myfaces_ext.tld,v
retrieving revision 1.185
diff -u -r1.185 myfaces_ext.tld
--- tlds/myfaces_ext.tld 26 Mar 2005 20:31:37 -0000 1.185
+++ tlds/myfaces_ext.tld 28 Mar 2005 20:13:10 -0000
@@ -2152,4 +2152,24 @@
<attribute><name>onkeyup</name> <required>false</required>
<rtexprvalue>false</rtexprvalue></attribute>
</tag>
+ <!-- columns -->
+ <tag>
+ <name>columns</name>
+
<tag-class>org.apache.myfaces.custom.crosstable.HtmlColumnsTag</tag-class>
+ <body-content>JSP</body-content>
+ &ui_component_attributes;
+ &ui_column_attributes;
+ <attribute>
+ <name>value</name>
+ <required>true</required>
+ <rtexprvalue>false</rtexprvalue>
+ <description>Supported types see JSF Spec 4.1.3</description>
+ </attribute>
+ <attribute>
+ <name>var</name>
+ <required>true</required>
+ <rtexprvalue>false</rtexprvalue>
+ </attribute>
+ </tag>
+
</taglib>
Index: webapps/examples/WEB-INF/examples-config.xml
===================================================================
RCS file:
/home/cvspublic/incubator-myfaces/webapps/examples/WEB-INF/examples-config.xml,v
retrieving revision 1.2
diff -u -r1.2 examples-config.xml
--- webapps/examples/WEB-INF/examples-config.xml 26 Mar 2005 20:31:37
-0000 1.2
+++ webapps/examples/WEB-INF/examples-config.xml 28 Mar 2005 20:13:10
-0000
@@ -241,7 +241,15 @@
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
-
+
+
+ <!-- Managed Beans for crosstable example -->
+
+ <managed-bean>
+ <managed-bean-name>crossDataTable</managed-bean-name>
+
<managed-bean-class>org.apache.myfaces.examples.crosstable.DataBean</managed-bean-class>
+ <managed-bean-scope>session</managed-bean-scope>
+ </managed-bean>
<navigation-rule>
@@ -413,6 +421,11 @@
<to-view-id>/selectOneCountry.jsp</to-view-id>
</navigation-case>
+ <navigation-case>
+ <from-outcome>go_crossDataTable</from-outcome>
+ <to-view-id>/crossDataTable.jsp</to-view-id>
+ </navigation-case>
+
</navigation-rule>
<navigation-rule>
Index: webapps/examples/inc/navigation.jsp
===================================================================
RCS file:
/home/cvspublic/incubator-myfaces/webapps/examples/inc/navigation.jsp,v
retrieving revision 1.2
diff -u -r1.2 navigation.jsp
--- webapps/examples/inc/navigation.jsp 26 Mar 2005 20:31:37 -0000 1.2
+++ webapps/examples/inc/navigation.jsp 28 Mar 2005 20:13:10 -0000
@@ -39,6 +39,7 @@
<x:commandNavigation id="nav_2_4_17"
value="#{example_messages['nav_swapimage']}" action="go_swapimage" />
<x:commandNavigation id="nav_2_4_18"
value="#{example_messages['nav_forceId']}" action="go_forceId" />
<x:commandNavigation id="nav_2_4_19"
value="#{example_messages['nav_selectOneCountry']}"
action="go_selectOneCountry" />
+ <x:commandNavigation id="nav_2_4_20"
value="#{example_messages['nav_crossDataTable']}" action="go_crossDataTable" />
</x:commandNavigation>
</x:commandNavigation>
<x:commandNavigation id="nav_3"
value="#{example_messages['nav_Documentation']}" >
Index:
webapps/src/example/org/apache/myfaces/examples/resource/example_messages.properties
===================================================================
RCS file:
/home/cvspublic/incubator-myfaces/webapps/src/example/org/apache/myfaces/examples/resource/example_messages.properties,v
retrieving revision 1.2
diff -u -r1.2 example_messages.properties
---
webapps/src/example/org/apache/myfaces/examples/resource/example_messages.properties
26 Mar 2005 20:31:36 -0000 1.2
+++
webapps/src/example/org/apache/myfaces/examples/resource/example_messages.properties
28 Mar 2005 20:13:11 -0000
@@ -39,6 +39,8 @@
nav_selectOneCountry= Select a country box
nav_swapimage = SwapImage
+nav_crossDataTable = Crosstable
+
# buttons
button_save = Save
@@ -162,4 +164,9 @@
css_msg=A simple test for the
forceOne=Value 1
-forceTwo=Value 2 (with forceId)
\ No newline at end of file
+forceTwo=Value 2 (with forceId)
+
+crosstable_field_column=column label
+crosstable_add_column=add a column
+crosstable_remove_column=remove the column
+crosstable_save_values=save values
\ No newline at end of file
Index:
webapps/src/example/org/apache/myfaces/examples/resource/example_messages_de.properties
===================================================================
RCS file:
/home/cvspublic/incubator-myfaces/webapps/src/example/org/apache/myfaces/examples/resource/example_messages_de.properties,v
retrieving revision 1.1
diff -u -r1.1 example_messages_de.properties
---
webapps/src/example/org/apache/myfaces/examples/resource/example_messages_de.properties
24 Mar 2005 16:47:11 -0000 1.1
+++
webapps/src/example/org/apache/myfaces/examples/resource/example_messages_de.properties
28 Mar 2005 20:13:11 -0000
@@ -32,6 +32,7 @@
nav_newspaperTable = Newspaper Table
nav_forceId = ForceId
nav_swapimage = SwapImage
+nav_crossDataTable = Kreuztabelle
# buttons
@@ -105,3 +106,9 @@
forceOne=Eingabe 1
forceTwo=Eingabe 2 (mit forceId)
+
+
+crosstable_field_column=Spaltenname
+crosstable_add_column=Spalte hinzuf�gen
+crosstable_remove_column=Spalte l�schen
+crosstable_save_values=Werte speichern
\ No newline at end of file
Index: src/components/org/apache/myfaces/custom/crosstable/HtmlColumnsTag.java
===================================================================
RCS file:
src/components/org/apache/myfaces/custom/crosstable/HtmlColumnsTag.java
diff -N src/components/org/apache/myfaces/custom/crosstable/HtmlColumnsTag.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/components/org/apache/myfaces/custom/crosstable/HtmlColumnsTag.java
1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.myfaces.custom.crosstable;
+
+import javax.faces.component.UIComponent;
+
+import org.apache.myfaces.component.UIColumns;
+import org.apache.myfaces.renderkit.JSFAttr;
+import org.apache.myfaces.taglib.html.HtmlComponentBodyTagBase;
+
+/**
+ * @author Mathias Broekelmann (latest modification by $Author: Mathias
Broekelmann $)
+ * @version $Revision$ $Date$
+ * $Log$
+ */
+public class HtmlColumnsTag extends HtmlComponentBodyTagBase
+{
+ private String mVar;
+
+ /**
+ * @see javax.faces.webapp.UIComponentTag#getComponentType()
+ */
+ public String getComponentType()
+ {
+ return UIColumns.COMPONENT_TYPE;
+ }
+
+ /**
+ * @see javax.faces.webapp.UIComponentTag#getRendererType()
+ */
+ public String getRendererType()
+ {
+ return null;
+ }
+
+ public void setVar(String var)
+ {
+ mVar = var;
+ }
+
+ protected void setProperties(UIComponent component)
+ {
+ super.setProperties(component);
+
+ setStringProperty(component, JSFAttr.VAR_ATTR, mVar);
+ }
+}
Index: src/share/org/apache/myfaces/component/UIColumns.java
===================================================================
RCS file: src/share/org/apache/myfaces/component/UIColumns.java
diff -N src/share/org/apache/myfaces/component/UIColumns.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/share/org/apache/myfaces/component/UIColumns.java 1 Jan 1970
00:00:00 -0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.myfaces.component;
+
+import javax.faces.component.UIData;
+
+/**
+ * @author Mathias Broekelmann (latest modification by $Author: Mathias
Broekelmann $)
+ * @version $Revision$ $Date$
+ * $Log$
+ */
+public class UIColumns extends UIData
+{
+ public static final String COMPONENT_TYPE = "org.apache.myfaces.Columns";
+ public static final String COMPONENT_FAMILY = UIData.COMPONENT_FAMILY;
+
+ /**
+ *
+ */
+ public UIColumns()
+ {
+ super();
+ }
+
+ /**
+ * @see javax.faces.component.UIComponentBase#getRendererType()
+ */
+ public String getRendererType()
+ {
+ return null;
+ }
+
+ /**
+ * @see javax.faces.component.UIComponent#getFamily()
+ */
+ public String getFamily()
+ {
+ return COMPONENT_FAMILY;
+ }
+}
Index: webapps/examples/crossDataTable.jsp
===================================================================
RCS file: webapps/examples/crossDataTable.jsp
diff -N webapps/examples/crossDataTable.jsp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ webapps/examples/crossDataTable.jsp 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,130 @@
+<%@ page session="false" contentType="text/html;charset=utf-8"%>
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
+<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="x"%>
+<html>
+
+<!--
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//-->
+
+<[EMAIL PROTECTED] file="inc/head.inc"%>
+
+<body>
+
+<!--
+managed beans used:
+ countryList
+-->
+
+<f:view>
+
+ <f:loadBundle
+ basename="org.apache.myfaces.examples.resource.example_messages"
+ var="example_messages" />
+
+ <x:panelLayout id="page" layout="#{globalOptions.pageLayout}"
+ styleClass="pageLayout" headerClass="pageHeader"
+ navigationClass="pageNavigation" bodyClass="pageBody"
+ footerClass="pageFooter">
+
+ <f:facet name="header">
+ <f:subview id="header">
+ <jsp:include page="inc/page_header.jsp" />
+ </f:subview>
+ </f:facet>
+
+ <f:facet name="navigation">
+ <f:subview id="menu">
+ <jsp:include page="inc/navigation.jsp" />
+ </f:subview>
+ </f:facet>
+
+ <f:facet name="body">
+ <h:form>
+ <h:panelGroup id="body">
+
+ <h:panelGrid columns="1">
+ <h:commandLink
rendered="#{!crossDataTable.editValues}" action="#{crossDataTable.editValues}"
+ immediate="true">
+ <h:outputText
value="#{example_messages['country_edit_table']}"
+ styleClass="standard" />
+ </h:commandLink>
+ <h:panelGrid
rendered="#{!crossDataTable.editValues}" columns="3">
+ <h:outputLabel
for="columnLabel" value="#{example_messages['crosstable_field_column']}"/>
+ <h:inputText id="columnLabel"
value="#{crossDataTable.columnLabel}" />
+ <h:commandLink
action="#{crossDataTable.addColumn}">
+ <h:outputText
value="#{example_messages['crosstable_add_column']}"
+
styleClass="standard" />
+ </h:commandLink>
+ </h:panelGrid>
+ <h:commandLink
rendered="#{crossDataTable.editValues}" action="#{crossDataTable.saveValues}">
+ <h:outputText
value="#{example_messages['crosstable_save_values']}"
+ styleClass="standard" />
+ </h:commandLink>
+ </h:panelGrid>
+ <f:verbatim>
+ <br>
+ </f:verbatim>
+
+ <x:dataTable id="data"
styleClass="standardTable"
+ headerClass="standardTable_Header"
+ footerClass="standardTable_Header"
+
rowClasses="standardTable_Row1,standardTable_Row2"
+ columnClasses="standardTable_Column"
var="country"
+
value="#{crossDataTable.countryDataModel}" preserveDataModel="false">
+ <h:column>
+ <f:facet name="header">
+ <h:outputText
value="#{example_messages['label_country_name']}" />
+ </f:facet>
+ <h:outputText
value="#{country.name}" />
+ </h:column>
+
+ <x:columns
value="#{crossDataTable.columnDataModel}" var="column">
+ <f:facet name="header">
+ <h:panelGroup>
+ <h:outputText
value="#{column} " />
+ <h:commandLink
action="#{crossDataTable.removeColumn}">
+
<h:outputText value="-" title="#{example_messages['crosstable_remove_column']}"
/>
+ </h:commandLink>
+ </h:panelGroup>
+ </f:facet>
+ <h:outputText
rendered="#{!crossDataTable.editValues}"
+
value="#{crossDataTable.columnValue}" />
+ <h:inputText
rendered="#{crossDataTable.editValues}"
+
value="#{crossDataTable.columnValue}" />
+ </x:columns>
+
+ </x:dataTable>
+
+ <f:verbatim>
+ <br>+ </f:verbatim> + + </h:panelGroup> + </h:form> + </f:facet> + + <[EMAIL PROTECTED] file="inc/page_footer.jsp"%> + + </x:panelLayout> + +</f:view> + +</body> + +</html> Index: webapps/src/example/org/apache/myfaces/examples/crosstable/DataBean.java =================================================================== RCS file: webapps/src/example/org/apache/myfaces/examples/crosstable/DataBean.java diff -N webapps/src/example/org/apache/myfaces/examples/crosstable/DataBean.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ webapps/src/example/org/apache/myfaces/examples/crosstable/DataBean.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,212 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.myfaces.examples.crosstable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.faces.model.DataModel; +import javax.faces.model.ListDataModel; + +import org.apache.myfaces.examples.listexample.SimpleCountry; +import org.apache.myfaces.examples.listexample.SimpleCountryList; + +/** + * @author Mathias Broekelmann (latest modification by $Author$) + * @version $Revision$ $Date$ + */ +public class DataBean extends SimpleCountryList +{ + private DataModel mColumns; + private DataModel mCountryDataModel; + private Map mValueMap = new HashMap(); + private boolean mEditValues; + private String mColumnLabel; + + /** + * + */ + public DataBean() + { + super(); + } + + public boolean isEditValues() + { + return mEditValues; + } + + public String editValues() + { + mEditValues = true; + return null; + } + + public String saveValues() + { + mEditValues = false; + return null; + } + + public String addColumn() + { + if (mColumnLabel != null) + { + List columns = (List) getColumnDataModel().getWrappedData(); + columns.add(mColumnLabel); + } + return null; + } + + public String removeColumn() + { + if (mColumns != null && mColumns.isRowAvailable()) + { + Object column = mColumns.getRowData(); + List columns = (List) getColumnDataModel().getWrappedData(); + columns.remove(column); + } + return null; + } + + public String getColumnLabel() + { + return mColumnLabel; + } + + public void setColumnLabel(String label) + { + mColumnLabel = label; + } + + public DataModel getCountryDataModel() + { + if (mCountryDataModel == null) + { + mCountryDataModel = new ListDataModel(getCountries()); + } + return mCountryDataModel; + } + + public DataModel getColumnDataModel() + { + if (mColumns == null) + { + String[] result = new String[] {"2002", "2003", "2004"}; + mColumns = new ListDataModel(new ArrayList(Arrays.asList(result))); + } + return mColumns; + } + + public String getColumnValue() + { + DataModel countryDataModel = getCountryDataModel(); + if (countryDataModel.isRowAvailable()) + { + SimpleCountry row = (SimpleCountry) countryDataModel.getRowData(); + DataModel columnDataModel = getColumnDataModel(); + if (columnDataModel.isRowAvailable()) + { + Object column = columnDataModel.getRowData(); + Object key = new RowColumnKey(new Long(row.getId()), column); + if (!mValueMap.containsKey(key)) + { + // initialize with random value + String randomValue = String.valueOf((int) (Math.random() * 5000) + 5000); + mValueMap.put(key, randomValue); + } + return (String) mValueMap.get(key); + } + } + return null; + } + + public void setColumnValue(String value) + { + DataModel countryDataModel = getCountryDataModel(); + if (countryDataModel.isRowAvailable()) + { + SimpleCountry row = (SimpleCountry) countryDataModel.getRowData(); + DataModel columnDataModel = getColumnDataModel(); + if (columnDataModel.isRowAvailable()) + { + Object column = columnDataModel.getRowData(); + Object key = new RowColumnKey(new Long(row.getId()), column); + mValueMap.put(key, value); + } + } + } + + private class RowColumnKey + { + private final Object mRow; + private final Object mColumn; + + /** + * @param row + * @param column + */ + public RowColumnKey(Object row, Object column) + { + mRow = row; + mColumn = column; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + if (obj == this) + { + return true; + } + if (obj instanceof RowColumnKey) + { + RowColumnKey other = (RowColumnKey) obj; + return other.mRow.equals(mRow) && other.mColumn.equals(mColumn); + } + return super.equals(obj); + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() + { + return (37 * 3 + mRow.hashCode()) * (37 * 3 + mColumn.hashCode()); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() + { + return mRow.toString() + "," + mColumn.toString(); + } + } +} + +/** + * $Log$ + */
