added the capability to add an optional configuration
[utils] / wicket / components / src / main / java / org / wamblee / wicket / jquery / AbstractJQueryBehavior.java
index b1d271346ffe605579333ed8cf7f72bd84cceecc..d49110dd3d14e929162d149d2e3ba950abea3b22 100644 (file)
@@ -23,19 +23,33 @@ import org.apache.wicket.behavior.IBehavior;
 import org.apache.wicket.markup.html.IHeaderResponse;
 import org.wamblee.wicket.behavior.CompositeBehavior;
 
+import flexjson.JSONSerializer;
+
 /**
  * Abstract JQuery hehavior class that makes it easy to write jQuery behaviors:
  * <ul>
  * <li>Creating a ready function which will be invoked for the component</li>
  * <li>Checking that the component is not a page</li>
  * <li>Ensuring tha the markup id of the component is output</li>
- * <li>Creating a call to an intialization function from the ready handler using the component id </li>
+ * <li>Creating a call to an intialization function from the ready handler using
+ * the component id</li>
  * </ul>
  * 
+ * The ready function will be invoked as part of a ready handler and will invoke 
+ * a function with two arguments. The first is the id of the component and the second
+ * is a configuration object. 
+ * <p>
+ * The second parameter is obtained through a call to {@link #getConfigurationJavascript()}.
+ * 
+ * 
  * @author Erik Brakkee
  * 
+ * <ConfigType> 
  */
-public class AbstractJQueryBehavior extends CompositeBehavior {
+public class AbstractJQueryBehavior<ConfigType> extends CompositeBehavior {
+
+    private static final String DEFAULT_NAMESPACE = "org.wamblee";
+    private static JSONSerializer DEFAULT_JSON_SERIALIZER = new JSONSerializer();
 
     private Component component;
     private String function;
@@ -44,8 +58,8 @@ public class AbstractJQueryBehavior extends CompositeBehavior {
      * Constructs the behavior.
      * 
      * @param aFunction
-     *            Function to be invoked from the ready handler. This function is invoked with a 
-     *            CSS selector that identifies the component.
+     *            Function to be invoked from the ready handler. This function
+     *            is invoked with a CSS selector that identifies the component.
      * @param aBehaviors
      *            Behaviors to add in addition to the basic JQuery stuff.
      */
@@ -84,34 +98,92 @@ public class AbstractJQueryBehavior extends CompositeBehavior {
     @Override
     public void renderHead(IHeaderResponse aResponse) {
         super.renderHead(aResponse);
-        String jsString = createReadyFunction(function, component);
+        String jsString = createReadyFunction();
         aResponse.renderJavascript(jsString, null);
     }
 
     /**
      * Creates a jQuery ready handler that invokes a given javascript function
-     * with the id of a component.
+     * with the id of a component and with a second parameter of parameters to
+     * pass additional information to the function.
      * 
      * @param aFunction
-     *            Javascript function to invoke.
+     *            Javascript function to invoke, the name of this function must
+     *            include the namespace as it is called from a global scope.
      * @param aComponent
      *            Component to invoke the id for.
      * @return
      */
-    public static String createReadyFunction(String aFunction,
-        Component aComponent) {
-        if (!aComponent.getOutputMarkupId()) {
+    String createReadyFunction() {
+        if (!component.getOutputMarkupId()) {
             throw new IllegalStateException(
                 "The component " +
-                    aComponent +
+                    component +
                     " does not have its markup id set so this ready handler will not have any effect");
         }
         StringBuffer js = new StringBuffer();
         js.append("jQuery(function(){");
-        js.append("org.wamblee." + aFunction + "(\"#" +
-            aComponent.getMarkupId() + "\");");
+        js.append(function + "(");
+        js.append("\"#" + component.getMarkupId() + "\"");
+        String config = getConfigurationJavascript();
+        if (config != null) {
+            js.append(",");
+            js.append(config);
+        }
+        js.append(");");
         js.append("});");
         String jsString = js.toString();
         return jsString;
     }
+
+    /**
+     * Returns a javascript object that is passed as second argument to the
+     * ready function. This method uses {@link #getConfigurationObject()} to
+     * obtain the configuration object to use which is then serialized to
+     * javascript using {@link JSONSerializer}. Subclasses can override the
+     * default JSONSerializer by implementing {@link #getCustomSerializer()}.
+     * <p>
+     * Subclasses should override this method to perform custom serialization.
+     * 
+     * @return Configuration object in javascript.
+     */
+    protected String getConfigurationJavascript() {
+        Object config = getConfigurationObject();
+        return getActualSerializer().serialize(config);
+    }
+
+    /**
+     * Gets the actual serializer to use. It uses {@link #getCustomSerializer()}
+     * to check if there is a custom serializer available.
+     * 
+     * @return Serializer.
+     */
+    private JSONSerializer getActualSerializer() {
+        JSONSerializer serializer = getCustomSerializer();
+        if (serializer != null) {
+            return serializer;
+        }
+        return DEFAULT_JSON_SERIALIZER;
+    }
+
+    /**
+     * Returns the serializer to use. Implementations can override this method
+     * to perform custom initialization of the serializer knowing the type of
+     * configuration object to use.
+     * 
+     * @return Custom serializer to use.
+     */
+    protected JSONSerializer getCustomSerializer() {
+        return null;
+    }
+
+    /**
+     * Gets the configuration object to use. This is transformed to JSON using
+     * the serializer.
+     * 
+     * @return Configuration object.
+     */
+    protected ConfigType getConfigurationObject() {
+        return null;
+    }
 }