]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merged fix for #2688
authorArtur Signell <artur.signell@itmill.com>
Tue, 3 Mar 2009 09:32:05 +0000 (09:32 +0000)
committerArtur Signell <artur.signell@itmill.com>
Tue, 3 Mar 2009 09:32:05 +0000 (09:32 +0000)
svn changeset:7013/svn branch:6.0

src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java
src/com/itmill/toolkit/tests/components/table/LabelEmbeddedClickThroughForTable.java [new file with mode: 0644]

index b80eacfad9597926998e3f1286dc6e5ce8cde39f..4c06ad6aaa35d20a4b0077caedf1feda4d41cab7 100755 (executable)
@@ -1475,6 +1475,16 @@ public class ApplicationConnection {
         }
     }
 
+    /**
+     * Returns a Paintable element by its root element
+     * 
+     * @param element
+     *            Root element of the paintable
+     */
+    public Paintable getPaintable(Element element) {
+        return getPaintable(getPid(element));
+    }
+
     public String getResource(String name) {
         return resourcesMap.get(name);
     }
index 1f7bdcea2edcc85f78d347d7346bcf9fe1d9c449..91623c29fb63120e05b1371152eda26868581040 100644 (file)
@@ -2159,21 +2159,24 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener {
                 }
             }
 
