You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2013/11/09 07:49:11 UTC
git commit: WICKET-5411 auto label auto update during ajax
Updated Branches:
refs/heads/wicket-6.x 4e9a83fdc -> a73209bea
WICKET-5411 auto label auto update during ajax
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/a73209be
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/a73209be
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/a73209be
Branch: refs/heads/wicket-6.x
Commit: a73209beab8814a06f2e085384ad87bdf1fda212
Parents: 4e9a83f
Author: Igor Vaynberg <ig...@gmail.com>
Authored: Fri Nov 8 22:48:22 2013 -0800
Committer: Igor Vaynberg <ig...@gmail.com>
Committed: Fri Nov 8 22:48:22 2013 -0800
----------------------------------------------------------------------
.../form/AjaxFormComponentUpdatingBehavior.java | 2 +-
.../wicket/core/util/string/CssUtils.java | 14 ++
.../markup/html/form/AutoLabelResolver.java | 130 ++++++++++++++++++-
.../apache/wicket/markup/html/form/Form.java | 24 +++-
.../wicket/markup/html/form/FormComponent.java | 34 ++++-
.../wicket/protocol/http/WebApplication.java | 36 +++--
6 files changed, 212 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
index 7eab478..bd8267c 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
@@ -160,8 +160,8 @@ public abstract class AjaxFormComponentUpdatingBehavior extends AjaxEventBehavio
catch (RuntimeException e)
{
onError(target, e);
-
}
+ formComponent.updateAutoLabels(target);
}
/**
http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
index a4944a3..7de8669 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
@@ -103,4 +103,18 @@ public final class CssUtils
}
response.write(" />");
}
+
+ /**
+ * Get a standardized key for a CSS class.
+ *
+ * @param scope
+ * scope of CSS class
+ * @param facet
+ * facet of CSS class
+ * @return CSS key
+ */
+ public static String key(Class<?> scope, String facet)
+ {
+ return scope.getSimpleName() + ".CSS." + facet;
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
index 562e6ed..7892fa7 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
@@ -16,9 +16,14 @@
*/
package org.apache.wicket.markup.html.form;
+import java.io.Serializable;
+
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.MetaDataKey;
import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.core.util.string.CssUtils;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.TransparentWebMarkupContainer;
@@ -36,11 +41,14 @@ import org.slf4j.LoggerFactory;
* <li>Outputs the {@code for} attribute with the value equivalent to the markup id of the
* referenced form component</li>
* <li>Appends {@code required} css class to the {@code <label>} tag if the referenced form
- * component is required</li>
+ * component is required. Name of the css class can be overwritten by having a i18n property defined
+ * for key AutoLabelResolver.CSS.required</li>
* <li>Appends {@code error} css class to the {@code <label>} tag if the referenced form component
- * has failed validation</li>
+ * has failed validation. Name of the css class can be overwritten by having a i18n property defined
+ * for key AutoLabelResolver.CSS.error</li>
* <li>Appends {@code disabled} css class to the {@code <label>} tag if the referenced form
- * component has is not enabled in hierarchy</li>
+ * component has is not enabled in hierarchy. Name of the css class can be overwritten by having a i18n property defined
+ * for key AutoLabelResolver.CSS.disabled</li>
* </ul>
*
* <p>
@@ -64,6 +72,14 @@ public class AutoLabelResolver implements IComponentResolver
static final String WICKET_FOR = ":for";
+ public static final String CSS_REQUIRED_KEY = CssUtils.key(AutoLabelResolver.class, "requried");
+ public static final String CSS_DISABLED_KEY = CssUtils.key(AutoLabelResolver.class, "requried");
+ public static final String CSS_ERROR_KEY = CssUtils.key(AutoLabelResolver.class, "requried");
+ private static final String CSS_DISABLED_DEFAULT = "disabled";
+ private static final String CSS_REQUIRED_DEFAULT = "required";
+ private static final String CSS_ERROR_DEFAULT = "error";
+
+
@Override
public Component resolve(final MarkupContainer container, final MarkupStream markupStream,
final ComponentTag tag)
@@ -99,6 +115,11 @@ public class AutoLabelResolver implements IComponentResolver
}
}
+ if (component instanceof FormComponent)
+ {
+ component.setMetaData(MARKER_KEY, new AutoLabelMarker((FormComponent<?>)component));
+ }
+
return new AutoLabel("label" + container.getPage().getAutoIndex(), component);
}
@@ -161,6 +182,100 @@ public class AutoLabelResolver implements IComponentResolver
return null;
}
+ public static final String getLabelIdFor(Component component)
+ {
+ return component.getMarkupId() + "-w-lbl";
+ }
+
+ public static final MetaDataKey<AutoLabelMarker> MARKER_KEY = new MetaDataKey<AutoLabelMarker>()
+ {
+ };
+
+ /**
+ * Marker used to track whether or not a form component has an associated auto label by its mere
+ * presense as well as some attributes of the component across requests.
+ *
+ * @author igor
+ *
+ */
+ public static final class AutoLabelMarker implements Serializable
+ {
+ public static final short VALID = 0x01;
+ public static final short REQUIRED = 0x02;
+ public static final short ENABLED = 0x04;
+
+ private short flags;
+
+ public AutoLabelMarker(FormComponent<?> component)
+ {
+ setFlag(VALID, component.isValid());
+ setFlag(REQUIRED, component.isRequired());
+ setFlag(ENABLED, component.isEnabledInHierarchy());
+ }
+
+ public void updateFrom(FormComponent<?> component, AjaxRequestTarget target)
+ {
+ boolean valid = component.isValid(), required = component.isRequired(), enabled = component.isEnabledInHierarchy();
+
+ if (isValid() != valid)
+ {
+ target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
+ getLabelIdFor(component), component.getString(CSS_ERROR_KEY, null, CSS_ERROR_DEFAULT),
+ !valid));
+ }
+
+ if (isRequired() != required)
+ {
+ target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
+ getLabelIdFor(component), component.getString(CSS_REQUIRED_KEY, null, CSS_REQUIRED_DEFAULT),
+ required));
+ }
+
+ if (isEnabled() != enabled)
+ {
+ target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
+ getLabelIdFor(component), component.getString(CSS_DISABLED_KEY, null, CSS_DISABLED_DEFAULT),
+ !enabled));
+ }
+
+ setFlag(VALID, valid);
+ setFlag(REQUIRED, required);
+ setFlag(ENABLED, enabled);
+ }
+
+ public boolean isValid()
+ {
+ return getFlag(VALID);
+ }
+
+ public boolean isEnabled()
+ {
+ return getFlag(ENABLED);
+ }
+
+ public boolean isRequired()
+ {
+ return getFlag(REQUIRED);
+ }
+
+ private boolean getFlag(final int flag)
+ {
+ return (flags & flag) != 0;
+ }
+
+ private void setFlag(final short flag, final boolean set)
+ {
+ if (set)
+ {
+ flags |= flag;
+ }
+ else
+ {
+ flags &= ~flag;
+ }
+ }
+ }
+
/**
* Component that is attached to the {@code <label>} tag and takes care of writing out the label
* text as well as setting classes on the {@code <label>} tag
@@ -184,23 +299,24 @@ public class AutoLabelResolver implements IComponentResolver
{
super.onComponentTag(tag);
tag.put("for", component.getMarkupId());
+ tag.put("id", getLabelIdFor(component));
if (component instanceof FormComponent)
{
FormComponent<?> fc = (FormComponent<?>)component;
if (fc.isRequired())
{
- tag.append("class", "required", " ");
+ tag.append("class", component.getString(CSS_REQUIRED_KEY, null, CSS_REQUIRED_DEFAULT), " ");
}
if (!fc.isValid())
{
- tag.append("class", "error", " ");
+ tag.append("class", component.getString(CSS_ERROR_KEY, null, CSS_ERROR_DEFAULT), " ");
}
}
if (!component.isEnabledInHierarchy())
{
- tag.append("class", "disabled", " ");
+ tag.append("class", component.getString(CSS_DISABLED_KEY, null, CSS_DISABLED_DEFAULT), " ");
}
}
@@ -213,4 +329,6 @@ public class AutoLabelResolver implements IComponentResolver
return component;
}
}
+
+
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
index a7f07f3..a9ea6a6 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
@@ -30,6 +30,7 @@ import org.apache.wicket.Component;
import org.apache.wicket.IGenericComponent;
import org.apache.wicket.Page;
import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
@@ -144,10 +145,8 @@ import org.slf4j.LoggerFactory;
* @param <T>
* The model object type
*/
-public class Form<T> extends WebMarkupContainer
- implements
- IFormSubmitListener,
- IGenericComponent<T>
+public class Form<T> extends WebMarkupContainer implements IFormSubmitListener,
+ IGenericComponent<T>
{
private static final String HIDDEN_DIV_START = "<div style=\"width:0px;height:0px;position:absolute;left:-100px;top:-100px;overflow:hidden\">";
@@ -778,6 +777,20 @@ public class Form<T> extends WebMarkupContainer
{
callOnError(submitter);
}
+
+
+ if (((WebRequest)getRequest()).isAjax())
+ {
+ final AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
+ visitChildren(FormComponent.class, new IVisitor<FormComponent<?>, Void>()
+ {
+ @Override
+ public void component(FormComponent<?> component, IVisit<Void> visit)
+ {
+ component.updateAutoLabels(target);
+ }
+ });
+ }
}
/**
@@ -2089,7 +2102,8 @@ public class Form<T> extends WebMarkupContainer
*
* @author igor
*/
- public static enum MethodMismatchResponse {
+ public static enum MethodMismatchResponse
+ {
/**
* Continue processing.
*/
http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
index 450b6bd..e4b89ed 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
@@ -36,12 +36,15 @@ import org.apache.wicket.IConverterLocator;
import org.apache.wicket.IGenericComponent;
import org.apache.wicket.Localizer;
import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.core.util.lang.WicketObjects;
import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.form.AutoLabelResolver.AutoLabelMarker;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.IPropertyReflectionAwareModel;
import org.apache.wicket.model.Model;
+import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.util.convert.ConversionException;
import org.apache.wicket.util.convert.IConverter;
import org.apache.wicket.util.lang.Args;
@@ -98,11 +101,8 @@ import org.slf4j.LoggerFactory;
* The model object type
*
*/
-public abstract class FormComponent<T> extends LabeledWebMarkupContainer
- implements
- IFormVisitorParticipant,
- IFormModelUpdateListener,
- IGenericComponent<T>
+public abstract class FormComponent<T> extends LabeledWebMarkupContainer implements
+ IFormVisitorParticipant, IFormModelUpdateListener, IGenericComponent<T>
{
private static final Logger logger = LoggerFactory.getLogger(FormComponent.class);
@@ -1579,6 +1579,30 @@ public abstract class FormComponent<T> extends LabeledWebMarkupContainer
}
/**
+ * Updates auto label css classes such as error/required during ajax updates when the labels may
+ * not be directly repainted in the response.
+ *
+ * @param target
+ */
+ public final void updateAutoLabels(AjaxRequestTarget target)
+ {
+ if (!((WebApplication)getApplication()).getUpdateAutoLabelsOnAjaxRequests())
+ {
+ return;
+ }
+
+ AutoLabelMarker marker = getMetaData(AutoLabelResolver.MARKER_KEY);
+
+ if (marker == null)
+ {
+ // this component does not have an auto label
+ return;
+ }
+
+ marker.updateFrom(this, target);
+ }
+
+ /**
* Update the model of a {@link FormComponent} containing a {@link Collection}.
*
* If the model object does not yet exists, a new {@link ArrayList} is filled with the converted
http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
index ba69791..22bbfda 100644
--- a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
+++ b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
@@ -394,10 +394,10 @@ public abstract class WebApplication extends Application
/**
* Registers a replacement resource for the given javascript resource. This replacement can be
* another {@link JavaScriptResourceReference} for a packaged resource, but it can also be an
- * {@link org.apache.wicket.request.resource.UrlResourceReference} to replace the resource by a resource hosted on a CDN.
- * Registering a replacement will cause the resource to replaced by the given resource
- * throughout the application: if {@code base} is added, {@code replacement} will be added
- * instead.
+ * {@link org.apache.wicket.request.resource.UrlResourceReference} to replace the resource by a
+ * resource hosted on a CDN. Registering a replacement will cause the resource to replaced by
+ * the given resource throughout the application: if {@code base} is added, {@code replacement}
+ * will be added instead.
*
* @param base
* The resource to replace
@@ -415,10 +415,10 @@ public abstract class WebApplication extends Application
/**
* Registers a replacement resource for the given CSS resource. This replacement can be another
* {@link CssResourceReference} for a packaged resource, but it can also be an
- * {@link org.apache.wicket.request.resource.UrlResourceReference} to replace the resource by a resource hosted on a CDN.
- * Registering a replacement will cause the resource to replaced by the given resource
- * throughout the application: if {@code base} is added, {@code replacement} will be added
- * instead.
+ * {@link org.apache.wicket.request.resource.UrlResourceReference} to replace the resource by a
+ * resource hosted on a CDN. Registering a replacement will cause the resource to replaced by
+ * the given resource throughout the application: if {@code base} is added, {@code replacement}
+ * will be added instead.
*
* @param base
* The resource to replace
@@ -951,9 +951,8 @@ public abstract class WebApplication extends Application
return ajaxRequestTargetListeners;
}
- private static class DefaultAjaxRequestTargetProvider
- implements
- IContextProvider<AjaxRequestTarget, Page>
+ private static class DefaultAjaxRequestTargetProvider implements
+ IContextProvider<AjaxRequestTarget, Page>
{
@Override
public AjaxRequestTarget get(Page page)
@@ -981,4 +980,19 @@ public abstract class WebApplication extends Application
}
return filterFactoryManager;
}
+
+ /**
+ * If true, auto label css classes such as {@code error} and {@code required} will be updated
+ * after form component processing during an ajax request. This allows auto labels to correctly
+ * reflect the state of the form component even if they are not part of the ajax markup update.
+ *
+ * TODO in wicket-7 this should move into a settings object. cannot move in 6.x because it
+ * requires a change to a setting interface.
+ *
+ * @return {@code true} iff enabled
+ */
+ public boolean getUpdateAutoLabelsOnAjaxRequests()
+ {
+ return true;
+ }
}
Re: git commit: WICKET-5411 auto label auto update during ajax
Posted by Martin Grigorov <mg...@apache.org>.
I am not aware of any other impl but having such JS bits in the Java code
would make it hard for any such attempt in the future.
For example jQuery#extend is Wicket#bind.
I suggest to have Wicket.Dom.toggleClass.
I will redo it soon unless there are objections.
On Sun, Nov 10, 2013 at 1:43 AM, Igor Vaynberg <ig...@gmail.com>wrote:
> i suppose that bit of js can be rewritten to use pure dom, but has
> anyone actually ever implemented wicket-event.js and wicket-ajax.js
> using anything other then jquery?
>
> -igor
>
> On Sat, Nov 9, 2013 at 1:34 PM, Martin Grigorov <mg...@apache.org>
> wrote:
> > On Sat, Nov 9, 2013 at 8:49 AM, <iv...@apache.org> wrote:
> >
> >> Updated Branches:
> >> refs/heads/wicket-6.x 4e9a83fdc -> a73209bea
> >>
> >>
> >> WICKET-5411 auto label auto update during ajax
> >>
> >>
> >> Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
> >> Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/a73209be
> >> Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/a73209be
> >> Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/a73209be
> >>
> >> Branch: refs/heads/wicket-6.x
> >> Commit: a73209beab8814a06f2e085384ad87bdf1fda212
> >> Parents: 4e9a83f
> >> Author: Igor Vaynberg <ig...@gmail.com>
> >> Authored: Fri Nov 8 22:48:22 2013 -0800
> >> Committer: Igor Vaynberg <ig...@gmail.com>
> >> Committed: Fri Nov 8 22:48:22 2013 -0800
> >>
> >> ----------------------------------------------------------------------
> >> .../form/AjaxFormComponentUpdatingBehavior.java | 2 +-
> >> .../wicket/core/util/string/CssUtils.java | 14 ++
> >> .../markup/html/form/AutoLabelResolver.java | 130
> ++++++++++++++++++-
> >> .../apache/wicket/markup/html/form/Form.java | 24 +++-
> >> .../wicket/markup/html/form/FormComponent.java | 34 ++++-
> >> .../wicket/protocol/http/WebApplication.java | 36 +++--
> >> 6 files changed, 212 insertions(+), 28 deletions(-)
> >> ----------------------------------------------------------------------
> >>
> >>
> >>
> >>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> >> ----------------------------------------------------------------------
> >> diff --git
> >>
> a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> >>
> b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> >> index 7eab478..bd8267c 100644
> >> ---
> >>
> a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> >> +++
> >>
> b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> >> @@ -160,8 +160,8 @@ public abstract class
> >> AjaxFormComponentUpdatingBehavior extends AjaxEventBehavio
> >> catch (RuntimeException e)
> >> {
> >> onError(target, e);
> >> -
> >> }
> >> + formComponent.updateAutoLabels(target);
> >> }
> >>
> >> /**
> >>
> >>
> >>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> >> ----------------------------------------------------------------------
> >> diff --git
> >>
> a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> >>
> b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> >> index a4944a3..7de8669 100644
> >> ---
> >>
> a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> >> +++
> >>
> b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> >> @@ -103,4 +103,18 @@ public final class CssUtils
> >> }
> >> response.write(" />");
> >> }
> >> +
> >> + /**
> >> + * Get a standardized key for a CSS class.
> >> + *
> >> + * @param scope
> >> + * scope of CSS class
> >> + * @param facet
> >> + * facet of CSS class
> >> + * @return CSS key
> >> + */
> >> + public static String key(Class<?> scope, String facet)
> >> + {
> >> + return scope.getSimpleName() + ".CSS." + facet;
> >> + }
> >> }
> >>
> >>
> >>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> >> ----------------------------------------------------------------------
> >> diff --git
> >>
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> >>
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> >> index 562e6ed..7892fa7 100644
> >> ---
> >>
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> >> +++
> >>
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> >> @@ -16,9 +16,14 @@
> >> */
> >> package org.apache.wicket.markup.html.form;
> >>
> >> +import java.io.Serializable;
> >> +
> >> import org.apache.wicket.Component;
> >> import org.apache.wicket.MarkupContainer;
> >> +import org.apache.wicket.MetaDataKey;
> >> import org.apache.wicket.WicketRuntimeException;
> >> +import org.apache.wicket.ajax.AjaxRequestTarget;
> >> +import org.apache.wicket.core.util.string.CssUtils;
> >> import org.apache.wicket.markup.ComponentTag;
> >> import org.apache.wicket.markup.MarkupStream;
> >> import org.apache.wicket.markup.html.TransparentWebMarkupContainer;
> >> @@ -36,11 +41,14 @@ import org.slf4j.LoggerFactory;
> >> * <li>Outputs the {@code for} attribute with the value equivalent to
> the
> >> markup id of the
> >> * referenced form component</li>
> >> * <li>Appends {@code required} css class to the {@code <label>} tag if
> >> the referenced form
> >> - * component is required</li>
> >> + * component is required. Name of the css class can be overwritten by
> >> having a i18n property defined
> >> + * for key AutoLabelResolver.CSS.required</li>
> >> * <li>Appends {@code error} css class to the {@code <label>} tag if
> the
> >> referenced form component
> >> - * has failed validation</li>
> >> + * has failed validation. Name of the css class can be overwritten by
> >> having a i18n property defined
> >> + * for key AutoLabelResolver.CSS.error</li>
> >> * <li>Appends {@code disabled} css class to the {@code <label>} tag if
> >> the referenced form
> >> - * component has is not enabled in hierarchy</li>
> >> + * component has is not enabled in hierarchy. Name of the css class can
> >> be overwritten by having a i18n property defined
> >> + * for key AutoLabelResolver.CSS.disabled</li>
> >> * </ul>
> >> *
> >> * <p>
> >> @@ -64,6 +72,14 @@ public class AutoLabelResolver implements
> >> IComponentResolver
> >>
> >> static final String WICKET_FOR = ":for";
> >>
> >> + public static final String CSS_REQUIRED_KEY =
> >> CssUtils.key(AutoLabelResolver.class, "requried");
> >> + public static final String CSS_DISABLED_KEY =
> >> CssUtils.key(AutoLabelResolver.class, "requried");
> >> + public static final String CSS_ERROR_KEY =
> >> CssUtils.key(AutoLabelResolver.class, "requried");
> >> + private static final String CSS_DISABLED_DEFAULT = "disabled";
> >> + private static final String CSS_REQUIRED_DEFAULT = "required";
> >> + private static final String CSS_ERROR_DEFAULT = "error";
> >> +
> >> +
> >> @Override
> >> public Component resolve(final MarkupContainer container, final
> >> MarkupStream markupStream,
> >> final ComponentTag tag)
> >> @@ -99,6 +115,11 @@ public class AutoLabelResolver implements
> >> IComponentResolver
> >> }
> >> }
> >>
> >> + if (component instanceof FormComponent)
> >> + {
> >> + component.setMetaData(MARKER_KEY, new
> >> AutoLabelMarker((FormComponent<?>)component));
> >> + }
> >> +
> >> return new AutoLabel("label" +
> >> container.getPage().getAutoIndex(), component);
> >> }
> >>
> >> @@ -161,6 +182,100 @@ public class AutoLabelResolver implements
> >> IComponentResolver
> >> return null;
> >> }
> >>
> >> + public static final String getLabelIdFor(Component component)
> >> + {
> >> + return component.getMarkupId() + "-w-lbl";
> >> + }
> >> +
> >> + public static final MetaDataKey<AutoLabelMarker> MARKER_KEY =
> new
> >> MetaDataKey<AutoLabelMarker>()
> >> + {
> >> + };
> >> +
> >> + /**
> >> + * Marker used to track whether or not a form component has an
> >> associated auto label by its mere
> >> + * presense as well as some attributes of the component across
> >> requests.
> >> + *
> >> + * @author igor
> >> + *
> >> + */
> >> + public static final class AutoLabelMarker implements
> Serializable
> >> + {
> >> + public static final short VALID = 0x01;
> >> + public static final short REQUIRED = 0x02;
> >> + public static final short ENABLED = 0x04;
> >> +
> >> + private short flags;
> >> +
> >> + public AutoLabelMarker(FormComponent<?> component)
> >> + {
> >> + setFlag(VALID, component.isValid());
> >> + setFlag(REQUIRED, component.isRequired());
> >> + setFlag(ENABLED,
> component.isEnabledInHierarchy());
> >> + }
> >> +
> >> + public void updateFrom(FormComponent<?> component,
> >> AjaxRequestTarget target)
> >> + {
> >> + boolean valid = component.isValid(), required =
> >> component.isRequired(), enabled = component.isEnabledInHierarchy();
> >> +
> >> + if (isValid() != valid)
> >> + {
> >> +
> >> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
> >>
> >
> > Until now we haven't used jQuery APIs directly in the Java code.
> > This makes it harder to use different impl of wicket-event/ajax js.
> >
> >
> >> + getLabelIdFor(component),
> >> component.getString(CSS_ERROR_KEY, null, CSS_ERROR_DEFAULT),
> >> + !valid));
> >> + }
> >> +
> >> + if (isRequired() != required)
> >> + {
> >> +
> >> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
> >> + getLabelIdFor(component),
> >> component.getString(CSS_REQUIRED_KEY, null, CSS_REQUIRED_DEFAULT),
> >> + required));
> >> + }
> >> +
> >> + if (isEnabled() != enabled)
> >> + {
> >> +
> >> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
> >> + getLabelIdFor(component),
> >> component.getString(CSS_DISABLED_KEY, null, CSS_DISABLED_DEFAULT),
> >> + !enabled));
> >> + }
> >> +
> >> + setFlag(VALID, valid);
> >> + setFlag(REQUIRED, required);
> >> + setFlag(ENABLED, enabled);
> >> + }
> >> +
> >> + public boolean isValid()
> >> + {
> >> + return getFlag(VALID);
> >> + }
> >> +
> >> + public boolean isEnabled()
> >> + {
> >> + return getFlag(ENABLED);
> >> + }
> >> +
> >> + public boolean isRequired()
> >> + {
> >> + return getFlag(REQUIRED);
> >> + }
> >> +
> >> + private boolean getFlag(final int flag)
> >> + {
> >> + return (flags & flag) != 0;
> >> + }
> >> +
> >> + private void setFlag(final short flag, final boolean
> set)
> >> + {
> >> + if (set)
> >> + {
> >> + flags |= flag;
> >> + }
> >> + else
> >> + {
> >> + flags &= ~flag;
> >> + }
> >> + }
> >> + }
> >> +
> >> /**
> >> * Component that is attached to the {@code <label>} tag and
> takes
> >> care of writing out the label
> >> * text as well as setting classes on the {@code <label>} tag
> >> @@ -184,23 +299,24 @@ public class AutoLabelResolver implements
> >> IComponentResolver
> >> {
> >> super.onComponentTag(tag);
> >> tag.put("for", component.getMarkupId());
> >> + tag.put("id", getLabelIdFor(component));
> >>
> >> if (component instanceof FormComponent)
> >> {
> >> FormComponent<?> fc =
> >> (FormComponent<?>)component;
> >> if (fc.isRequired())
> >> {
> >> - tag.append("class", "required",
> "
> >> ");
> >> + tag.append("class",
> >> component.getString(CSS_REQUIRED_KEY, null, CSS_REQUIRED_DEFAULT), " ");
> >> }
> >> if (!fc.isValid())
> >> {
> >> - tag.append("class", "error", "
> ");
> >> + tag.append("class",
> >> component.getString(CSS_ERROR_KEY, null, CSS_ERROR_DEFAULT), " ");
> >> }
> >> }
> >>
> >> if (!component.isEnabledInHierarchy())
> >> {
> >> - tag.append("class", "disabled", " ");
> >> + tag.append("class",
> >> component.getString(CSS_DISABLED_KEY, null, CSS_DISABLED_DEFAULT), " ");
> >> }
> >> }
> >>
> >> @@ -213,4 +329,6 @@ public class AutoLabelResolver implements
> >> IComponentResolver
> >> return component;
> >> }
> >> }
> >> +
> >> +
> >> }
> >>
> >>
> >>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> >> ----------------------------------------------------------------------
> >> diff --git
> >> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> >> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> >> index a7f07f3..a9ea6a6 100644
> >> ---
> >> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> >> +++
> >> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> >> @@ -30,6 +30,7 @@ import org.apache.wicket.Component;
> >> import org.apache.wicket.IGenericComponent;
> >> import org.apache.wicket.Page;
> >> import org.apache.wicket.WicketRuntimeException;
> >> +import org.apache.wicket.ajax.AjaxRequestTarget;
> >> import org.apache.wicket.behavior.Behavior;
> >> import org.apache.wicket.markup.ComponentTag;
> >> import org.apache.wicket.markup.MarkupStream;
> >> @@ -144,10 +145,8 @@ import org.slf4j.LoggerFactory;
> >> * @param <T>
> >> * The model object type
> >> */
> >> -public class Form<T> extends WebMarkupContainer
> >> - implements
> >> - IFormSubmitListener,
> >> - IGenericComponent<T>
> >> +public class Form<T> extends WebMarkupContainer implements
> >> IFormSubmitListener,
> >> + IGenericComponent<T>
> >> {
> >> private static final String HIDDEN_DIV_START = "<div
> >>
> style=\"width:0px;height:0px;position:absolute;left:-100px;top:-100px;overflow:hidden\">";
> >>
> >> @@ -778,6 +777,20 @@ public class Form<T> extends WebMarkupContainer
> >> {
> >> callOnError(submitter);
> >> }
> >> +
> >> +
> >> + if (((WebRequest)getRequest()).isAjax())
> >> + {
> >> + final AjaxRequestTarget target =
> >> getRequestCycle().find(AjaxRequestTarget.class);
> >> + visitChildren(FormComponent.class, new
> >> IVisitor<FormComponent<?>, Void>()
> >> + {
> >> + @Override
> >> + public void component(FormComponent<?>
> >> component, IVisit<Void> visit)
> >> + {
> >> +
> component.updateAutoLabels(target);
> >> + }
> >> + });
> >> + }
> >> }
> >>
> >> /**
> >> @@ -2089,7 +2102,8 @@ public class Form<T> extends WebMarkupContainer
> >> *
> >> * @author igor
> >> */
> >> - public static enum MethodMismatchResponse {
> >> + public static enum MethodMismatchResponse
> >> + {
> >> /**
> >> * Continue processing.
> >> */
> >>
> >>
> >>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> >> ----------------------------------------------------------------------
> >> diff --git
> >>
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> >>
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> >> index 450b6bd..e4b89ed 100644
> >> ---
> >>
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> >> +++
> >>
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> >> @@ -36,12 +36,15 @@ import org.apache.wicket.IConverterLocator;
> >> import org.apache.wicket.IGenericComponent;
> >> import org.apache.wicket.Localizer;
> >> import org.apache.wicket.WicketRuntimeException;
> >> +import org.apache.wicket.ajax.AjaxRequestTarget;
> >> import org.apache.wicket.behavior.Behavior;
> >> import org.apache.wicket.core.util.lang.WicketObjects;
> >> import org.apache.wicket.markup.ComponentTag;
> >> +import
> >> org.apache.wicket.markup.html.form.AutoLabelResolver.AutoLabelMarker;
> >> import org.apache.wicket.model.IModel;
> >> import org.apache.wicket.model.IPropertyReflectionAwareModel;
> >> import org.apache.wicket.model.Model;
> >> +import org.apache.wicket.protocol.http.WebApplication;
> >> import org.apache.wicket.util.convert.ConversionException;
> >> import org.apache.wicket.util.convert.IConverter;
> >> import org.apache.wicket.util.lang.Args;
> >> @@ -98,11 +101,8 @@ import org.slf4j.LoggerFactory;
> >> * The model object type
> >> *
> >> */
> >> -public abstract class FormComponent<T> extends
> LabeledWebMarkupContainer
> >> - implements
> >> - IFormVisitorParticipant,
> >> - IFormModelUpdateListener,
> >> - IGenericComponent<T>
> >> +public abstract class FormComponent<T> extends
> LabeledWebMarkupContainer
> >> implements
> >> + IFormVisitorParticipant, IFormModelUpdateListener,
> >> IGenericComponent<T>
> >> {
> >> private static final Logger logger =
> >> LoggerFactory.getLogger(FormComponent.class);
> >>
> >> @@ -1579,6 +1579,30 @@ public abstract class FormComponent<T> extends
> >> LabeledWebMarkupContainer
> >> }
> >>
> >> /**
> >> + * Updates auto label css classes such as error/required during
> >> ajax updates when the labels may
> >> + * not be directly repainted in the response.
> >> + *
> >> + * @param target
> >> + */
> >> + public final void updateAutoLabels(AjaxRequestTarget target)
> >> + {
> >> + if
> >>
> (!((WebApplication)getApplication()).getUpdateAutoLabelsOnAjaxRequests())
> >> + {
> >> + return;
> >> + }
> >> +
> >> + AutoLabelMarker marker =
> >> getMetaData(AutoLabelResolver.MARKER_KEY);
> >> +
> >> + if (marker == null)
> >> + {
> >> + // this component does not have an auto label
> >> + return;
> >> + }
> >> +
> >> + marker.updateFrom(this, target);
> >> + }
> >> +
> >> + /**
> >> * Update the model of a {@link FormComponent} containing a
> {@link
> >> Collection}.
> >> *
> >> * If the model object does not yet exists, a new {@link
> >> ArrayList} is filled with the converted
> >>
> >>
> >>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> >> ----------------------------------------------------------------------
> >> diff --git
> >>
> a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> >>
> b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> >> index ba69791..22bbfda 100644
> >> ---
> >>
> a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> >> +++
> >>
> b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> >> @@ -394,10 +394,10 @@ public abstract class WebApplication extends
> >> Application
> >> /**
> >> * Registers a replacement resource for the given javascript
> >> resource. This replacement can be
> >> * another {@link JavaScriptResourceReference} for a packaged
> >> resource, but it can also be an
> >> - * {@link
> org.apache.wicket.request.resource.UrlResourceReference}
> >> to replace the resource by a resource hosted on a CDN.
> >> - * Registering a replacement will cause the resource to replaced
> >> by the given resource
> >> - * throughout the application: if {@code base} is added, {@code
> >> replacement} will be added
> >> - * instead.
> >> + * {@link
> org.apache.wicket.request.resource.UrlResourceReference}
> >> to replace the resource by a
> >> + * resource hosted on a CDN. Registering a replacement will
> cause
> >> the resource to replaced by
> >> + * the given resource throughout the application: if {@code
> base}
> >> is added, {@code replacement}
> >> + * will be added instead.
> >> *
> >> * @param base
> >> * The resource to replace
> >> @@ -415,10 +415,10 @@ public abstract class WebApplication extends
> >> Application
> >> /**
> >> * Registers a replacement resource for the given CSS resource.
> >> This replacement can be another
> >> * {@link CssResourceReference} for a packaged resource, but it
> >> can also be an
> >> - * {@link
> org.apache.wicket.request.resource.UrlResourceReference}
> >> to replace the resource by a resource hosted on a CDN.
> >> - * Registering a replacement will cause the resource to replaced
> >> by the given resource
> >> - * throughout the application: if {@code base} is added, {@code
> >> replacement} will be added
> >> - * instead.
> >> + * {@link
> org.apache.wicket.request.resource.UrlResourceReference}
> >> to replace the resource by a
> >> + * resource hosted on a CDN. Registering a replacement will
> cause
> >> the resource to replaced by
> >> + * the given resource throughout the application: if {@code
> base}
> >> is added, {@code replacement}
> >> + * will be added instead.
> >> *
> >> * @param base
> >> * The resource to replace
> >> @@ -951,9 +951,8 @@ public abstract class WebApplication extends
> >> Application
> >> return ajaxRequestTargetListeners;
> >> }
> >>
> >> - private static class DefaultAjaxRequestTargetProvider
> >> - implements
> >> - IContextProvider<AjaxRequestTarget, Page>
> >> + private static class DefaultAjaxRequestTargetProvider implements
> >> + IContextProvider<AjaxRequestTarget, Page>
> >> {
> >> @Override
> >> public AjaxRequestTarget get(Page page)
> >> @@ -981,4 +980,19 @@ public abstract class WebApplication extends
> >> Application
> >> }
> >> return filterFactoryManager;
> >> }
> >> +
> >> + /**
> >> + * If true, auto label css classes such as {@code error} and
> >> {@code required} will be updated
> >> + * after form component processing during an ajax request. This
> >> allows auto labels to correctly
> >> + * reflect the state of the form component even if they are not
> >> part of the ajax markup update.
> >> + *
> >> + * TODO in wicket-7 this should move into a settings object.
> >> cannot move in 6.x because it
> >> + * requires a change to a setting interface.
> >> + *
> >> + * @return {@code true} iff enabled
> >> + */
> >> + public boolean getUpdateAutoLabelsOnAjaxRequests()
> >> + {
> >> + return true;
> >> + }
> >> }
> >>
> >>
>
Re: git commit: WICKET-5411 auto label auto update during ajax
Posted by Igor Vaynberg <ig...@gmail.com>.
i suppose that bit of js can be rewritten to use pure dom, but has
anyone actually ever implemented wicket-event.js and wicket-ajax.js
using anything other then jquery?
-igor
On Sat, Nov 9, 2013 at 1:34 PM, Martin Grigorov <mg...@apache.org> wrote:
> On Sat, Nov 9, 2013 at 8:49 AM, <iv...@apache.org> wrote:
>
>> Updated Branches:
>> refs/heads/wicket-6.x 4e9a83fdc -> a73209bea
>>
>>
>> WICKET-5411 auto label auto update during ajax
>>
>>
>> Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
>> Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/a73209be
>> Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/a73209be
>> Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/a73209be
>>
>> Branch: refs/heads/wicket-6.x
>> Commit: a73209beab8814a06f2e085384ad87bdf1fda212
>> Parents: 4e9a83f
>> Author: Igor Vaynberg <ig...@gmail.com>
>> Authored: Fri Nov 8 22:48:22 2013 -0800
>> Committer: Igor Vaynberg <ig...@gmail.com>
>> Committed: Fri Nov 8 22:48:22 2013 -0800
>>
>> ----------------------------------------------------------------------
>> .../form/AjaxFormComponentUpdatingBehavior.java | 2 +-
>> .../wicket/core/util/string/CssUtils.java | 14 ++
>> .../markup/html/form/AutoLabelResolver.java | 130 ++++++++++++++++++-
>> .../apache/wicket/markup/html/form/Form.java | 24 +++-
>> .../wicket/markup/html/form/FormComponent.java | 34 ++++-
>> .../wicket/protocol/http/WebApplication.java | 36 +++--
>> 6 files changed, 212 insertions(+), 28 deletions(-)
>> ----------------------------------------------------------------------
>>
>>
>>
>> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
>> ----------------------------------------------------------------------
>> diff --git
>> a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
>> b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
>> index 7eab478..bd8267c 100644
>> ---
>> a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
>> +++
>> b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
>> @@ -160,8 +160,8 @@ public abstract class
>> AjaxFormComponentUpdatingBehavior extends AjaxEventBehavio
>> catch (RuntimeException e)
>> {
>> onError(target, e);
>> -
>> }
>> + formComponent.updateAutoLabels(target);
>> }
>>
>> /**
>>
>>
>> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
>> ----------------------------------------------------------------------
>> diff --git
>> a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
>> b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
>> index a4944a3..7de8669 100644
>> ---
>> a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
>> +++
>> b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
>> @@ -103,4 +103,18 @@ public final class CssUtils
>> }
>> response.write(" />");
>> }
>> +
>> + /**
>> + * Get a standardized key for a CSS class.
>> + *
>> + * @param scope
>> + * scope of CSS class
>> + * @param facet
>> + * facet of CSS class
>> + * @return CSS key
>> + */
>> + public static String key(Class<?> scope, String facet)
>> + {
>> + return scope.getSimpleName() + ".CSS." + facet;
>> + }
>> }
>>
>>
>> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
>> ----------------------------------------------------------------------
>> diff --git
>> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
>> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
>> index 562e6ed..7892fa7 100644
>> ---
>> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
>> +++
>> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
>> @@ -16,9 +16,14 @@
>> */
>> package org.apache.wicket.markup.html.form;
>>
>> +import java.io.Serializable;
>> +
>> import org.apache.wicket.Component;
>> import org.apache.wicket.MarkupContainer;
>> +import org.apache.wicket.MetaDataKey;
>> import org.apache.wicket.WicketRuntimeException;
>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>> +import org.apache.wicket.core.util.string.CssUtils;
>> import org.apache.wicket.markup.ComponentTag;
>> import org.apache.wicket.markup.MarkupStream;
>> import org.apache.wicket.markup.html.TransparentWebMarkupContainer;
>> @@ -36,11 +41,14 @@ import org.slf4j.LoggerFactory;
>> * <li>Outputs the {@code for} attribute with the value equivalent to the
>> markup id of the
>> * referenced form component</li>
>> * <li>Appends {@code required} css class to the {@code <label>} tag if
>> the referenced form
>> - * component is required</li>
>> + * component is required. Name of the css class can be overwritten by
>> having a i18n property defined
>> + * for key AutoLabelResolver.CSS.required</li>
>> * <li>Appends {@code error} css class to the {@code <label>} tag if the
>> referenced form component
>> - * has failed validation</li>
>> + * has failed validation. Name of the css class can be overwritten by
>> having a i18n property defined
>> + * for key AutoLabelResolver.CSS.error</li>
>> * <li>Appends {@code disabled} css class to the {@code <label>} tag if
>> the referenced form
>> - * component has is not enabled in hierarchy</li>
>> + * component has is not enabled in hierarchy. Name of the css class can
>> be overwritten by having a i18n property defined
>> + * for key AutoLabelResolver.CSS.disabled</li>
>> * </ul>
>> *
>> * <p>
>> @@ -64,6 +72,14 @@ public class AutoLabelResolver implements
>> IComponentResolver
>>
>> static final String WICKET_FOR = ":for";
>>
>> + public static final String CSS_REQUIRED_KEY =
>> CssUtils.key(AutoLabelResolver.class, "requried");
>> + public static final String CSS_DISABLED_KEY =
>> CssUtils.key(AutoLabelResolver.class, "requried");
>> + public static final String CSS_ERROR_KEY =
>> CssUtils.key(AutoLabelResolver.class, "requried");
>> + private static final String CSS_DISABLED_DEFAULT = "disabled";
>> + private static final String CSS_REQUIRED_DEFAULT = "required";
>> + private static final String CSS_ERROR_DEFAULT = "error";
>> +
>> +
>> @Override
>> public Component resolve(final MarkupContainer container, final
>> MarkupStream markupStream,
>> final ComponentTag tag)
>> @@ -99,6 +115,11 @@ public class AutoLabelResolver implements
>> IComponentResolver
>> }
>> }
>>
>> + if (component instanceof FormComponent)
>> + {
>> + component.setMetaData(MARKER_KEY, new
>> AutoLabelMarker((FormComponent<?>)component));
>> + }
>> +
>> return new AutoLabel("label" +
>> container.getPage().getAutoIndex(), component);
>> }
>>
>> @@ -161,6 +182,100 @@ public class AutoLabelResolver implements
>> IComponentResolver
>> return null;
>> }
>>
>> + public static final String getLabelIdFor(Component component)
>> + {
>> + return component.getMarkupId() + "-w-lbl";
>> + }
>> +
>> + public static final MetaDataKey<AutoLabelMarker> MARKER_KEY = new
>> MetaDataKey<AutoLabelMarker>()
>> + {
>> + };
>> +
>> + /**
>> + * Marker used to track whether or not a form component has an
>> associated auto label by its mere
>> + * presense as well as some attributes of the component across
>> requests.
>> + *
>> + * @author igor
>> + *
>> + */
>> + public static final class AutoLabelMarker implements Serializable
>> + {
>> + public static final short VALID = 0x01;
>> + public static final short REQUIRED = 0x02;
>> + public static final short ENABLED = 0x04;
>> +
>> + private short flags;
>> +
>> + public AutoLabelMarker(FormComponent<?> component)
>> + {
>> + setFlag(VALID, component.isValid());
>> + setFlag(REQUIRED, component.isRequired());
>> + setFlag(ENABLED, component.isEnabledInHierarchy());
>> + }
>> +
>> + public void updateFrom(FormComponent<?> component,
>> AjaxRequestTarget target)
>> + {
>> + boolean valid = component.isValid(), required =
>> component.isRequired(), enabled = component.isEnabledInHierarchy();
>> +
>> + if (isValid() != valid)
>> + {
>> +
>> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
>>
>
> Until now we haven't used jQuery APIs directly in the Java code.
> This makes it harder to use different impl of wicket-event/ajax js.
>
>
>> + getLabelIdFor(component),
>> component.getString(CSS_ERROR_KEY, null, CSS_ERROR_DEFAULT),
>> + !valid));
>> + }
>> +
>> + if (isRequired() != required)
>> + {
>> +
>> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
>> + getLabelIdFor(component),
>> component.getString(CSS_REQUIRED_KEY, null, CSS_REQUIRED_DEFAULT),
>> + required));
>> + }
>> +
>> + if (isEnabled() != enabled)
>> + {
>> +
>> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
>> + getLabelIdFor(component),
>> component.getString(CSS_DISABLED_KEY, null, CSS_DISABLED_DEFAULT),
>> + !enabled));
>> + }
>> +
>> + setFlag(VALID, valid);
>> + setFlag(REQUIRED, required);
>> + setFlag(ENABLED, enabled);
>> + }
>> +
>> + public boolean isValid()
>> + {
>> + return getFlag(VALID);
>> + }
>> +
>> + public boolean isEnabled()
>> + {
>> + return getFlag(ENABLED);
>> + }
>> +
>> + public boolean isRequired()
>> + {
>> + return getFlag(REQUIRED);
>> + }
>> +
>> + private boolean getFlag(final int flag)
>> + {
>> + return (flags & flag) != 0;
>> + }
>> +
>> + private void setFlag(final short flag, final boolean set)
>> + {
>> + if (set)
>> + {
>> + flags |= flag;
>> + }
>> + else
>> + {
>> + flags &= ~flag;
>> + }
>> + }
>> + }
>> +
>> /**
>> * Component that is attached to the {@code <label>} tag and takes
>> care of writing out the label
>> * text as well as setting classes on the {@code <label>} tag
>> @@ -184,23 +299,24 @@ public class AutoLabelResolver implements
>> IComponentResolver
>> {
>> super.onComponentTag(tag);
>> tag.put("for", component.getMarkupId());
>> + tag.put("id", getLabelIdFor(component));
>>
>> if (component instanceof FormComponent)
>> {
>> FormComponent<?> fc =
>> (FormComponent<?>)component;
>> if (fc.isRequired())
>> {
>> - tag.append("class", "required", "
>> ");
>> + tag.append("class",
>> component.getString(CSS_REQUIRED_KEY, null, CSS_REQUIRED_DEFAULT), " ");
>> }
>> if (!fc.isValid())
>> {
>> - tag.append("class", "error", " ");
>> + tag.append("class",
>> component.getString(CSS_ERROR_KEY, null, CSS_ERROR_DEFAULT), " ");
>> }
>> }
>>
>> if (!component.isEnabledInHierarchy())
>> {
>> - tag.append("class", "disabled", " ");
>> + tag.append("class",
>> component.getString(CSS_DISABLED_KEY, null, CSS_DISABLED_DEFAULT), " ");
>> }
>> }
>>
>> @@ -213,4 +329,6 @@ public class AutoLabelResolver implements
>> IComponentResolver
>> return component;
>> }
>> }
>> +
>> +
>> }
>>
>>
>> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
>> ----------------------------------------------------------------------
>> diff --git
>> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
>> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
>> index a7f07f3..a9ea6a6 100644
>> ---
>> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
>> +++
>> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
>> @@ -30,6 +30,7 @@ import org.apache.wicket.Component;
>> import org.apache.wicket.IGenericComponent;
>> import org.apache.wicket.Page;
>> import org.apache.wicket.WicketRuntimeException;
>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>> import org.apache.wicket.behavior.Behavior;
>> import org.apache.wicket.markup.ComponentTag;
>> import org.apache.wicket.markup.MarkupStream;
>> @@ -144,10 +145,8 @@ import org.slf4j.LoggerFactory;
>> * @param <T>
>> * The model object type
>> */
>> -public class Form<T> extends WebMarkupContainer
>> - implements
>> - IFormSubmitListener,
>> - IGenericComponent<T>
>> +public class Form<T> extends WebMarkupContainer implements
>> IFormSubmitListener,
>> + IGenericComponent<T>
>> {
>> private static final String HIDDEN_DIV_START = "<div
>> style=\"width:0px;height:0px;position:absolute;left:-100px;top:-100px;overflow:hidden\">";
>>
>> @@ -778,6 +777,20 @@ public class Form<T> extends WebMarkupContainer
>> {
>> callOnError(submitter);
>> }
>> +
>> +
>> + if (((WebRequest)getRequest()).isAjax())
>> + {
>> + final AjaxRequestTarget target =
>> getRequestCycle().find(AjaxRequestTarget.class);
>> + visitChildren(FormComponent.class, new
>> IVisitor<FormComponent<?>, Void>()
>> + {
>> + @Override
>> + public void component(FormComponent<?>
>> component, IVisit<Void> visit)
>> + {
>> + component.updateAutoLabels(target);
>> + }
>> + });
>> + }
>> }
>>
>> /**
>> @@ -2089,7 +2102,8 @@ public class Form<T> extends WebMarkupContainer
>> *
>> * @author igor
>> */
>> - public static enum MethodMismatchResponse {
>> + public static enum MethodMismatchResponse
>> + {
>> /**
>> * Continue processing.
>> */
>>
>>
>> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
>> ----------------------------------------------------------------------
>> diff --git
>> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
>> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
>> index 450b6bd..e4b89ed 100644
>> ---
>> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
>> +++
>> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
>> @@ -36,12 +36,15 @@ import org.apache.wicket.IConverterLocator;
>> import org.apache.wicket.IGenericComponent;
>> import org.apache.wicket.Localizer;
>> import org.apache.wicket.WicketRuntimeException;
>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>> import org.apache.wicket.behavior.Behavior;
>> import org.apache.wicket.core.util.lang.WicketObjects;
>> import org.apache.wicket.markup.ComponentTag;
>> +import
>> org.apache.wicket.markup.html.form.AutoLabelResolver.AutoLabelMarker;
>> import org.apache.wicket.model.IModel;
>> import org.apache.wicket.model.IPropertyReflectionAwareModel;
>> import org.apache.wicket.model.Model;
>> +import org.apache.wicket.protocol.http.WebApplication;
>> import org.apache.wicket.util.convert.ConversionException;
>> import org.apache.wicket.util.convert.IConverter;
>> import org.apache.wicket.util.lang.Args;
>> @@ -98,11 +101,8 @@ import org.slf4j.LoggerFactory;
>> * The model object type
>> *
>> */
>> -public abstract class FormComponent<T> extends LabeledWebMarkupContainer
>> - implements
>> - IFormVisitorParticipant,
>> - IFormModelUpdateListener,
>> - IGenericComponent<T>
>> +public abstract class FormComponent<T> extends LabeledWebMarkupContainer
>> implements
>> + IFormVisitorParticipant, IFormModelUpdateListener,
>> IGenericComponent<T>
>> {
>> private static final Logger logger =
>> LoggerFactory.getLogger(FormComponent.class);
>>
>> @@ -1579,6 +1579,30 @@ public abstract class FormComponent<T> extends
>> LabeledWebMarkupContainer
>> }
>>
>> /**
>> + * Updates auto label css classes such as error/required during
>> ajax updates when the labels may
>> + * not be directly repainted in the response.
>> + *
>> + * @param target
>> + */
>> + public final void updateAutoLabels(AjaxRequestTarget target)
>> + {
>> + if
>> (!((WebApplication)getApplication()).getUpdateAutoLabelsOnAjaxRequests())
>> + {
>> + return;
>> + }
>> +
>> + AutoLabelMarker marker =
>> getMetaData(AutoLabelResolver.MARKER_KEY);
>> +
>> + if (marker == null)
>> + {
>> + // this component does not have an auto label
>> + return;
>> + }
>> +
>> + marker.updateFrom(this, target);
>> + }
>> +
>> + /**
>> * Update the model of a {@link FormComponent} containing a {@link
>> Collection}.
>> *
>> * If the model object does not yet exists, a new {@link
>> ArrayList} is filled with the converted
>>
>>
>> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
>> ----------------------------------------------------------------------
>> diff --git
>> a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
>> b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
>> index ba69791..22bbfda 100644
>> ---
>> a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
>> +++
>> b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
>> @@ -394,10 +394,10 @@ public abstract class WebApplication extends
>> Application
>> /**
>> * Registers a replacement resource for the given javascript
>> resource. This replacement can be
>> * another {@link JavaScriptResourceReference} for a packaged
>> resource, but it can also be an
>> - * {@link org.apache.wicket.request.resource.UrlResourceReference}
>> to replace the resource by a resource hosted on a CDN.
>> - * Registering a replacement will cause the resource to replaced
>> by the given resource
>> - * throughout the application: if {@code base} is added, {@code
>> replacement} will be added
>> - * instead.
>> + * {@link org.apache.wicket.request.resource.UrlResourceReference}
>> to replace the resource by a
>> + * resource hosted on a CDN. Registering a replacement will cause
>> the resource to replaced by
>> + * the given resource throughout the application: if {@code base}
>> is added, {@code replacement}
>> + * will be added instead.
>> *
>> * @param base
>> * The resource to replace
>> @@ -415,10 +415,10 @@ public abstract class WebApplication extends
>> Application
>> /**
>> * Registers a replacement resource for the given CSS resource.
>> This replacement can be another
>> * {@link CssResourceReference} for a packaged resource, but it
>> can also be an
>> - * {@link org.apache.wicket.request.resource.UrlResourceReference}
>> to replace the resource by a resource hosted on a CDN.
>> - * Registering a replacement will cause the resource to replaced
>> by the given resource
>> - * throughout the application: if {@code base} is added, {@code
>> replacement} will be added
>> - * instead.
>> + * {@link org.apache.wicket.request.resource.UrlResourceReference}
>> to replace the resource by a
>> + * resource hosted on a CDN. Registering a replacement will cause
>> the resource to replaced by
>> + * the given resource throughout the application: if {@code base}
>> is added, {@code replacement}
>> + * will be added instead.
>> *
>> * @param base
>> * The resource to replace
>> @@ -951,9 +951,8 @@ public abstract class WebApplication extends
>> Application
>> return ajaxRequestTargetListeners;
>> }
>>
>> - private static class DefaultAjaxRequestTargetProvider
>> - implements
>> - IContextProvider<AjaxRequestTarget, Page>
>> + private static class DefaultAjaxRequestTargetProvider implements
>> + IContextProvider<AjaxRequestTarget, Page>
>> {
>> @Override
>> public AjaxRequestTarget get(Page page)
>> @@ -981,4 +980,19 @@ public abstract class WebApplication extends
>> Application
>> }
>> return filterFactoryManager;
>> }
>> +
>> + /**
>> + * If true, auto label css classes such as {@code error} and
>> {@code required} will be updated
>> + * after form component processing during an ajax request. This
>> allows auto labels to correctly
>> + * reflect the state of the form component even if they are not
>> part of the ajax markup update.
>> + *
>> + * TODO in wicket-7 this should move into a settings object.
>> cannot move in 6.x because it
>> + * requires a change to a setting interface.
>> + *
>> + * @return {@code true} iff enabled
>> + */
>> + public boolean getUpdateAutoLabelsOnAjaxRequests()
>> + {
>> + return true;
>> + }
>> }
>>
>>
Re: git commit: WICKET-5411 auto label auto update during ajax
Posted by Martin Grigorov <mg...@apache.org>.
On Sat, Nov 9, 2013 at 8:49 AM, <iv...@apache.org> wrote:
> Updated Branches:
> refs/heads/wicket-6.x 4e9a83fdc -> a73209bea
>
>
> WICKET-5411 auto label auto update during ajax
>
>
> Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
> Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/a73209be
> Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/a73209be
> Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/a73209be
>
> Branch: refs/heads/wicket-6.x
> Commit: a73209beab8814a06f2e085384ad87bdf1fda212
> Parents: 4e9a83f
> Author: Igor Vaynberg <ig...@gmail.com>
> Authored: Fri Nov 8 22:48:22 2013 -0800
> Committer: Igor Vaynberg <ig...@gmail.com>
> Committed: Fri Nov 8 22:48:22 2013 -0800
>
> ----------------------------------------------------------------------
> .../form/AjaxFormComponentUpdatingBehavior.java | 2 +-
> .../wicket/core/util/string/CssUtils.java | 14 ++
> .../markup/html/form/AutoLabelResolver.java | 130 ++++++++++++++++++-
> .../apache/wicket/markup/html/form/Form.java | 24 +++-
> .../wicket/markup/html/form/FormComponent.java | 34 ++++-
> .../wicket/protocol/http/WebApplication.java | 36 +++--
> 6 files changed, 212 insertions(+), 28 deletions(-)
> ----------------------------------------------------------------------
>
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> ----------------------------------------------------------------------
> diff --git
> a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> index 7eab478..bd8267c 100644
> ---
> a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> +++
> b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
> @@ -160,8 +160,8 @@ public abstract class
> AjaxFormComponentUpdatingBehavior extends AjaxEventBehavio
> catch (RuntimeException e)
> {
> onError(target, e);
> -
> }
> + formComponent.updateAutoLabels(target);
> }
>
> /**
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> ----------------------------------------------------------------------
> diff --git
> a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> index a4944a3..7de8669 100644
> ---
> a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> +++
> b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
> @@ -103,4 +103,18 @@ public final class CssUtils
> }
> response.write(" />");
> }
> +
> + /**
> + * Get a standardized key for a CSS class.
> + *
> + * @param scope
> + * scope of CSS class
> + * @param facet
> + * facet of CSS class
> + * @return CSS key
> + */
> + public static String key(Class<?> scope, String facet)
> + {
> + return scope.getSimpleName() + ".CSS." + facet;
> + }
> }
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> ----------------------------------------------------------------------
> diff --git
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> index 562e6ed..7892fa7 100644
> ---
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> +++
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
> @@ -16,9 +16,14 @@
> */
> package org.apache.wicket.markup.html.form;
>
> +import java.io.Serializable;
> +
> import org.apache.wicket.Component;
> import org.apache.wicket.MarkupContainer;
> +import org.apache.wicket.MetaDataKey;
> import org.apache.wicket.WicketRuntimeException;
> +import org.apache.wicket.ajax.AjaxRequestTarget;
> +import org.apache.wicket.core.util.string.CssUtils;
> import org.apache.wicket.markup.ComponentTag;
> import org.apache.wicket.markup.MarkupStream;
> import org.apache.wicket.markup.html.TransparentWebMarkupContainer;
> @@ -36,11 +41,14 @@ import org.slf4j.LoggerFactory;
> * <li>Outputs the {@code for} attribute with the value equivalent to the
> markup id of the
> * referenced form component</li>
> * <li>Appends {@code required} css class to the {@code <label>} tag if
> the referenced form
> - * component is required</li>
> + * component is required. Name of the css class can be overwritten by
> having a i18n property defined
> + * for key AutoLabelResolver.CSS.required</li>
> * <li>Appends {@code error} css class to the {@code <label>} tag if the
> referenced form component
> - * has failed validation</li>
> + * has failed validation. Name of the css class can be overwritten by
> having a i18n property defined
> + * for key AutoLabelResolver.CSS.error</li>
> * <li>Appends {@code disabled} css class to the {@code <label>} tag if
> the referenced form
> - * component has is not enabled in hierarchy</li>
> + * component has is not enabled in hierarchy. Name of the css class can
> be overwritten by having a i18n property defined
> + * for key AutoLabelResolver.CSS.disabled</li>
> * </ul>
> *
> * <p>
> @@ -64,6 +72,14 @@ public class AutoLabelResolver implements
> IComponentResolver
>
> static final String WICKET_FOR = ":for";
>
> + public static final String CSS_REQUIRED_KEY =
> CssUtils.key(AutoLabelResolver.class, "requried");
> + public static final String CSS_DISABLED_KEY =
> CssUtils.key(AutoLabelResolver.class, "requried");
> + public static final String CSS_ERROR_KEY =
> CssUtils.key(AutoLabelResolver.class, "requried");
> + private static final String CSS_DISABLED_DEFAULT = "disabled";
> + private static final String CSS_REQUIRED_DEFAULT = "required";
> + private static final String CSS_ERROR_DEFAULT = "error";
> +
> +
> @Override
> public Component resolve(final MarkupContainer container, final
> MarkupStream markupStream,
> final ComponentTag tag)
> @@ -99,6 +115,11 @@ public class AutoLabelResolver implements
> IComponentResolver
> }
> }
>
> + if (component instanceof FormComponent)
> + {
> + component.setMetaData(MARKER_KEY, new
> AutoLabelMarker((FormComponent<?>)component));
> + }
> +
> return new AutoLabel("label" +
> container.getPage().getAutoIndex(), component);
> }
>
> @@ -161,6 +182,100 @@ public class AutoLabelResolver implements
> IComponentResolver
> return null;
> }
>
> + public static final String getLabelIdFor(Component component)
> + {
> + return component.getMarkupId() + "-w-lbl";
> + }
> +
> + public static final MetaDataKey<AutoLabelMarker> MARKER_KEY = new
> MetaDataKey<AutoLabelMarker>()
> + {
> + };
> +
> + /**
> + * Marker used to track whether or not a form component has an
> associated auto label by its mere
> + * presense as well as some attributes of the component across
> requests.
> + *
> + * @author igor
> + *
> + */
> + public static final class AutoLabelMarker implements Serializable
> + {
> + public static final short VALID = 0x01;
> + public static final short REQUIRED = 0x02;
> + public static final short ENABLED = 0x04;
> +
> + private short flags;
> +
> + public AutoLabelMarker(FormComponent<?> component)
> + {
> + setFlag(VALID, component.isValid());
> + setFlag(REQUIRED, component.isRequired());
> + setFlag(ENABLED, component.isEnabledInHierarchy());
> + }
> +
> + public void updateFrom(FormComponent<?> component,
> AjaxRequestTarget target)
> + {
> + boolean valid = component.isValid(), required =
> component.isRequired(), enabled = component.isEnabledInHierarchy();
> +
> + if (isValid() != valid)
> + {
> +
> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
>
Until now we haven't used jQuery APIs directly in the Java code.
This makes it harder to use different impl of wicket-event/ajax js.
> + getLabelIdFor(component),
> component.getString(CSS_ERROR_KEY, null, CSS_ERROR_DEFAULT),
> + !valid));
> + }
> +
> + if (isRequired() != required)
> + {
> +
> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
> + getLabelIdFor(component),
> component.getString(CSS_REQUIRED_KEY, null, CSS_REQUIRED_DEFAULT),
> + required));
> + }
> +
> + if (isEnabled() != enabled)
> + {
> +
> target.appendJavaScript(String.format("$('#%s').toggleClass('%s', %s);",
> + getLabelIdFor(component),
> component.getString(CSS_DISABLED_KEY, null, CSS_DISABLED_DEFAULT),
> + !enabled));
> + }
> +
> + setFlag(VALID, valid);
> + setFlag(REQUIRED, required);
> + setFlag(ENABLED, enabled);
> + }
> +
> + public boolean isValid()
> + {
> + return getFlag(VALID);
> + }
> +
> + public boolean isEnabled()
> + {
> + return getFlag(ENABLED);
> + }
> +
> + public boolean isRequired()
> + {
> + return getFlag(REQUIRED);
> + }
> +
> + private boolean getFlag(final int flag)
> + {
> + return (flags & flag) != 0;
> + }
> +
> + private void setFlag(final short flag, final boolean set)
> + {
> + if (set)
> + {
> + flags |= flag;
> + }
> + else
> + {
> + flags &= ~flag;
> + }
> + }
> + }
> +
> /**
> * Component that is attached to the {@code <label>} tag and takes
> care of writing out the label
> * text as well as setting classes on the {@code <label>} tag
> @@ -184,23 +299,24 @@ public class AutoLabelResolver implements
> IComponentResolver
> {
> super.onComponentTag(tag);
> tag.put("for", component.getMarkupId());
> + tag.put("id", getLabelIdFor(component));
>
> if (component instanceof FormComponent)
> {
> FormComponent<?> fc =
> (FormComponent<?>)component;
> if (fc.isRequired())
> {
> - tag.append("class", "required", "
> ");
> + tag.append("class",
> component.getString(CSS_REQUIRED_KEY, null, CSS_REQUIRED_DEFAULT), " ");
> }
> if (!fc.isValid())
> {
> - tag.append("class", "error", " ");
> + tag.append("class",
> component.getString(CSS_ERROR_KEY, null, CSS_ERROR_DEFAULT), " ");
> }
> }
>
> if (!component.isEnabledInHierarchy())
> {
> - tag.append("class", "disabled", " ");
> + tag.append("class",
> component.getString(CSS_DISABLED_KEY, null, CSS_DISABLED_DEFAULT), " ");
> }
> }
>
> @@ -213,4 +329,6 @@ public class AutoLabelResolver implements
> IComponentResolver
> return component;
> }
> }
> +
> +
> }
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> ----------------------------------------------------------------------
> diff --git
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> index a7f07f3..a9ea6a6 100644
> ---
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> +++
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
> @@ -30,6 +30,7 @@ import org.apache.wicket.Component;
> import org.apache.wicket.IGenericComponent;
> import org.apache.wicket.Page;
> import org.apache.wicket.WicketRuntimeException;
> +import org.apache.wicket.ajax.AjaxRequestTarget;
> import org.apache.wicket.behavior.Behavior;
> import org.apache.wicket.markup.ComponentTag;
> import org.apache.wicket.markup.MarkupStream;
> @@ -144,10 +145,8 @@ import org.slf4j.LoggerFactory;
> * @param <T>
> * The model object type
> */
> -public class Form<T> extends WebMarkupContainer
> - implements
> - IFormSubmitListener,
> - IGenericComponent<T>
> +public class Form<T> extends WebMarkupContainer implements
> IFormSubmitListener,
> + IGenericComponent<T>
> {
> private static final String HIDDEN_DIV_START = "<div
> style=\"width:0px;height:0px;position:absolute;left:-100px;top:-100px;overflow:hidden\">";
>
> @@ -778,6 +777,20 @@ public class Form<T> extends WebMarkupContainer
> {
> callOnError(submitter);
> }
> +
> +
> + if (((WebRequest)getRequest()).isAjax())
> + {
> + final AjaxRequestTarget target =
> getRequestCycle().find(AjaxRequestTarget.class);
> + visitChildren(FormComponent.class, new
> IVisitor<FormComponent<?>, Void>()
> + {
> + @Override
> + public void component(FormComponent<?>
> component, IVisit<Void> visit)
> + {
> + component.updateAutoLabels(target);
> + }
> + });
> + }
> }
>
> /**
> @@ -2089,7 +2102,8 @@ public class Form<T> extends WebMarkupContainer
> *
> * @author igor
> */
> - public static enum MethodMismatchResponse {
> + public static enum MethodMismatchResponse
> + {
> /**
> * Continue processing.
> */
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> ----------------------------------------------------------------------
> diff --git
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> index 450b6bd..e4b89ed 100644
> ---
> a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> +++
> b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
> @@ -36,12 +36,15 @@ import org.apache.wicket.IConverterLocator;
> import org.apache.wicket.IGenericComponent;
> import org.apache.wicket.Localizer;
> import org.apache.wicket.WicketRuntimeException;
> +import org.apache.wicket.ajax.AjaxRequestTarget;
> import org.apache.wicket.behavior.Behavior;
> import org.apache.wicket.core.util.lang.WicketObjects;
> import org.apache.wicket.markup.ComponentTag;
> +import
> org.apache.wicket.markup.html.form.AutoLabelResolver.AutoLabelMarker;
> import org.apache.wicket.model.IModel;
> import org.apache.wicket.model.IPropertyReflectionAwareModel;
> import org.apache.wicket.model.Model;
> +import org.apache.wicket.protocol.http.WebApplication;
> import org.apache.wicket.util.convert.ConversionException;
> import org.apache.wicket.util.convert.IConverter;
> import org.apache.wicket.util.lang.Args;
> @@ -98,11 +101,8 @@ import org.slf4j.LoggerFactory;
> * The model object type
> *
> */
> -public abstract class FormComponent<T> extends LabeledWebMarkupContainer
> - implements
> - IFormVisitorParticipant,
> - IFormModelUpdateListener,
> - IGenericComponent<T>
> +public abstract class FormComponent<T> extends LabeledWebMarkupContainer
> implements
> + IFormVisitorParticipant, IFormModelUpdateListener,
> IGenericComponent<T>
> {
> private static final Logger logger =
> LoggerFactory.getLogger(FormComponent.class);
>
> @@ -1579,6 +1579,30 @@ public abstract class FormComponent<T> extends
> LabeledWebMarkupContainer
> }
>
> /**
> + * Updates auto label css classes such as error/required during
> ajax updates when the labels may
> + * not be directly repainted in the response.
> + *
> + * @param target
> + */
> + public final void updateAutoLabels(AjaxRequestTarget target)
> + {
> + if
> (!((WebApplication)getApplication()).getUpdateAutoLabelsOnAjaxRequests())
> + {
> + return;
> + }
> +
> + AutoLabelMarker marker =
> getMetaData(AutoLabelResolver.MARKER_KEY);
> +
> + if (marker == null)
> + {
> + // this component does not have an auto label
> + return;
> + }
> +
> + marker.updateFrom(this, target);
> + }
> +
> + /**
> * Update the model of a {@link FormComponent} containing a {@link
> Collection}.
> *
> * If the model object does not yet exists, a new {@link
> ArrayList} is filled with the converted
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/a73209be/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> ----------------------------------------------------------------------
> diff --git
> a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> index ba69791..22bbfda 100644
> ---
> a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> +++
> b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
> @@ -394,10 +394,10 @@ public abstract class WebApplication extends
> Application
> /**
> * Registers a replacement resource for the given javascript
> resource. This replacement can be
> * another {@link JavaScriptResourceReference} for a packaged
> resource, but it can also be an
> - * {@link org.apache.wicket.request.resource.UrlResourceReference}
> to replace the resource by a resource hosted on a CDN.
> - * Registering a replacement will cause the resource to replaced
> by the given resource
> - * throughout the application: if {@code base} is added, {@code
> replacement} will be added
> - * instead.
> + * {@link org.apache.wicket.request.resource.UrlResourceReference}
> to replace the resource by a
> + * resource hosted on a CDN. Registering a replacement will cause
> the resource to replaced by
> + * the given resource throughout the application: if {@code base}
> is added, {@code replacement}
> + * will be added instead.
> *
> * @param base
> * The resource to replace
> @@ -415,10 +415,10 @@ public abstract class WebApplication extends
> Application
> /**
> * Registers a replacement resource for the given CSS resource.
> This replacement can be another
> * {@link CssResourceReference} for a packaged resource, but it
> can also be an
> - * {@link org.apache.wicket.request.resource.UrlResourceReference}
> to replace the resource by a resource hosted on a CDN.
> - * Registering a replacement will cause the resource to replaced
> by the given resource
> - * throughout the application: if {@code base} is added, {@code
> replacement} will be added
> - * instead.
> + * {@link org.apache.wicket.request.resource.UrlResourceReference}
> to replace the resource by a
> + * resource hosted on a CDN. Registering a replacement will cause
> the resource to replaced by
> + * the given resource throughout the application: if {@code base}
> is added, {@code replacement}
> + * will be added instead.
> *
> * @param base
> * The resource to replace
> @@ -951,9 +951,8 @@ public abstract class WebApplication extends
> Application
> return ajaxRequestTargetListeners;
> }
>
> - private static class DefaultAjaxRequestTargetProvider
> - implements
> - IContextProvider<AjaxRequestTarget, Page>
> + private static class DefaultAjaxRequestTargetProvider implements
> + IContextProvider<AjaxRequestTarget, Page>
> {
> @Override
> public AjaxRequestTarget get(Page page)
> @@ -981,4 +980,19 @@ public abstract class WebApplication extends
> Application
> }
> return filterFactoryManager;
> }
> +
> + /**
> + * If true, auto label css classes such as {@code error} and
> {@code required} will be updated
> + * after form component processing during an ajax request. This
> allows auto labels to correctly
> + * reflect the state of the form component even if they are not
> part of the ajax markup update.
> + *
> + * TODO in wicket-7 this should move into a settings object.
> cannot move in 6.x because it
> + * requires a change to a setting interface.
> + *
> + * @return {@code true} iff enabled
> + */
> + public boolean getUpdateAutoLabelsOnAjaxRequests()
> + {
> + return true;
> + }
> }
>
>