You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@click.apache.org by sa...@apache.org on 2010/06/12 11:35:57 UTC
svn commit: r953971 - in /click/trunk/click/framework/src/org/apache/click:
Control.java control/AbstractControl.java control/AbstractLink.java
control/ActionButton.java
Author: sabob
Date: Sat Jun 12 09:35:56 2010
New Revision: 953971
URL: http://svn.apache.org/viewvc?rev=953971&view=rev
Log:
added Ajax support to Control interface. CLK-653
Modified:
click/trunk/click/framework/src/org/apache/click/Control.java
click/trunk/click/framework/src/org/apache/click/control/AbstractControl.java
click/trunk/click/framework/src/org/apache/click/control/AbstractLink.java
click/trunk/click/framework/src/org/apache/click/control/ActionButton.java
Modified: click/trunk/click/framework/src/org/apache/click/Control.java
URL: http://svn.apache.org/viewvc/click/trunk/click/framework/src/org/apache/click/Control.java?rev=953971&r1=953970&r2=953971&view=diff
==============================================================================
--- click/trunk/click/framework/src/org/apache/click/Control.java (original)
+++ click/trunk/click/framework/src/org/apache/click/Control.java Sat Jun 12 09:35:56 2010
@@ -463,4 +463,15 @@ public interface Control extends Seriali
* @param buffer the specified buffer to render the control's output to
*/
public void render(HtmlStringBuffer buffer);
+
+ public boolean hasBehaviors();
+
+ public List<Behavior> getBehaviors();
+
+ // What about setCssSelector?
+ public String getCssSelector();
+
+ // TODO this method could be changed to both check and return the target
+ // behavior
+ public boolean isAjaxTarget(Context context);
}
Modified: click/trunk/click/framework/src/org/apache/click/control/AbstractControl.java
URL: http://svn.apache.org/viewvc/click/trunk/click/framework/src/org/apache/click/control/AbstractControl.java?rev=953971&r1=953970&r2=953971&view=diff
==============================================================================
--- click/trunk/click/framework/src/org/apache/click/control/AbstractControl.java (original)
+++ click/trunk/click/framework/src/org/apache/click/control/AbstractControl.java Sat Jun 12 09:35:56 2010
@@ -34,6 +34,8 @@ import javax.servlet.ServletContext;
import org.apache.click.ActionEventDispatcher;
import org.apache.click.ActionListener;
+import org.apache.click.Behavior;
+import org.apache.click.CallbackDispatcher;
import org.apache.click.Context;
import org.apache.click.Control;
import org.apache.click.Page;
@@ -138,6 +140,9 @@ public abstract class AbstractControl im
/** The control's action listener. */
protected ActionListener actionListener;
+ /** The control's list of {@link org.apache.click.Behavior behaviors}. */
+ protected List<Behavior> behaviors;
+
/**
* The list of page HTML HEAD elements including: Javascript imports,
* Css imports, inline Javascript and inline Css.
@@ -230,6 +235,54 @@ public abstract class AbstractControl im
this.actionListener = listener;
}
+ public boolean hasBehaviors() {
+ return (behaviors != null && behaviors.size() > 0);
+ }
+
+ public void addBehavior(Behavior behavior) {
+ if (getBehaviors().contains(behavior)) {
+ return;
+ }
+
+ getBehaviors().add(behavior);
+
+ // Register control here in case behavior was added *after* the onInit event.
+ // This can occur if the behavior is added in a listener event or during
+ // onRender.
+ CallbackDispatcher.registerBehavior(this);
+ }
+
+ public void removeBehavior(Behavior behavior) {
+ getBehaviors().remove(behavior);
+ }
+
+ public List<Behavior> getBehaviors() {
+ if (behaviors == null) {
+ behaviors = new ArrayList();
+ }
+ return behaviors;
+ }
+
+ public String getCssSelector() {
+ // TODO each control could have an optimized version of cssSelector
+ // targeting specifically that control. For now we just use a generic
+ // utility impl
+ return ClickUtils.getCssSelector(this);
+ }
+
+ public boolean isAjaxTarget(Context context) {
+ // TODO each control could have an optimized version of isAjaxTarget
+ // targeting specifically that control. For now we just check that the
+ // control id is present. Not all controls can use an ID for example:
+ // ActionLink
+ String id = getId();
+ if (id != null) {
+ return context.getRequestParameter(id) != null;
+ } else {
+ return false;
+ }
+ }
+
/**
* Return the control HTML attribute with the given name, or null if the
* attribute does not exist.
@@ -498,12 +551,26 @@ public abstract class AbstractControl im
}
/**
- * This method does nothing. Subclasses may override this method to perform
- * initialization.
+ * If a behavior has been attached to this control, it will be registered
+ * with the {@link org.apache.click.CallbackDispatcher}.
+ * <p/>
+ * <b>Please note:</b> a common problem when overriding onInit in
+ * subclasses is forgetting to call <em>super.onInit()</em>. Consider
+ * carefully whether you should call <em>super.onInit()</em> or not.
*
* @see org.apache.click.Control#onInit()
*/
public void onInit() {
+ // Q: Why does onInit need to register callback instead of addBehavior?
+ // A: Because on stateful pages addBehavior might only be called once
+ // when the control was created so we ensure the behavior is registered
+ // before onProcess
+ // TODO might want to extract the code below into ClickServlet itself
+ // to ensure this code is called *before* onProcess. Leaving the code
+ // here opens problems if subclass does not call super.onInit
+ if (hasBehaviors()) {
+ CallbackDispatcher.registerBehavior(this);
+ }
}
/**
@@ -834,6 +901,10 @@ public abstract class AbstractControl im
if (getActionListener() != null) {
ActionEventDispatcher.dispatchActionEvent(this, getActionListener());
}
+
+ if (hasBehaviors()) {
+ ActionEventDispatcher.dispatchBehavior(this);
+ }
}
/**
Modified: click/trunk/click/framework/src/org/apache/click/control/AbstractLink.java
URL: http://svn.apache.org/viewvc/click/trunk/click/framework/src/org/apache/click/control/AbstractLink.java?rev=953971&r1=953970&r2=953971&view=diff
==============================================================================
--- click/trunk/click/framework/src/org/apache/click/control/AbstractLink.java (original)
+++ click/trunk/click/framework/src/org/apache/click/control/AbstractLink.java Sat Jun 12 09:35:56 2010
@@ -568,6 +568,20 @@ public abstract class AbstractLink exten
this.renderLabelAndImage = renderLabelAndImage;
}
+ @Override
+ public boolean isAjaxTarget(Context context) {
+ String id = getId();
+ if (id != null) {
+ return context.getRequestParameter(id) != null;
+ } else {
+ String name = getName();
+ if (name != null) {
+ return name.equals(context.getRequestParameter(ActionLink.ACTION_LINK));
+ }
+ }
+ return false;
+ }
+
// Public Methods ---------------------------------------------------------
/**
Modified: click/trunk/click/framework/src/org/apache/click/control/ActionButton.java
URL: http://svn.apache.org/viewvc/click/trunk/click/framework/src/org/apache/click/control/ActionButton.java?rev=953971&r1=953970&r2=953971&view=diff
==============================================================================
--- click/trunk/click/framework/src/org/apache/click/control/ActionButton.java (original)
+++ click/trunk/click/framework/src/org/apache/click/control/ActionButton.java Sat Jun 12 09:35:56 2010
@@ -435,6 +435,20 @@ public class ActionButton extends Button
return parameters != null && !parameters.isEmpty();
}
+ @Override
+ public boolean isAjaxTarget(Context context) {
+ String id = getId();
+ if (id != null) {
+ return context.getRequestParameter(id) != null;
+ } else {
+ String name = getName();
+ if (name != null) {
+ return name.equals(context.getRequestParameter(ActionButton.ACTION_BUTTON));
+ }
+ }
+ return false;
+ }
+
/**
* Returns the ActionButton value if the action link was processed and has
* a value, or null otherwise.