-            private void handleClickEvent(Event event) {
+            private void handleClickEvent(Event event, Element targetTdOrTr) {
                 if (emitClickEvents) {
-                    boolean dbl = DOM.eventGetType(event) == Event.ONDBLCLICK;
-                    final Element tdOrTr = DOM.getParent(DOM
-                            .eventGetTarget(event));
+                    boolean doubleClick = (DOM.eventGetType(event) == Event.ONDBLCLICK);
+
+                    /* This row was clicked */
                     client.updateVariable(paintableId, "clickedKey", ""
                             + rowKey, false);
-                    if (getElement() == tdOrTr.getParentElement()) {
-                        int childIndex = DOM
-                                .getChildIndex(getElement(), tdOrTr);
+
+                    if (getElement() == targetTdOrTr.getParentElement()) {
+                        /* A specific column was clicked */
+                        int childIndex = DOM.getChildIndex(getElement(),
+                                targetTdOrTr);
                         String colKey = null;
                         colKey = tHead.getHeaderCell(childIndex).getColKey();
                         client.updateVariable(paintableId, "clickedColKey",
                                 colKey, false);
                     }
+
                     MouseEventDetails details = new MouseEventDetails(event);
                     // Note: the 'immediate' logic would need to be more
                     // involved (see #2104), but iscrolltable always sends
@@ -2185,7 +2188,7 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener {
                                     paintableId,
                                     "clickEvent",
                                     details.toString(),
-                                    !(!dbl
+                                    !(!doubleClick
                                             && selectMode > Table.SELECT_MODE_NONE && immediate));
                 }
             }
@@ -2195,12 +2198,11 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener {
              */
             @Override
             public void onBrowserEvent(Event event) {
-                final Element tdOrTr = DOM.getParent(DOM.eventGetTarget(event));
-                if (getElement() == tdOrTr
-                        || getElement() == tdOrTr.getParentElement()) {
+                Element targetTdOrTr = getEventTargetTdOrTr(event);
+                if (targetTdOrTr != null) {
                     switch (DOM.eventGetType(event)) {
                     case Event.ONCLICK:
-                        handleClickEvent(event);
+                        handleClickEvent(event, targetTdOrTr);
                         if (selectMode > Table.SELECT_MODE_NONE) {
                             toggleSelection();
                             // Note: changing the immediateness of this might
@@ -2211,7 +2213,7 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener {
                         }
                         break;
                     case Event.ONDBLCLICK:
-                        handleClickEvent(event);
+                        handleClickEvent(event, targetTdOrTr);
                         break;
                     case Event.ONCONTEXTMENU:
                         showContextMenu(event);
@@ -2223,6 +2225,60 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener {
                 super.onBrowserEvent(event);
             }
 
+            /**
+             * Finds the TD that the event interacts with. Returns null if the
+             * target of the event should not be handled. If the event target is
+             * the row directly this method returns the TR element instead of
+             * the TD.
+             * 
+             * @param event
+             * @return TD or TR element that the event targets (the actual event
+             *         target is this element or a child of it)
+             */
+            private Element getEventTargetTdOrTr(Event event) {
+                Element targetTdOrTr = null;
+
+                final Element eventTarget = DOM.eventGetTarget(event);
+                final Element eventTargetParent = DOM.getParent(eventTarget);
+                final Element eventTargetGrandParent = DOM
+                        .getParent(eventTargetParent);
+
+                final Element thisTrElement = getElement();
+
+                if (eventTarget == thisTrElement) {
+                    // This was a click on the TR element
+                    targetTdOrTr = eventTarget;
+                    // rowTarget = true;
+                } else if (thisTrElement == eventTargetParent) {
+                    // Target parent is the TR, so the actual target is the TD
+                    targetTdOrTr = eventTarget;
+                } else if (thisTrElement == eventTargetGrandParent) {
+                    // Target grand parent is the TR, so the parent is the TD
+                    targetTdOrTr = eventTargetParent;
+                } else {
+                    /*
+                     * This is a workaround to make Labels and Embedded in a
+                     * Table clickable (see #2688). It is really not a fix as it
+                     * does not work for a custom component (not extending
+                     * ILabel/IEmbedded) or for read only textfields etc.
+                     */
+                    Element tdElement = eventTargetParent;
+                    while (DOM.getParent(tdElement) != thisTrElement) {
+                        tdElement = DOM.getParent(tdElement);
+                    }
+
+                    Element componentElement = tdElement.getFirstChildElement()
+                            .getFirstChildElement().cast();
+                    Widget widget = (Widget) client
+                            .getPaintable(componentElement);
+                    if (widget instanceof ILabel || widget instanceof IEmbedded) {
+                        targetTdOrTr = tdElement;
+                    }
+                }
+
+                return targetTdOrTr;
+            }
+
             public void showContextMenu(Event event) {
                 if (enabled && actionKeys != null) {
                     int left = event.getClientX();
diff --git a/src/com/itmill/toolkit/tests/components/table/LabelEmbeddedClickThroughForTable.java b/src/com/itmill/toolkit/tests/components/table/LabelEmbeddedClickThroughForTable.java
new file mode 100644 (file)
index 0000000..0b9760e
--- /dev/null
@@ -0,0 +1,69 @@
+package com.itmill.toolkit.tests.components.table;
+
+import com.itmill.toolkit.data.Item;
+import com.itmill.toolkit.event.ItemClickEvent;
+import com.itmill.toolkit.event.ItemClickEvent.ItemClickListener;
+import com.itmill.toolkit.terminal.ThemeResource;
+import com.itmill.toolkit.tests.components.TestBase;
+import com.itmill.toolkit.ui.Component;
+import com.itmill.toolkit.ui.Embedded;
+import com.itmill.toolkit.ui.Label;
+import com.itmill.toolkit.ui.Table;
+
+public class LabelEmbeddedClickThroughForTable extends TestBase {
+
+    @Override
+    protected String getDescription() {
+        return "Clicking on a Label or Embedded inside a Table should select the row in the same way that clicking on a text selects the row.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 2688;
+    }
+
+    @Override
+    protected void setup() {
+        Table table = new Table();
+        table.setSelectable(true);
+        table.addContainerProperty("Column 1", String.class, "");
+        table.addContainerProperty("Column 2", Component.class, "");
+        table.addContainerProperty("Column 3", Component.class, "");
+        table.addContainerProperty("Column 4", Component.class, "");
+
+        Item item = table.addItem("Item 1 (row 1)");
+        item.getItemProperty("Column 1").setValue("String A");
+        item.getItemProperty("Column 2").setValue(new Label("Label A"));
+        item.getItemProperty("Column 3").setValue(
+                new Label("<b>Label A</b>", Label.CONTENT_XHTML));
+        item.getItemProperty("Column 4").setValue(
+                new Embedded("An embedded image", new ThemeResource(
+                        "icons/32/ok.png")));
+
+        item = table.addItem("Item 2 (row 2)");
+        item.getItemProperty("Column 1").setValue("String B");
+        item.getItemProperty("Column 2").setValue(new Label("Label B"));
+        item
+                .getItemProperty("Column 3")
+                .setValue(
+                        new Label(
+                                "<a href=\"http://www.itmill.com\" target=_blank>Label A</a>",
+                                Label.CONTENT_XHTML));
+        item.getItemProperty("Column 4").setValue(
+                new Embedded("", new ThemeResource("icons/32/cancel.png")));
+
+        table.addListener(new ItemClickListener() {
+
+            @Override
+            public void itemClick(ItemClickEvent event) {
+                getMainWindow().showNotification(
+                        "Clickevent on item " + event.getItemId()
+                                + ", column: " + event.getPropertyId());
+
+            }
+
+        });
+        addComponent(table);
+    }
+
+}