You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2012/10/07 06:37:18 UTC
svn commit: r1395211 - in /myfaces/tomahawk/trunk/core20/src:
main/java/org/apache/myfaces/component/html/ext/
test/java/org/apache/myfaces/component/html/ext/
Author: lu4242
Date: Sun Oct 7 04:37:18 2012
New Revision: 1395211
URL: http://svn.apache.org/viewvc?rev=1395211&view=rev
Log:
TOMAHAWK-1639 AbstractHtmlDataTable.expandAllDetails() doesn't work unless rowKey is specified on dataTable
Added:
myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/DetailTogglerModel.java (with props)
Modified:
myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java
myfaces/tomahawk/trunk/core20/src/test/java/org/apache/myfaces/component/html/ext/HtmlDataTableTest.java
Modified: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java?rev=1395211&r1=1395210&r2=1395211&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java (original)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java Sun Oct 7 04:37:18 2012
@@ -85,7 +85,8 @@ import org.apache.myfaces.shared_tomahaw
clazz = "org.apache.myfaces.component.html.ext.HtmlDataTable",
tagClass = "org.apache.myfaces.generated.taglib.html.ext.HtmlDataTableTag",
tagHandler = "org.apache.myfaces.component.html.ext.HtmlDataTableTagHandler")
-public abstract class AbstractHtmlDataTable extends HtmlDataTableHack implements UserRoleAware, NewspaperTable
+public abstract class AbstractHtmlDataTable extends HtmlDataTableHack
+ implements UserRoleAware, NewspaperTable, DetailTogglerModel
{
private static final Log log = LogFactory.getLog(AbstractHtmlDataTable.class);
@@ -121,8 +122,6 @@ public abstract class AbstractHtmlDataTa
private boolean _isValidChildren = true;
- private Map<String, Boolean> _expandedNodes = new HashMap<String, Boolean>();
-
//private Map<String, Object> _detailRowStates = new HashMap<String, Object>();
private TableContext _tableContext = null;
@@ -145,7 +144,7 @@ public abstract class AbstractHtmlDataTa
* This facet renders an additional row after or before (according
* to detailStampLocation value) the current row, usually containing
* additional information of the related row. It is toggled usually
- * using varDetailToggle variable and the method toggleDetail().
+ * using varDetailToggler variable and the method toggleDetail().
*
* @JSFFacet name="detailStamp"
*/
@@ -1543,7 +1542,7 @@ public abstract class AbstractHtmlDataTa
return null;
}
- Object[] values = new Object[5];
+ Object[] values = new Object[4];
values[0] = parentSaved;
if (isPreserveDataModel())
@@ -1558,12 +1557,11 @@ public abstract class AbstractHtmlDataTa
values[2] = preserveSort ? getSortColumn() : null;
values[3] = preserveSort ? Boolean.valueOf(isSortAscending()) : null;
- values[4] = _expandedNodes;
return values;
}
else
{
- Object[] values = new Object[5];
+ Object[] values = new Object[4];
values[0] = super.saveState(context);
if (isPreserveDataModel())
@@ -1578,7 +1576,6 @@ public abstract class AbstractHtmlDataTa
values[2] = preserveSort ? getSortColumn() : null;
values[3] = preserveSort ? Boolean.valueOf(isSortAscending()) : null;
- values[4] = _expandedNodes;
return values;
}
@@ -1685,7 +1682,7 @@ public abstract class AbstractHtmlDataTa
}
}
- _expandedNodes = (Map) values[4];
+ //_expandedNodes = (Map) values[4];
}
public _SerializableDataModel getSerializableDataModel()
@@ -1899,6 +1896,8 @@ public abstract class AbstractHtmlDataTa
*/
@JSFProperty(defaultValue="false")
public abstract boolean isDetailStampExpandedDefault();
+
+ public abstract void setDetailStampExpandedDefault(boolean value);
/**
* before|after - where to render the detailStamp, before the
@@ -2015,10 +2014,41 @@ public abstract class AbstractHtmlDataTa
_preservedDataModel = preservedDataModel;
}
+ protected Map<String, Object> getExpandedNodes()
+ {
+ return (Map<String, Object>) getStateHelper().get(PropertyKeys.expandedNodes);
+ }
+
+ protected void clearExpandedNodes()
+ {
+ Map<String, Object> nodes = (Map<String, Object>) getExpandedNodes();
+ if (nodes != null)
+ {
+ nodes.clear();
+ }
+ }
+
+ protected Boolean getExpandedNode(String key)
+ {
+ Map<String, Object> nodes = (Map<String, Object>) getExpandedNodes();
+ return (Boolean) ( (nodes == null) ? null : nodes.get(key) );
+ }
+
+ protected Boolean setExpandedNode(String key, Boolean value)
+ {
+ return (Boolean) getStateHelper().put(PropertyKeys.expandedNodes, key, value);
+ }
+
+ protected Boolean removeExpandedNode(String key)
+ {
+ return (Boolean) getStateHelper().remove(PropertyKeys.expandedNodes, key);
+ }
public boolean isCurrentDetailExpanded()
{
- Boolean expanded = (Boolean) _expandedNodes.get(getContainerClientId(getFacesContext()));
+ Boolean expanded = (getValueExpression("rowKey") != null) ?
+ (Boolean) getExpandedNode(getContainerClientId(getFacesContext())) :
+ (Boolean) getExpandedNode(new Integer(getRowIndex()).toString());
if (expanded != null)
{
return expanded.booleanValue();
@@ -2084,7 +2114,8 @@ public abstract class AbstractHtmlDataTa
*/
public void toggleDetail()
{
- String derivedRowKey = getContainerClientId(getFacesContext());
+ String derivedRowKey = (getValueExpression("rowKey") != null) ?
+ getContainerClientId(getFacesContext()) : new Integer(getRowIndex()).toString();
// get the current expanded state of the row
boolean expanded = isDetailExpanded();
@@ -2095,12 +2126,12 @@ public abstract class AbstractHtmlDataTa
if (isDetailStampExpandedDefault())
{
// if default is expanded we have to override with FALSE here
- _expandedNodes.put(derivedRowKey, Boolean.FALSE);
+ setExpandedNode(derivedRowKey, Boolean.FALSE);
}
else
{
// if default is collapsed we can fallback to this default
- _expandedNodes.remove(derivedRowKey);
+ removeExpandedNode(derivedRowKey);
}
}
else
@@ -2110,12 +2141,12 @@ public abstract class AbstractHtmlDataTa
if (isDetailStampExpandedDefault())
{
// if default is expanded we can fallback to this default
- _expandedNodes.remove(derivedRowKey);
+ removeExpandedNode(derivedRowKey);
}
else
{
// if default is collapsed we have to override with TRUE
- _expandedNodes.put(derivedRowKey, Boolean.TRUE);
+ setExpandedNode(derivedRowKey, Boolean.TRUE);
}
}
}
@@ -2127,7 +2158,9 @@ public abstract class AbstractHtmlDataTa
*/
public boolean isDetailExpanded()
{
- Boolean expanded = (Boolean) _expandedNodes.get(getContainerClientId(getFacesContext()));
+ Boolean expanded = (getValueExpression("rowKey") != null) ?
+ getExpandedNode(getContainerClientId(getFacesContext())) :
+ getExpandedNode(new Integer(getRowIndex()).toString());
if (expanded == null)
{
return isDetailStampExpandedDefault();
@@ -2192,31 +2225,51 @@ public abstract class AbstractHtmlDataTa
*/
public void expandAllDetails()
{
- int rowCount = getRowCount();
+ clearExpandedNodes();
- _expandedNodes.clear();
-
- if (getRowKey() != null)
+ if (!isDetailStampExpandedDefault())
{
+ setDetailStampExpandedDefault(true);
+ }
+ }
+
+ public void expandAllPageDetails()
+ {
+ clearExpandedNodes();
+
+ if (!isDetailStampExpandedDefault())
+ {
+ // iterate over the rows
+ int rowsToProcess = getRows();
+ // if getRows() returns 0, all rows have to be processed
+ if (rowsToProcess == 0)
+ {
+ rowsToProcess = getRowCount();
+ }
+ int rowIndex = getFirst();
int oldRow = getRowIndex();
+ boolean hasRowKey = getValueExpression("rowKey") != null;
try
{
- for (int row = 0; row < rowCount; row++)
+ for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
{
- setRowIndex(row);
- _expandedNodes.put(getContainerClientId(getFacesContext()), Boolean.TRUE);
+ if (hasRowKey)
+ {
+ setRowIndex(rowIndex);
+ setExpandedNode(getContainerClientId(getFacesContext()), Boolean.TRUE);
+ }
+ else
+ {
+ setExpandedNode(new Integer(rowIndex).toString(), Boolean.TRUE);
+ }
}
}
finally
{
- setRowIndex(oldRow);
- }
- }
- else
- {
- for (int row = 0; row < rowCount; row++)
- {
- _expandedNodes.put(new Integer(row).toString(), Boolean.TRUE);
+ if (hasRowKey)
+ {
+ setRowIndex(oldRow);
+ }
}
}
}
@@ -2226,7 +2279,53 @@ public abstract class AbstractHtmlDataTa
*/
public void collapseAllDetails()
{
- _expandedNodes.clear();
+ clearExpandedNodes();
+
+ if (isDetailStampExpandedDefault())
+ {
+ setDetailStampExpandedDefault(false);
+ }
+ }
+
+ public void collapseAllPageDetails()
+ {
+ clearExpandedNodes();
+
+ if (isDetailStampExpandedDefault())
+ {
+ // iterate over the rows
+ int rowsToProcess = getRows();
+ // if getRows() returns 0, all rows have to be processed
+ if (rowsToProcess == 0)
+ {
+ rowsToProcess = getRowCount();
+ }
+ int rowIndex = getFirst();
+ int oldRow = getRowIndex();
+ boolean hasRowKey = getValueExpression("rowKey") != null;
+ try
+ {
+ for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
+ {
+ if (hasRowKey)
+ {
+ setRowIndex(rowIndex);
+ setExpandedNode(getContainerClientId(getFacesContext()), Boolean.FALSE);
+ }
+ else
+ {
+ setExpandedNode(new Integer(rowIndex).toString(), Boolean.FALSE);
+ }
+ }
+ }
+ finally
+ {
+ if (hasRowKey)
+ {
+ setRowIndex(oldRow);
+ }
+ }
+ }
}
/**
@@ -2235,9 +2334,9 @@ public abstract class AbstractHtmlDataTa
public boolean isExpandedEmpty()
{
boolean expandedEmpty = true;
- if (_expandedNodes != null)
+ if (getExpandedNodes() != null)
{
- expandedEmpty = _expandedNodes.isEmpty();
+ expandedEmpty = getExpandedNodes().isEmpty();
}
return expandedEmpty;
}
@@ -2251,10 +2350,7 @@ public abstract class AbstractHtmlDataTa
{
if (expandedEmpty)
{
- if (_expandedNodes != null)
- {
- _expandedNodes.clear();
- }
+ clearExpandedNodes();
}
}
Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/DetailTogglerModel.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/DetailTogglerModel.java?rev=1395211&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/DetailTogglerModel.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/DetailTogglerModel.java Sun Oct 7 04:37:18 2012
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.html.ext;
+
+/**
+ * This interface define a contract to manipulate the toggle state of components
+ * like t:dataTable with detailStamp enabled. An object implementing this interface
+ * is set on request scope under the key defined by varDetailToggler.
+ *
+ * @author Leonardo Uribe
+ */
+public interface DetailTogglerModel
+{
+ /**
+ * Collapse all details of all rows in all pages.
+ */
+ public void collapseAllDetails();
+
+ /**
+ * Expand all details of the rows displayed on the current page.
+ */
+ public void collapseAllPageDetails();
+
+ /**
+ * Expand all details of all rows in all pages.
+ */
+ public void expandAllDetails();
+
+ /**
+ * Expand all details of the rows displayed on the current page.
+ */
+ public void expandAllPageDetails();
+
+ /**
+ * Return true if the current detail row is expanded.
+ *
+ * @return true if the current detail row is expanded.
+ */
+ public boolean isCurrentDetailExpanded();
+
+ /**
+ * Change the status of the current detail row from collapsed to expanded or
+ * viceversa.
+ */
+ public void toggleDetail();
+
+ /**
+ * true|false - true if the detailStamp should be expanded by default. default: false
+ *
+ */
+ public boolean isDetailStampExpandedDefault();
+
+}
Propchange: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/component/html/ext/DetailTogglerModel.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/tomahawk/trunk/core20/src/test/java/org/apache/myfaces/component/html/ext/HtmlDataTableTest.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/test/java/org/apache/myfaces/component/html/ext/HtmlDataTableTest.java?rev=1395211&r1=1395210&r2=1395211&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/test/java/org/apache/myfaces/component/html/ext/HtmlDataTableTest.java (original)
+++ myfaces/tomahawk/trunk/core20/src/test/java/org/apache/myfaces/component/html/ext/HtmlDataTableTest.java Sun Oct 7 04:37:18 2012
@@ -36,7 +36,6 @@ import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.model.ListDataModel;
-import junit.framework.Test;
import org.apache.myfaces.component.html.ext.HtmlDataTablePreserveRowComponentStateTest.RowData;
import org.apache.myfaces.test.AbstractTomahawkViewControllerTestCase;
@@ -348,5 +347,184 @@ public class HtmlDataTableTest extends A
assertEquals(model.get(i).getText(), detailStampText.getValue());
}
}
+
+ public void testDetailStampRowState3() throws Exception
+ {
+ List<RowData> model = new ArrayList<RowData>();
+ model.add(new RowData("text1","style1"));
+ model.add(new RowData("text1","style2"));
+ model.add(new RowData("text1","style3"));
+ model.add(new RowData("text1","style4"));
+
+ //Put on request map to be resolved later
+ request.setAttribute("list", model);
+
+ UIViewRoot root = facesContext.getViewRoot();
+ HtmlDataTable table = new HtmlDataTable();
+ UIColumn column = new UIColumn();
+ UIPanel detailStampPanel = new UIPanel();
+ UIOutput text = new UIOutput();
+ UIOutput detailStampText = new UIOutput();
+
+ //This is only required if markInitiaState fix is not used
+ root.setId("root");
+ table.setId("table");
+ detailStampPanel.setId("detailStamp");
+ column.setId("column");
+ text.setId("text");
+ detailStampText.setId("detailStampText");
+
+ table.setVar("row");
+ table.setPreserveRowComponentState(true);
+ table.setValueExpression("value", application.
+ getExpressionFactory().createValueExpression(
+ facesContext.getELContext(),"#{list}",List.class));
+
+ text.setValueExpression("value", application.
+ getExpressionFactory().createValueExpression(
+ facesContext.getELContext(),"#{row.text}",String.class));
+
+ detailStampText.setValueExpression("value", application.
+ getExpressionFactory().createValueExpression(
+ facesContext.getELContext(),"#{row.text}",String.class));
+
+ root.getChildren().add(table);
+ table.getChildren().add(column);
+ table.getFacets().put(AbstractHtmlDataTable.DETAIL_STAMP_FACET_NAME, detailStampPanel);
+ column.getChildren().add(text);
+ detailStampPanel.getChildren().add(detailStampText);
+
+ //Check the value expressions are working and change the component state
+ for (int i = 0; i < model.size(); i++)
+ {
+ RowData rowData = model.get(i);
+ table.setRowIndex(i);
+ assertEquals(rowData.getText(), text.getValue());
+ assertEquals(rowData.getText(), detailStampText.getValue());
+ }
+
+ //Reset row index
+ table.setRowIndex(-1);
+
+ //Remove a row
+ table.deleteRowStateForRow(1);
+ model.remove(1);
+ //Check the values were not lost
+ for (int i = 0; i < model.size(); i++)
+ {
+ table.setRowIndex(i);
+ assertEquals(model.get(i).getText(), text.getValue());
+ assertEquals(model.get(i).getText(), detailStampText.getValue());
+ }
+
+ table.expandAllDetails();
+
+ for (int i = 0; i < model.size(); i++)
+ {
+ table.setRowIndex(i);
+ assertTrue(table.isDetailExpanded());
+ }
+
+ table.collapseAllDetails();
+ for (int i = 0; i < model.size(); i++)
+ {
+ table.setRowIndex(i);
+ assertFalse(table.isDetailExpanded());
+ }
+ }
+
+ public void testDetailStampRowState4() throws Exception
+ {
+ List<RowData> model = new ArrayList<RowData>();
+ model.add(new RowData("text1","style1"));
+ model.add(new RowData("text1","style2"));
+ model.add(new RowData("text1","style3"));
+ model.add(new RowData("text1","style4"));
+
+ //Put on request map to be resolved later
+ request.setAttribute("list", model);
+
+ UIViewRoot root = facesContext.getViewRoot();
+ HtmlDataTable table = new HtmlDataTable();
+ UIColumn column = new UIColumn();
+ UIPanel detailStampPanel = new UIPanel();
+ UIOutput text = new UIOutput();
+ UIOutput detailStampText = new UIOutput();
+
+ //This is only required if markInitiaState fix is not used
+ root.setId("root");
+ table.setId("table");
+ detailStampPanel.setId("detailStamp");
+ column.setId("column");
+ text.setId("text");
+ detailStampText.setId("detailStampText");
+
+ table.setVar("row");
+ table.setPreserveRowComponentState(true);
+ table.setValueExpression("value", application.
+ getExpressionFactory().createValueExpression(
+ facesContext.getELContext(),"#{list}",List.class));
+ table.setRows(2);
+
+ text.setValueExpression("value", application.
+ getExpressionFactory().createValueExpression(
+ facesContext.getELContext(),"#{row.text}",String.class));
+
+ detailStampText.setValueExpression("value", application.
+ getExpressionFactory().createValueExpression(
+ facesContext.getELContext(),"#{row.text}",String.class));
+
+ root.getChildren().add(table);
+ table.getChildren().add(column);
+ table.getFacets().put(AbstractHtmlDataTable.DETAIL_STAMP_FACET_NAME, detailStampPanel);
+ column.getChildren().add(text);
+ detailStampPanel.getChildren().add(detailStampText);
+
+ //Check the value expressions are working and change the component state
+ for (int i = 0; i < model.size(); i++)
+ {
+ RowData rowData = model.get(i);
+ table.setRowIndex(i);
+ assertEquals(rowData.getText(), text.getValue());
+ assertEquals(rowData.getText(), detailStampText.getValue());
+ }
+
+ //Reset row index
+ table.setRowIndex(-1);
+
+ //Remove a row
+ table.deleteRowStateForRow(1);
+ model.remove(1);
+
+ //Check the values were not lost
+ for (int i = 0; i < model.size(); i++)
+ {
+ table.setRowIndex(i);
+ assertEquals(model.get(i).getText(), text.getValue());
+ assertEquals(model.get(i).getText(), detailStampText.getValue());
+ }
+
+ table.expandAllPageDetails();
+
+ for (int i = 0; i < model.size(); i++)
+ {
+ table.setRowIndex(i);
+ if (i < 2)
+ {
+ assertTrue(table.isDetailExpanded());
+ }
+ else
+ {
+ assertFalse(table.isDetailExpanded());
+ }
+ }
+
+ table.collapseAllPageDetails();
+ for (int i = 0; i < model.size(); i++)
+ {
+ table.setRowIndex(i);
+ assertFalse(table.isDetailExpanded());
+ }
+ }
}