import org.apache.wicket.markup.html.IHeaderResponse;
import org.wamblee.wicket.behavior.CompositeBehavior;
+import flexjson.JSONSerializer;
+
/**
- * Abstract JQuery hehavior class that performs some useful basic behaviors for
- * the behavior such as:
+ * 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>Creating a call to an intialization function from the ready handler using the component id </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>
* </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;
* Constructs the behavior.
*
* @param aFunction
- * Ready function to be invoked.
+ * 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.
*/
@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;
+ }
}