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 <[email protected]>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 <[email protected]> > wrote: > > On Sat, Nov 9, 2013 at 8:49 AM, <[email protected]> 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 <[email protected]> > >> Authored: Fri Nov 8 22:48:22 2013 -0800 > >> Committer: Igor Vaynberg <[email protected]> > >> 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; > >> + } > >> } > >> > >> >
