top += Window.getScrollTop();
left += Window.getScrollLeft();
client.getContextMenu().showAt(this, left, top);
+
+ // Only prevent browser context menu if there are action handlers
+ // registered
+ event.stopPropagation();
+ event.preventDefault();
}
- event.stopPropagation();
- event.preventDefault();
}
/**
final Element targetTdOrTr = getEventTargetTdOrTr(event);
if (type == Event.ONCONTEXTMENU) {
showContextMenu(event);
- event.stopPropagation();
+ if (enabled
+ && (actionKeys != null || client
+ .hasEventListeners(VScrollTable.this,
+ ITEM_CLICK_EVENT_ID))) {
+ // Prevent browser context menu only if there are
+ // action handlers or item click listeners
+ // registered
+ event.stopPropagation();
+ event.preventDefault();
+ }
return;
}
public void showContextMenu(Event event) {
if (enabled && actionKeys != null) {
+ // Show context menu if there are registered action handlers
int left = Util.getTouchOrMouseClientX(event);
int top = Util.getTouchOrMouseClientY(event);
top += Window.getScrollTop();
left += Window.getScrollLeft();
client.getContextMenu().showAt(this, left, top);
}
- event.stopPropagation();
- event.preventDefault();
}
/**
--- /dev/null
+package com.vaadin.tests.components.table;\r
+\r
+import com.vaadin.data.Item;\r
+import com.vaadin.data.Property.ValueChangeEvent;\r
+import com.vaadin.data.Property.ValueChangeListener;\r
+import com.vaadin.event.Action;\r
+import com.vaadin.event.ItemClickEvent;\r
+import com.vaadin.event.ItemClickEvent.ItemClickListener;\r
+import com.vaadin.terminal.ExternalResource;\r
+import com.vaadin.tests.components.TestBase;\r
+import com.vaadin.ui.CheckBox;\r
+import com.vaadin.ui.Component;\r
+import com.vaadin.ui.Link;\r
+import com.vaadin.ui.Table;\r
+\r
+public class TableAndBrowserContextMenu extends TestBase implements\r
+ Action.Handler, ItemClickListener {\r
+\r
+ private Table table;\r
+ private boolean actionHandlerHasActions = false;\r
+\r
+ @Override\r
+ public void setup() {\r
+ CheckBox cb = new CheckBox("Item click listener");\r
+ cb.setImmediate(true);\r
+ cb.addListener(new ValueChangeListener() {\r
+\r
+ public void valueChange(ValueChangeEvent event) {\r
+ if (((Boolean) event.getProperty().getValue())) {\r
+ table.addListener(TableAndBrowserContextMenu.this);\r
+ } else {\r
+ table.removeListener(TableAndBrowserContextMenu.this);\r
+ }\r
+\r
+ }\r
+ });\r
+ addComponent(cb);\r
+\r
+ CheckBox cbActionHandler = new CheckBox("Action handler");\r
+ cbActionHandler.setImmediate(true);\r
+ cbActionHandler.addListener(new ValueChangeListener() {\r
+\r
+ public void valueChange(ValueChangeEvent event) {\r
+ if (((Boolean) event.getProperty().getValue())) {\r
+ table.addActionHandler(TableAndBrowserContextMenu.this);\r
+ } else {\r
+ table.removeActionHandler(TableAndBrowserContextMenu.this);\r
+ }\r
+\r
+ }\r
+ });\r
+ addComponent(cbActionHandler);\r
+\r
+ CheckBox cbActionHasActions = new CheckBox("Action handler has actions");\r
+ cbActionHasActions.setImmediate(true);\r
+ cbActionHasActions.addListener(new ValueChangeListener() {\r
+\r
+ public void valueChange(ValueChangeEvent event) {\r
+ actionHandlerHasActions = ((Boolean) event.getProperty()\r
+ .getValue());\r
+\r
+ // Workaround to ensure actions are repainted\r
+ removeComponent(table);\r
+ addComponent(table);\r
+\r
+ }\r
+ });\r
+ addComponent(cbActionHasActions);\r
+\r
+ createTable();\r
+ addComponent(table);\r
+\r
+ }\r
+\r
+ private void createTable() {\r
+ // Have a table with a numeric column\r
+ table = new Table("A table");\r
+ table.addContainerProperty("Name", String.class, null);\r
+ table.addContainerProperty("Died At Age", Integer.class, null);\r
+\r
+ // Add a generated column with a link to Google\r
+ table.addGeneratedColumn("Search", new Table.ColumnGenerator() {\r
+ public Component generateCell(Table source, Object itemId,\r
+ Object columnId) {\r
+ Item item = source.getItem(itemId);\r
+ String name = (String) item.getItemProperty("Name").getValue();\r
+ return new Link("Google for " + name, new ExternalResource(\r
+ "http://www.google.co.uk/search?q=" + name));\r
+ }\r
+ });\r
+\r
+ // Insert some data\r
+ Object people[][] = { { "Galileo", 77 }, { "Monnier", 83 },\r
+ { "Vaisala", 79 }, { "Oterma", 86 } };\r
+\r
+ for (int i = 0; i < people.length; i++) {\r
+ table.addItem(people[i], i);\r
+ }\r
+\r
+ // Calculate the average of the numeric column\r
+ double avgAge = 0;\r
+ for (int i = 0; i < people.length; i++) {\r
+ avgAge += (Integer) people[i][1];\r
+ }\r
+ avgAge /= people.length;\r
+\r
+ // Set the footers\r
+ table.setFooterVisible(true);\r
+ table.setColumnFooter("Name", "Average");\r
+ table.setColumnFooter("Died At Age", String.valueOf(avgAge));\r
+\r
+ // Adjust the table height a bit\r
+ table.setPageLength(table.size() + 2);\r
+\r
+ for (int i = 0; i < people.length; i++) {\r
+ Object[] person = people[i];\r
+ String name = (String) person[0];\r
+ addComponent(new Link("Google for " + name, new ExternalResource(\r
+ "http://www.google.co.uk/search?q=" + name)));\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ protected String getDescription() {\r
+ return "Table should only prevent the browser context menu when the right click is used for some Table specific operation. In practice these are either action handlers/context menu or item click listeners (right click). Note that item click listeners affects rows only, not the body.";\r
+ }\r
+\r
+ @Override\r
+ protected Integer getTicketNumber() {\r
+ return 5924;\r
+ }\r
+\r
+ public void itemClick(ItemClickEvent event) {\r
+ getMainWindow()\r
+ .showNotification("Click using " + event.getButtonName());\r
+ }\r
+\r
+ public Action[] getActions(Object target, Object sender) {\r
+ if (!actionHandlerHasActions) {\r
+ return null;\r
+ }\r
+\r
+ return new Action[] { new Action("test") };\r
+ }\r
+\r
+ public void handleAction(Action action, Object sender, Object target) {\r
+ getMainWindow().showNotification("Action: " + action.getCaption());\r
+ }\r
+}
\ No newline at end of file