summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebContent/VAADIN/themes/base/escalator/escalator.scss4
-rw-r--r--WebContent/VAADIN/themes/base/grid/grid.scss4
-rw-r--r--client/src/com/vaadin/client/widget/grid/DetailsGenerator.java45
-rw-r--r--client/src/com/vaadin/client/widgets/Grid.java100
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java40
5 files changed, 189 insertions, 4 deletions
diff --git a/WebContent/VAADIN/themes/base/escalator/escalator.scss b/WebContent/VAADIN/themes/base/escalator/escalator.scss
index 6d146f3a74..7949b52882 100644
--- a/WebContent/VAADIN/themes/base/escalator/escalator.scss
+++ b/WebContent/VAADIN/themes/base/escalator/escalator.scss
@@ -137,9 +137,7 @@
position: absolute;
display: block;
- // debug
- background-color: rgba(0,0,0,0.6);
- color: white;
+ background-color: $background-color;
> td {
width: 100%;
diff --git a/WebContent/VAADIN/themes/base/grid/grid.scss b/WebContent/VAADIN/themes/base/grid/grid.scss
index e4a4a1d920..730bee8a6b 100644
--- a/WebContent/VAADIN/themes/base/grid/grid.scss
+++ b/WebContent/VAADIN/themes/base/grid/grid.scss
@@ -328,6 +328,10 @@ $v-grid-editor-background-color: $v-grid-row-background-color !default;
.#{$primaryStyleName}-editor-save {
margin-right: 4px;
}
+
+ .#{$primaryStyleName}-spacer {
+ border: $v-grid-border;
+ }
// Renderers
diff --git a/client/src/com/vaadin/client/widget/grid/DetailsGenerator.java b/client/src/com/vaadin/client/widget/grid/DetailsGenerator.java
new file mode 100644
index 0000000000..665362ca8e
--- /dev/null
+++ b/client/src/com/vaadin/client/widget/grid/DetailsGenerator.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * 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 com.vaadin.client.widget.grid;
+
+/**
+ * A callback interface for generating details for a particular row in Grid.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface DetailsGenerator {
+
+ public static final DetailsGenerator NULL = new DetailsGenerator() {
+ @Override
+ public String getDetails(int rowIndex) {
+ return null;
+ }
+ };
+
+ /**
+ * This method is called for whenever a new details row needs to be
+ * generated.
+ *
+ * @param rowIndex
+ * the index of the row for which to generate details
+ * @return the details for the given row, or <code>null</code> to leave the
+ * details empty.
+ */
+ // TODO: provide a row object instead of index (maybe, needs discussion?)
+ // TODO: return a Widget instead of a String
+ String getDetails(int rowIndex);
+}
diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java
index 71962d6953..31984f7d5b 100644
--- a/client/src/com/vaadin/client/widgets/Grid.java
+++ b/client/src/com/vaadin/client/widgets/Grid.java
@@ -36,6 +36,7 @@ import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
+import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableCellElement;
@@ -77,10 +78,13 @@ import com.vaadin.client.widget.escalator.RowContainer;
import com.vaadin.client.widget.escalator.RowVisibilityChangeEvent;
import com.vaadin.client.widget.escalator.RowVisibilityChangeHandler;
import com.vaadin.client.widget.escalator.ScrollbarBundle.Direction;
+import com.vaadin.client.widget.escalator.Spacer;
+import com.vaadin.client.widget.escalator.SpacerUpdater;
import com.vaadin.client.widget.grid.CellReference;
import com.vaadin.client.widget.grid.CellStyleGenerator;
import com.vaadin.client.widget.grid.DataAvailableEvent;
import com.vaadin.client.widget.grid.DataAvailableHandler;
+import com.vaadin.client.widget.grid.DetailsGenerator;
import com.vaadin.client.widget.grid.EditorHandler;
import com.vaadin.client.widget.grid.EditorHandler.EditorRequest;
import com.vaadin.client.widget.grid.EventCellReference;
@@ -1776,6 +1780,8 @@ public class Grid<T> extends ResizeComposite implements
private static final String CUSTOM_STYLE_PROPERTY_NAME = "customStyle";
+ private static final double DETAILS_ROW_INITIAL_HEIGHT = 50;
+
private EventCellReference<T> eventCell = new EventCellReference<T>(this);
private GridKeyDownEvent keyDown = new GridKeyDownEvent(this, eventCell);
private GridKeyUpEvent keyUp = new GridKeyUpEvent(this, eventCell);
@@ -2768,6 +2774,38 @@ public class Grid<T> extends ResizeComposite implements
}
}
+ private class GridSpacerUpdater implements SpacerUpdater {
+ @Override
+ public void init(Spacer spacer) {
+ int rowIndex = spacer.getRow();
+
+ String string = detailsGenerator.getDetails(rowIndex);
+ if (string == null) {
+ destroy(spacer);
+ escalator.getBody().setSpacer(rowIndex,
+ DETAILS_ROW_INITIAL_HEIGHT);
+ return;
+ }
+
+ spacer.getElement().setInnerText(string);
+
+ /*
+ * Once we have the content properly inside the DOM, we should
+ * re-measure it to make sure that it's the correct height.
+ */
+ double measuredHeight = WidgetUtil
+ .getRequiredHeightBoundingClientRectDouble(spacer
+ .getElement());
+ assert getElement().isOrHasChild(spacer.getElement()) : "The spacer element wasn't in the DOM during measurement, but was assumed to be.";
+ escalator.getBody().setSpacer(rowIndex, measuredHeight);
+ }
+
+ @Override
+ public void destroy(Spacer spacer) {
+ spacer.getElement().setInnerText("");
+ }
+ }
+
/**
* Escalator used internally by grid to render the rows
*/
@@ -2853,6 +2891,10 @@ public class Grid<T> extends ResizeComposite implements
private boolean enabled = true;
+ private DetailsGenerator detailsGenerator = DetailsGenerator.NULL;
+
+ private GridSpacerUpdater gridSpacerUpdater = new GridSpacerUpdater();
+
/**
* Enumeration for easy setting of selection mode.
*/
@@ -4902,7 +4944,7 @@ public class Grid<T> extends ResizeComposite implements
EventTarget target = event.getEventTarget();
- if (!Element.is(target)) {
+ if (!Element.is(target) || isOrContainsInSpacer(Element.as(target))) {
return;
}
@@ -4968,6 +5010,19 @@ public class Grid<T> extends ResizeComposite implements
}
}
+ private boolean isOrContainsInSpacer(Node node) {
+ Node n = node;
+ while (n != null && n != getElement()) {
+ if (Element.is(n)
+ && Element.as(n).getClassName()
+ .equals(getStylePrimaryName() + "-spacer")) {
+ return true;
+ }
+ n = n.getParentNode();
+ }
+ return false;
+ }
+
private boolean isElementInChildWidget(Element e) {
Widget w = WidgetUtil.findWidget(e, null);
@@ -6279,4 +6334,47 @@ public class Grid<T> extends ResizeComposite implements
public void resetSizesFromDom() {
getEscalator().resetSizesFromDom();
}
+
+ /**
+ * Sets a new details generator for row details.
+ * <p>
+ * The currently opened row details will be re-rendered.
+ *
+ * @since
+ * @param detailsGenerator
+ * the details generator to set
+ */
+ public void setDetailsGenerator(DetailsGenerator detailsGenerator)
+ throws IllegalArgumentException {
+
+ this.detailsGenerator = detailsGenerator;
+
+ // this will refresh all visible spacers
+ escalator.getBody().setSpacerUpdater(gridSpacerUpdater);
+ }
+
+ /**
+ * Gets the current details generator for row details.
+ *
+ * @since
+ * @return the detailsGenerator the current details generator
+ */
+ public DetailsGenerator getDetailsGenerator() {
+ return detailsGenerator;
+ }
+
+ /**
+ * Shows or hides the details for a specific row.
+ *
+ * @since
+ * @param row
+ * the index of the affected row
+ * @param visible
+ * <code>true</code> to show the details, or <code>false</code>
+ * to hide them
+ */
+ public void setDetailsVisible(int rowIndex, boolean visible) {
+ double height = visible ? DETAILS_ROW_INITIAL_HEIGHT : -1;
+ escalator.getBody().setSpacer(rowIndex, height);
+ }
}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
index 0452aa65d1..7c2ca3eedb 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
@@ -46,6 +46,7 @@ import com.vaadin.client.renderers.TextRenderer;
import com.vaadin.client.ui.VLabel;
import com.vaadin.client.widget.grid.CellReference;
import com.vaadin.client.widget.grid.CellStyleGenerator;
+import com.vaadin.client.widget.grid.DetailsGenerator;
import com.vaadin.client.widget.grid.EditorHandler;
import com.vaadin.client.widget.grid.RendererCellReference;
import com.vaadin.client.widget.grid.RowReference;
@@ -400,6 +401,7 @@ public class GridBasicClientFeaturesWidget extends
createEditorMenu();
createInternalsMenu();
createDataSourceMenu();
+ createDetailsMenu();
grid.getElement().getStyle().setZIndex(0);
@@ -1214,4 +1216,42 @@ public class GridBasicClientFeaturesWidget extends
String coords = "(" + object + ", " + column + ")";
label.setText(coords + " " + output);
}
+
+ private void createDetailsMenu() {
+ String[] menupath = new String[] { "Component", "Row details" };
+ addMenuCommand("Set generator", new ScheduledCommand() {
+ @Override
+ public void execute() {
+ grid.setDetailsGenerator(new DetailsGenerator() {
+ @Override
+ public String getDetails(int rowIndex) {
+ return "Row: " + rowIndex + ". Lorem ipsum "
+ + "dolor sit amet, consectetur adipiscing "
+ + "elit. Morbi congue massa non augue "
+ + "pulvinar, nec consectetur justo efficitur. "
+ + "In nec arcu sit amet lorem hendrerit "
+ + "mollis.";
+ }
+ });
+ }
+ }, menupath);
+ addMenuCommand("Toggle details for row 1", new ScheduledCommand() {
+ boolean visible = false;
+
+ @Override
+ public void execute() {
+ visible = !visible;
+ grid.setDetailsVisible(1, visible);
+ }
+ }, menupath);
+ addMenuCommand("Toggle details for row 100", new ScheduledCommand() {
+ boolean visible = false;
+
+ @Override
+ public void execute() {
+ visible = !visible;
+ grid.setDetailsVisible(100, visible);
+ }
+ }, menupath);
+ }
}