You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractJavaScriptRenderer.java 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.ui.renderers;
  17. import com.vaadin.server.AbstractJavaScriptExtension;
  18. import com.vaadin.server.JavaScriptCallbackHelper;
  19. import com.vaadin.server.JsonCodec;
  20. import com.vaadin.shared.JavaScriptExtensionState;
  21. import com.vaadin.shared.communication.ServerRpc;
  22. import com.vaadin.ui.JavaScriptFunction;
  23. import com.vaadin.ui.LegacyGrid.AbstractRenderer;
  24. import elemental.json.Json;
  25. import elemental.json.JsonValue;
  26. /**
  27. * Base class for Renderers with all client-side logic implemented using
  28. * JavaScript.
  29. * <p>
  30. * When a new JavaScript renderer is initialized in the browser, the framework
  31. * will look for a globally defined JavaScript function that will initialize the
  32. * renderer. The name of the initialization function is formed by replacing .
  33. * with _ in the name of the server-side class. If no such function is defined,
  34. * each super class is used in turn until a match is found. The framework will
  35. * thus first attempt with <code>com_example_MyRenderer</code> for the
  36. * server-side
  37. * <code>com.example.MyRenderer extends AbstractJavaScriptRenderer</code> class.
  38. * If MyRenderer instead extends <code>com.example.SuperRenderer</code> , then
  39. * <code>com_example_SuperRenderer</code> will also be attempted if
  40. * <code>com_example_MyRenderer</code> has not been defined.
  41. * <p>
  42. *
  43. * In addition to the general JavaScript extension functionality explained in
  44. * {@link AbstractJavaScriptExtension}, this class also provides some
  45. * functionality specific for renderers.
  46. * <p>
  47. * The initialization function will be called with <code>this</code> pointing to
  48. * a connector wrapper object providing integration to Vaadin. Please note that
  49. * in JavaScript, <code>this</code> is not necessarily defined inside callback
  50. * functions and it might therefore be necessary to assign the reference to a
  51. * separate variable, e.g. <code>var self = this;</code>. In addition to the
  52. * extension functions described for {@link AbstractJavaScriptExtension}, the
  53. * connector wrapper object also provides this function:
  54. * <ul>
  55. * <li><code>getRowKey(rowIndex)</code> - Gets a unique identifier for the row
  56. * at the given index. This identifier can be used on the server to retrieve the
  57. * corresponding ItemId using {@link #getItemId(String)}.</li>
  58. * </ul>
  59. * The connector wrapper also supports these special functions that can be
  60. * implemented by the connector:
  61. * <ul>
  62. * <li><code>render(cell, data)</code> - Callback for rendering the given data
  63. * into the given cell. The structure of cell and data are described in separate
  64. * sections below. The renderer is required to implement this function.
  65. * Corresponds to
  66. * {@link com.vaadin.client.renderers.Renderer#render(com.vaadin.client.widget.grid.RendererCellReference, Object)}
  67. * .</li>
  68. * <li><code>init(cell)</code> - Prepares a cell for rendering. Corresponds to
  69. * {@link com.vaadin.client.renderers.ComplexRenderer#init(com.vaadin.client.widget.grid.RendererCellReference)}
  70. * .</li>
  71. * <li><code>destory(cell)</code> - Allows the renderer to release resources
  72. * allocate for a cell that will no longer be used. Corresponds to
  73. * {@link com.vaadin.client.renderers.ComplexRenderer#destroy(com.vaadin.client.widget.grid.RendererCellReference)}
  74. * .</li>
  75. * <li><code>onActivate(cell)</code> - Called when the cell is activated by the
  76. * user e.g. by double clicking on the cell or pressing enter with the cell
  77. * focused. Corresponds to
  78. * {@link com.vaadin.client.renderers.ComplexRenderer#onActivate(com.vaadin.client.widget.grid.CellReference)}
  79. * .</li>
  80. * <li><code>getConsumedEvents()</code> - Returns a JavaScript array of event
  81. * names that should cause onBrowserEvent to be invoked whenever an event is
  82. * fired for a cell managed by this renderer. Corresponds to
  83. * {@link com.vaadin.client.renderers.ComplexRenderer#getConsumedEvents()}.</li>
  84. * <li><code>onBrowserEvent(cell, event)</code> - Called by Grid when an event
  85. * of a type returned by getConsumedEvents is fired for a cell managed by this
  86. * renderer. Corresponds to
  87. * {@link com.vaadin.client.renderers.ComplexRenderer#onBrowserEvent(com.vaadin.client.widget.grid.CellReference, com.google.gwt.dom.client.NativeEvent)}
  88. * .</li>
  89. * </ul>
  90. *
  91. * <p>
  92. * The cell object passed to functions defined by the renderer has these
  93. * properties:
  94. * <ul>
  95. * <li><code>element</code> - The DOM element corresponding to this cell.
  96. * Readonly.</li>
  97. * <li><code>rowIndex</code> - The current index of the row of this cell.
  98. * Readonly.</li>
  99. * <li><code>columnIndex</code> - The current index of the column of this cell.
  100. * Readonly.</li>
  101. * <li><code>colSpan</code> - The number of columns spanned by this cell. Only
  102. * supported in the object passed to the <code>render</code> function - other
  103. * functions should not use the property. Readable and writable.
  104. * </ul>
  105. *
  106. * @author Vaadin Ltd
  107. * @since 7.4
  108. */
  109. public abstract class AbstractJavaScriptRenderer<T>
  110. extends AbstractRenderer<T> {
  111. private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper(
  112. this);
  113. protected AbstractJavaScriptRenderer(Class<T> presentationType,
  114. String nullRepresentation) {
  115. super(presentationType, nullRepresentation);
  116. }
  117. protected AbstractJavaScriptRenderer(Class<T> presentationType) {
  118. super(presentationType, null);
  119. }
  120. @Override
  121. protected <R extends ServerRpc> void registerRpc(R implementation,
  122. Class<R> rpcInterfaceType) {
  123. super.registerRpc(implementation, rpcInterfaceType);
  124. callbackHelper.registerRpc(rpcInterfaceType);
  125. }
  126. /**
  127. * Register a {@link JavaScriptFunction} that can be called from the
  128. * JavaScript using the provided name. A JavaScript function with the
  129. * provided name will be added to the connector wrapper object (initially
  130. * available as <code>this</code>). Calling that JavaScript function will
  131. * cause the call method in the registered {@link JavaScriptFunction} to be
  132. * invoked with the same arguments.
  133. *
  134. * @param functionName
  135. * the name that should be used for client-side callback
  136. * @param function
  137. * the {@link JavaScriptFunction} object that will be invoked
  138. * when the JavaScript function is called
  139. */
  140. protected void addFunction(String functionName,
  141. JavaScriptFunction function) {
  142. callbackHelper.registerCallback(functionName, function);
  143. }
  144. /**
  145. * Invoke a named function that the connector JavaScript has added to the
  146. * JavaScript connector wrapper object. The arguments can be any boxed
  147. * primitive type, String, {@link JsonValue} or arrays of any other
  148. * supported type. Complex types (e.g. List, Set, Map, Connector or any
  149. * JavaBean type) must be explicitly serialized to a {@link JsonValue}
  150. * before sending. This can be done either with
  151. * {@link JsonCodec#encode(Object, JsonValue, java.lang.reflect.Type, com.vaadin.ui.ConnectorTracker)}
  152. * or using the factory methods in {@link Json}.
  153. *
  154. * @param name
  155. * the name of the function
  156. * @param arguments
  157. * function arguments
  158. */
  159. protected void callFunction(String name, Object... arguments) {
  160. callbackHelper.invokeCallback(name, arguments);
  161. }
  162. @Override
  163. protected JavaScriptExtensionState getState() {
  164. return (JavaScriptExtensionState) super.getState();
  165. }
  166. }