diff options
author | Leif Åstrand <leif@vaadin.com> | 2014-11-17 08:14:10 +0200 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2015-01-13 20:30:45 +0000 |
commit | 5102cc98c295a49487fcf90cc6ac7980d166eb40 (patch) | |
tree | 59b27fb5a7b41053c7239603052e17793f1aaa3a | |
parent | 30f0e91195447140190f4c4feb232e9c13d02453 (diff) | |
download | vaadin-framework-5102cc98c295a49487fcf90cc6ac7980d166eb40.tar.gz vaadin-framework-5102cc98c295a49487fcf90cc6ac7980d166eb40.zip |
Implement JavaScript renderer support (#15485)
Change-Id: Ifeac12d4124a4a7e5d0c143ff5c0590a2c98509d
10 files changed, 619 insertions, 10 deletions
diff --git a/client/src/com/vaadin/client/JavaScriptConnectorHelper.java b/client/src/com/vaadin/client/JavaScriptConnectorHelper.java index 11511f9c36..3a9a6198d3 100644 --- a/client/src/com/vaadin/client/JavaScriptConnectorHelper.java +++ b/client/src/com/vaadin/client/JavaScriptConnectorHelper.java @@ -50,7 +50,7 @@ public class JavaScriptConnectorHelper { private JavaScriptObject connectorWrapper; private int tag; - private boolean inited = false; + private String initFunctionName; public JavaScriptConnectorHelper(ServerConnector connector) { this.connector = connector; @@ -96,9 +96,8 @@ public class JavaScriptConnectorHelper { } // Init after setting up callbacks & rpc - if (!inited) { + if (initFunctionName == null) { initJavaScript(); - inited = true; } invokeIfPresent(wrapper, "onStateChange"); @@ -120,7 +119,7 @@ public class JavaScriptConnectorHelper { return object; } - private boolean initJavaScript() { + protected boolean initJavaScript() { ApplicationConfiguration conf = connector.getConnection() .getConfiguration(); ArrayList<String> attemptedNames = new ArrayList<String>(); @@ -132,6 +131,7 @@ public class JavaScriptConnectorHelper { if (tryInitJs(initFunctionName, getConnectorWrapper())) { VConsole.log("JavaScript connector initialized using " + initFunctionName); + this.initFunctionName = initFunctionName; return true; } else { VConsole.log("No JavaScript function " + initFunctionName @@ -160,7 +160,7 @@ public class JavaScriptConnectorHelper { } }-*/; - private JavaScriptObject getConnectorWrapper() { + public JavaScriptObject getConnectorWrapper() { if (connectorWrapper == null) { connectorWrapper = createConnectorWrapper(this, connector.getConnection(), nativeState, rpcMap, @@ -465,4 +465,7 @@ public class JavaScriptConnectorHelper { } }-*/; + public String getInitFunctionName() { + return initFunctionName; + } } diff --git a/client/src/com/vaadin/client/connectors/JavaScriptRendererConnector.java b/client/src/com/vaadin/client/connectors/JavaScriptRendererConnector.java new file mode 100644 index 0000000000..82d863ce0c --- /dev/null +++ b/client/src/com/vaadin/client/connectors/JavaScriptRendererConnector.java @@ -0,0 +1,278 @@ +/* + * 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.connectors; + +import java.util.ArrayList; +import java.util.Collection; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArrayString; +import com.google.gwt.dom.client.NativeEvent; +import com.vaadin.client.BrowserInfo; +import com.vaadin.client.JavaScriptConnectorHelper; +import com.vaadin.client.Util; +import com.vaadin.client.communication.HasJavaScriptConnectorHelper; +import com.vaadin.client.renderers.ComplexRenderer; +import com.vaadin.client.renderers.Renderer; +import com.vaadin.client.widget.grid.CellReference; +import com.vaadin.client.widget.grid.RendererCellReference; +import com.vaadin.shared.JavaScriptExtensionState; +import com.vaadin.shared.ui.Connect; +import com.vaadin.ui.renderer.AbstractJavaScriptRenderer; + +import elemental.json.JsonObject; +import elemental.json.JsonValue; + +/** + * Connector for server-side renderer implemented using JavaScript. + * + * @since + * @author Vaadin Ltd + */ +@Connect(AbstractJavaScriptRenderer.class) +public class JavaScriptRendererConnector extends + AbstractRendererConnector<JsonValue> implements + HasJavaScriptConnectorHelper { + private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( + this); + + private final JavaScriptObject cellReferenceWrapper = createCellReferenceWrapper(BrowserInfo + .get().isIE8()); + + @Override + protected void init() { + super.init(); + helper.init(); + + addGetRowKey(helper.getConnectorWrapper()); + } + + private static native JavaScriptObject createCellReferenceWrapper( + boolean isIE8) + /*-{ + var reference = {}; + if (isIE8) { + // IE8 only supports defineProperty for DOM objects + reference = $doc.createElement('div'); + } + + var setProperty = function(name, getter, setter) { + var descriptor = { + get: getter + } + if (setter) { + descriptor.set = setter; + } + Object.defineProperty(reference, name, descriptor); + }; + + setProperty("element", function() { + return reference.target.@CellReference::getElement()(); + }, null); + + setProperty("rowIndex", function() { + return reference.target.@CellReference::getRowIndex()(); + }, null); + + setProperty("columnIndex", function() { + return reference.target.@CellReference::getColumnIndex()(); + }, null); + + setProperty("colSpan", function() { + return reference.target.@RendererCellReference::getColSpan()(); + }, function(colSpan) { + reference.target.@RendererCellReference::setColSpan(*)(colSpan); + }); + + return reference; + }-*/; + + @Override + public JavaScriptExtensionState getState() { + return (JavaScriptExtensionState) super.getState(); + } + + private native void addGetRowKey(JavaScriptObject wrapper) + /*-{ + var self = this; + wrapper.getRowKey = $entry(function(rowIndex) { + return @JavaScriptRendererConnector::findRowKey(*)(self, rowIndex); + }); + }-*/; + + private static String findRowKey(JavaScriptRendererConnector connector, + int rowIndex) { + GridConnector gc = (GridConnector) connector.getParent(); + JsonObject row = gc.getWidget().getDataSource().getRow(rowIndex); + return connector.getRowKey(row); + } + + private boolean hasFunction(String name) { + return hasFunction(helper.getConnectorWrapper(), name); + } + + private static native boolean hasFunction(JavaScriptObject wrapper, + String name) + /*-{ + return typeof wrapper[name] === 'function'; + }-*/; + + @Override + protected Renderer<JsonValue> createRenderer() { + if (!hasFunction("render")) { + throw new RuntimeException("JavaScriptRenderer " + + helper.getInitFunctionName() + + " must have a function named 'render'"); + } + + final boolean hasInit = hasFunction("init"); + final boolean hasDestroy = hasFunction("destroy"); + final boolean hasOnActivate = hasFunction("onActivate"); + final boolean hasGetConsumedEvents = hasFunction("getConsumedEvents"); + final boolean hasOnBrowserEvent = hasFunction("onBrowserEvent"); + + return new ComplexRenderer<JsonValue>() { + @Override + public void render(RendererCellReference cell, JsonValue data) { + render(helper.getConnectorWrapper(), getJsCell(cell), + Util.json2jso(data)); + } + + private JavaScriptObject getJsCell(CellReference<?> cell) { + updateCellReference(cellReferenceWrapper, cell); + return cellReferenceWrapper; + } + + public native void render(JavaScriptObject wrapper, + JavaScriptObject cell, JavaScriptObject data) + /*-{ + wrapper.render(cell, data); + }-*/; + + @Override + public void init(RendererCellReference cell) { + if (hasInit) { + init(helper.getConnectorWrapper(), getJsCell(cell)); + } + } + + private native void init(JavaScriptObject wrapper, + JavaScriptObject cell) + /*-{ + wrapper.init(cell); + }-*/; + + private native void updateCellReference( + JavaScriptObject cellWrapper, CellReference<?> target) + /*-{ + cellWrapper.target = target; + }-*/; + + @Override + public void destroy(RendererCellReference cell) { + if (hasDestroy) { + destory(helper.getConnectorWrapper(), getJsCell(cell)); + } else { + super.destroy(cell); + } + } + + private native void destory(JavaScriptObject wrapper, + JavaScriptObject cell) + /*-{ + wrapper.destory(cell); + }-*/; + + @Override + public boolean onActivate(CellReference<?> cell) { + if (hasOnActivate) { + return onActivate(helper.getConnectorWrapper(), + getJsCell(cell)); + } else { + return super.onActivate(cell); + } + } + + private native boolean onActivate(JavaScriptObject wrapper, + JavaScriptObject cell) + /*-{ + return !!wrapper.onActivate(cell); + }-*/; + + @Override + public Collection<String> getConsumedEvents() { + if (hasGetConsumedEvents) { + JsArrayString events = getConsumedEvents(helper + .getConnectorWrapper()); + + ArrayList<String> list = new ArrayList<String>( + events.length()); + for (int i = 0; i < events.length(); i++) { + list.add(events.get(i)); + } + return list; + } else { + return super.getConsumedEvents(); + } + } + + private native JsArrayString getConsumedEvents( + JavaScriptObject wrapper) + /*-{ + var rawEvents = wrapper.getConsumedEvents(); + var events = []; + for(var i = 0; i < rawEvents.length; i++) { + events[i] = ""+rawEvents[i]; + } + return events; + }-*/; + + @Override + public boolean onBrowserEvent(CellReference<?> cell, + NativeEvent event) { + if (hasOnBrowserEvent) { + return onBrowserEvent(helper.getConnectorWrapper(), + getJsCell(cell), event); + } else { + return super.onBrowserEvent(cell, event); + } + } + + private native boolean onBrowserEvent(JavaScriptObject wrapper, + JavaScriptObject cell, NativeEvent event) + /*-{ + return !!wrapper.onBrowserEvent(cell, event); + }-*/; + }; + } + + @Override + public JsonValue decode(JsonValue value) { + // Let the js logic decode the raw json that the server sent + return value; + } + + @Override + public void onUnregister() { + super.onUnregister(); + helper.onUnregister(); + } + + @Override + public JavaScriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } +} diff --git a/client/src/com/vaadin/client/widget/grid/RendererCellReference.java b/client/src/com/vaadin/client/widget/grid/RendererCellReference.java index 07ca462293..533eafded6 100644 --- a/client/src/com/vaadin/client/widget/grid/RendererCellReference.java +++ b/client/src/com/vaadin/client/widget/grid/RendererCellReference.java @@ -83,7 +83,7 @@ public class RendererCellReference extends CellReference<Object> { * * @return the number of columns that the cell should span */ - public int getColspan() { + public int getColSpan() { return cell.getColSpan(); } } diff --git a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java b/server/src/com/vaadin/server/AbstractJavaScriptExtension.java index e182319c85..e9cf2c5e33 100644 --- a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java +++ b/server/src/com/vaadin/server/AbstractJavaScriptExtension.java @@ -106,8 +106,8 @@ import com.vaadin.ui.JavaScriptFunction; * <li>Java Dates are represented by JavaScript numbers containing the timestamp * </li> * <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li> - * <li>Map<String, ?> in Java is represented by JavaScript object with fields - * corresponding to the map keys.</li> + * <li>Map<String, ?> in Java is represented by JavaScript object with + * fields corresponding to the map keys.</li> * <li>Any other Java Map is represented by a JavaScript array containing two * arrays, the first contains the keys and the second contains the values in the * same order.</li> diff --git a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java index f3cbf47b62..84023555bb 100644 --- a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java +++ b/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java @@ -119,8 +119,8 @@ import com.vaadin.shared.ui.JavaScriptComponentState; * <li>Java Dates are represented by JavaScript numbers containing the timestamp * </li> * <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li> - * <li>Map<String, ?> in Java is represented by JavaScript object with fields - * corresponding to the map keys.</li> + * <li>Map<String, ?> in Java is represented by JavaScript object with + * fields corresponding to the map keys.</li> * <li>Any other Java Map is represented by a JavaScript array containing two * arrays, the first contains the keys and the second contains the values in the * same order.</li> diff --git a/server/src/com/vaadin/ui/renderer/AbstractJavaScriptRenderer.java b/server/src/com/vaadin/ui/renderer/AbstractJavaScriptRenderer.java new file mode 100644 index 0000000000..92c5047279 --- /dev/null +++ b/server/src/com/vaadin/ui/renderer/AbstractJavaScriptRenderer.java @@ -0,0 +1,157 @@ +/* + * 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.ui.renderer; + +import com.vaadin.server.AbstractJavaScriptExtension; +import com.vaadin.server.JavaScriptCallbackHelper; +import com.vaadin.shared.JavaScriptExtensionState; +import com.vaadin.shared.communication.ServerRpc; +import com.vaadin.ui.Grid.AbstractRenderer; +import com.vaadin.ui.JavaScriptFunction; + +/** + * Base class for Renderers with all client-side logic implemented using + * JavaScript. + * <p> + * When a new JavaScript renderer is initialized in the browser, the framework + * will look for a globally defined JavaScript function that will initialize the + * renderer. The name of the initialization function is formed by replacing . + * with _ in the name of the server-side class. If no such function is defined, + * each super class is used in turn until a match is found. The framework will + * thus first attempt with <code>com_example_MyRenderer</code> for the + * server-side + * <code>com.example.MyRenderer extends AbstractJavaScriptRenderer</code> class. + * If MyRenderer instead extends <code>com.example.SuperRenderer</code> , then + * <code>com_example_SuperRenderer</code> will also be attempted if + * <code>com_example_MyRenderer</code> has not been defined. + * <p> + * + * In addition to the general JavaScript extension functionality explained in + * {@link AbstractJavaScriptExtension}, this class also provides some + * functionality specific for renderers. + * <p> + * The initialization function will be called with <code>this</code> pointing to + * a connector wrapper object providing integration to Vaadin with the following + * functions: + * <ul> + * <li><code>getRowKey(rowIndex)</code> - Gets a unique identifier for the row + * at the given index. This identifier can be used on the server to retrieve the + * corresponding ItemId using {@link #getItemId(String)}.</li> + * </ul> + * The connector wrapper also supports these special functions that can be + * implemented by the connector: + * <ul> + * <li><code>render(cell, data)</code> - Callback for rendering the given data + * into the given cell. The structure of cell and data are described in separate + * sections below. The renderer is required to implement this function. + * Corresponds to + * {@link com.vaadin.client.renderers.Renderer#render(com.vaadin.client.widget.grid.RendererCellReference, Object)} + * .</li> + * <li><code>init(cell)</code> - Prepares a cell for rendering. Corresponds to + * {@link com.vaadin.client.renderers.ComplexRenderer#init(com.vaadin.client.widget.grid.RendererCellReference)} + * .</li> + * <li><code>destory(cell)</code> - Allows the renderer to release resources + * allocate for a cell that will no longer be used. Corresponds to + * {@link com.vaadin.client.renderers.ComplexRenderer#destroy(com.vaadin.client.widget.grid.RendererCellReference)} + * .</li> + * <li><code>onActivate(cell)</code> - Called when the cell is activated by the + * user e.g. by double clicking on the cell or pressing enter with the cell + * focused. Corresponds to + * {@link com.vaadin.client.renderers.ComplexRenderer#onActivate(com.vaadin.client.widget.grid.CellReference)} + * .</li> + * <li><code>getConsumedEvents()</code> - Returns a JavaScript array of event + * names that should cause onBrowserEvent to be invoked whenever an event is + * fired for a cell managed by this renderer. Corresponds to + * {@link com.vaadin.client.renderers.ComplexRenderer#getConsumedEvents()}.</li> + * <li><code>onBrowserEvent(cell, event)</code> - Called by Grid when an event + * of a type returned by getConsumedEvents is fired for a cell managed by this + * renderer. Corresponds to + * {@link com.vaadin.client.renderers.ComplexRenderer#onBrowserEvent(com.vaadin.client.widget.grid.CellReference, com.google.gwt.dom.client.NativeEvent)} + * .</li> + * </ul> + * + * <p> + * The cell object passed to functions defined by the renderer has these + * properties: + * <ul> + * <li><code>element</code> - The DOM element corresponding to this cell. + * Readonly.</li> + * <li><code>rowIndex</code> - The current index of the row of this cell. + * Readonly.</li> + * <li><code>columnIndex</code> - The current index of the column of this cell. + * Readonly.</li> + * <li><code>colSpan</code> - The number of columns spanned by this cell. Only + * supported in the object passed to the <code>render</code> function - other + * functions should not use the property. Readable and writable. + * </ul> + * + * @author Vaadin Ltd + * @since + */ +public abstract class AbstractJavaScriptRenderer<T> extends AbstractRenderer<T> { + private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( + this); + + protected AbstractJavaScriptRenderer(Class<T> presentationType) { + super(presentationType); + } + + @Override + protected <R extends ServerRpc> void registerRpc(R implementation, + Class<R> rpcInterfaceType) { + super.registerRpc(implementation, rpcInterfaceType); + callbackHelper.registerRpc(rpcInterfaceType); + } + + /** + * Register a {@link JavaScriptFunction} that can be called from the + * JavaScript using the provided name. A JavaScript function with the + * provided name will be added to the connector wrapper object (initially + * available as <code>this</code>). Calling that JavaScript function will + * cause the call method in the registered {@link JavaScriptFunction} to be + * invoked with the same arguments. + * + * @param functionName + * the name that should be used for client-side callback + * @param function + * the {@link JavaScriptFunction} object that will be invoked + * when the JavaScript function is called + */ + protected void addFunction(String functionName, JavaScriptFunction function) { + callbackHelper.registerCallback(functionName, function); + } + + /** + * Invoke a named function that the connector JavaScript has added to the + * JavaScript connector wrapper object. The arguments should only contain + * data types that can be represented in JavaScript including primitives, + * their boxed types, arrays, String, List, Set, Map, Connector and + * JavaBeans. + * + * @param name + * the name of the function + * @param arguments + * function arguments + */ + protected void callFunction(String name, Object... arguments) { + callbackHelper.invokeCallback(name, arguments); + } + + @Override + protected JavaScriptExtensionState getState() { + return (JavaScriptExtensionState) super.getState(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderers.java b/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderers.java new file mode 100644 index 0000000000..4bfa244c22 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderers.java @@ -0,0 +1,75 @@ +/* + * 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.tests.components.grid; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; + +public class JavaScriptRenderers extends AbstractTestUI { + + public static class MyBean { + private int integer; + private String string; + + public MyBean(int integer, String string) { + super(); + this.integer = integer; + this.string = string; + } + + public int getInteger() { + return integer; + } + + public void setInteger(int integer) { + this.integer = integer; + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + } + + @Override + protected void setup(VaadinRequest request) { + IndexedContainer container = new IndexedContainer(); + container.addContainerProperty("id", Integer.class, Integer.valueOf(0)); + container.addContainerProperty("bean", MyBean.class, null); + + for (int i = 0; i < 1000; i++) { + Integer itemId = Integer.valueOf(i); + Item item = container.addItem(itemId); + item.getItemProperty("id").setValue(itemId); + item.getItemProperty("bean").setValue( + new MyBean(i + 1, Integer.toString(i - 1))); + } + + Grid grid = new Grid(container); + + grid.getColumn("bean").setRenderer(new MyBeanJSRenderer()); + grid.getColumn("bean").setWidth(250); + + addComponent(grid); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderersTest.java b/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderersTest.java new file mode 100644 index 0000000000..a3bb736086 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderersTest.java @@ -0,0 +1,46 @@ +/* + * 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.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class JavaScriptRenderersTest extends MultiBrowserTest { + + @Test + public void testJavaScriptRenderer() { + setDebug(true); + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + GridCellElement cell_1_2 = grid.getCell(1, 2); + + // Verify render functionality + Assert.assertEquals("Bean(2, 0)", cell_1_2.getText()); + + // Verify init functionality + Assert.assertEquals("2", cell_1_2.getAttribute("column")); + + // Verify onbrowserevent + cell_1_2.click(); + Assert.assertTrue(cell_1_2.getText().startsWith( + "Clicked 1 with key 1 at")); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/MyBeanJSRenderer.java b/uitest/src/com/vaadin/tests/components/grid/MyBeanJSRenderer.java new file mode 100644 index 0000000000..ccb94f5d2d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/MyBeanJSRenderer.java @@ -0,0 +1,34 @@ +/* + * 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.tests.components.grid; + +import com.vaadin.annotations.JavaScript; +import com.vaadin.tests.components.grid.JavaScriptRenderers.MyBean; +import com.vaadin.ui.renderer.AbstractJavaScriptRenderer; + +/** + * + * @since + * @author Vaadin Ltd + */ +@JavaScript("myBeanJsRenderer.js") +public class MyBeanJSRenderer extends AbstractJavaScriptRenderer<MyBean> { + + public MyBeanJSRenderer() { + super(MyBean.class); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/myBeanJsRenderer.js b/uitest/src/com/vaadin/tests/components/grid/myBeanJsRenderer.js new file mode 100644 index 0000000000..5e7bde5ec7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/myBeanJsRenderer.js @@ -0,0 +1,16 @@ +window.com_vaadin_tests_components_grid_MyBeanJSRenderer = function() { + this.init = function(cell) { + cell.element.setAttribute("column", cell.columnIndex); + } + + this.render = function(cell, data) { + cell.element.innerHTML = 'Bean(' + data.integer + ', ' + data.string + ')' + } + + this.getConsumedEvents = function() { return ["click"] }; + + this.onBrowserEvent = function(cell, event) { + cell.element.innerHTML = "Clicked " + cell.rowIndex + " with key " + this.getRowKey(cell.rowIndex) +" at " + event.clientX; + return true; + } +}
\ No newline at end of file |