X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=wicket%2Fcomponents%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fwicket%2Fjquery%2FAbstractJQueryBehavior.java;h=cdc72ab8b23629d283ef3bf81f21a8c44c3041fc;hb=HEAD;hp=b1d271346ffe605579333ed8cf7f72bd84cceecc;hpb=e1e84f0c0a30493e856bd2d54807cff237a6a112;p=utils
diff --git a/wicket/components/src/main/java/org/wamblee/wicket/jquery/AbstractJQueryBehavior.java b/wicket/components/src/main/java/org/wamblee/wicket/jquery/AbstractJQueryBehavior.java
index b1d27134..cdc72ab8 100644
--- a/wicket/components/src/main/java/org/wamblee/wicket/jquery/AbstractJQueryBehavior.java
+++ b/wicket/components/src/main/java/org/wamblee/wicket/jquery/AbstractJQueryBehavior.java
@@ -23,19 +23,39 @@ 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:
*
* - Creating a ready function which will be invoked for the component
- * - Checking that the component is not a page
- * - Ensuring tha the markup id of the component is output
- * - Creating a call to an intialization function from the ready handler using the component id
+ * - Checking whether or not the behavior may be attached to a page using
+ * {@link #isPageAllowed()}. By default, the behavior may be attached to
+ * pages. Behaviors that should not be allowed to be attached to pages should
+ * override this method.
+ * - Ensuring that the markup id of the component is output
+ * - Creating a call to an intialization function from the ready handler using
+ * the component id
*
*
+ * The ready function will be invoked as part of a ready handler and will invoke
+ * a function with two arguments. The first is the selector of the component and
+ * the second is a configuration object. In case the behavior is attached to a
+ * component, a selector is used based on the unique markup id. When used on a
+ * page, the selector matches with the "body" of the page.
+ *
+ * The second parameter is obtained through a call to
+ * {@link #getConfigurationJavascript()}.
+ *
+ *
* @author Erik Brakkee
*
+ *
*/
-public class AbstractJQueryBehavior extends CompositeBehavior {
+public class AbstractJQueryBehavior 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 +64,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.
*/
@@ -54,6 +74,15 @@ public class AbstractJQueryBehavior extends CompositeBehavior {
function = aFunction;
}
+ /**
+ * Determines whether the behavior is allowed to be attached toa page.
+ *
+ * @return True.
+ */
+ protected boolean isPageAllowed() {
+ return true;
+ }
+
private static IBehavior[] getBehaviors(IBehavior[] aBehaviors) {
IBehavior[] behaviors = new IBehavior[aBehaviors.length + 1];
behaviors[0] = new JQueryHeaderContributor();
@@ -72,46 +101,110 @@ public class AbstractJQueryBehavior extends CompositeBehavior {
component + ", but component " + aComponent +
" wants to be attached too");
}
- if (aComponent instanceof Page) {
+ if (!isPageAllowed() && aComponent instanceof Page) {
throw new IllegalStateException(
"This behavior cannot be applied to a page: " + aComponent);
}
component = aComponent;
super.bind(aComponent);
- aComponent.setOutputMarkupId(true);
+ if (!(aComponent instanceof Page)) {
+ aComponent.setOutputMarkupId(true);
+ }
}
@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 instanceof Page) && !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 + "(");
+ String selector = "body";
+ if (!(component instanceof Page)) {
+ selector = "#" + component.getMarkupId();
+ }
+ js.append("\"" + selector + "\"");
+ 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()}.
+ *
+ * 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;
+ }
}