001: /*
002: * $Id: AjaxFormComponentUpdatingBehavior.java,v 1.4 2006/02/02 18:49:46
003: * ivaynberg Exp $ $Revision: 462177 $ $Date: 2006-03-09 01:08:00 -0800 (Thu, 09
004: * Mar 2006) $
005: *
006: * ==============================================================================
007: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
008: * use this file except in compliance with the License. You may obtain a copy of
009: * the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
015: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
016: * License for the specific language governing permissions and limitations under
017: * the License.
018: */
019: package wicket.ajax.form;
020:
021: import wicket.WicketRuntimeException;
022: import wicket.ajax.AjaxEventBehavior;
023: import wicket.ajax.AjaxRequestTarget;
024: import wicket.markup.html.form.FormComponent;
025: import wicket.markup.html.form.persistence.IValuePersister;
026: import wicket.markup.html.form.validation.IFormValidator;
027: import wicket.util.string.AppendingStringBuffer;
028:
029: /**
030: * A behavior that updates the hosting FormComponent via ajax when an event it
031: * is attached to is triggered. This behavior encapsulates the entire
032: * form-processing workflow as relevant only to this component so if validation
033: * is successfull the component's model will be updated according to the
034: * submitted value.
035: * <p>
036: * NOTE: This behavior does not support persisting form component values into
037: * cookie or other {@link IValuePersister}. If this is necessary please add a
038: * request for enhancement.
039: * <p>
040: * NOTE: This behavior does not validate any {@link IFormValidator}s attached
041: * to this form even though they may reference the component being updated.
042: *
043: * @since 1.2
044: *
045: * @author Igor Vaynberg (ivaynberg)
046: */
047: public abstract class AjaxFormComponentUpdatingBehavior extends
048: AjaxEventBehavior {
049: /**
050: * Construct.
051: *
052: * @param event
053: * event to trigger this behavior
054: */
055: public AjaxFormComponentUpdatingBehavior(final String event) {
056: super (event);
057: }
058:
059: /**
060: *
061: * @see wicket.behavior.AbstractAjaxBehavior#onBind()
062: */
063: protected void onBind() {
064: super .onBind();
065:
066: if (!(getComponent() instanceof FormComponent)) {
067: throw new WicketRuntimeException(
068: "Behavior "
069: + getClass().getName()
070: + " can only be added to an isntance of a FormComponent");
071: }
072: }
073:
074: /**
075: *
076: * @return FormComponent
077: */
078: protected final FormComponent getFormComponent() {
079: return (FormComponent) getComponent();
080: }
081:
082: /**
083: * @see wicket.ajax.AjaxEventBehavior#getEventHandler()
084: */
085: protected final CharSequence getEventHandler() {
086: return getCallbackScript(new AppendingStringBuffer(
087: "wicketAjaxPost('").append(getCallbackUrl()).append(
088: "', wicketSerialize(document.getElementById('"
089: + getComponent().getMarkupId() + "'))"), null,
090: null);
091: }
092:
093: /**
094: * @see wicket.ajax.AjaxEventBehavior#onCheckEvent(java.lang.String)
095: */
096: protected void onCheckEvent(String event) {
097: if ("href".equalsIgnoreCase(event)) {
098: throw new IllegalArgumentException(
099: "this behavior cannot be attached to an 'href' event");
100: }
101: }
102:
103: /**
104: *
105: * @see wicket.ajax.AjaxEventBehavior#onEvent(wicket.ajax.AjaxRequestTarget)
106: */
107: protected final void onEvent(final AjaxRequestTarget target) {
108: final FormComponent formComponent = getFormComponent();
109: boolean callOnUpdate = true;
110:
111: try {
112: formComponent.inputChanged();
113: formComponent.validate();
114: if (formComponent.hasErrorMessage()) {
115: formComponent.invalid();
116: } else {
117: formComponent.valid();
118: formComponent.updateModel();
119: }
120: } catch (RuntimeException e) {
121: callOnUpdate = false;
122: onError(target, e);
123:
124: }
125:
126: if (callOnUpdate) {
127: onUpdate(target);
128: }
129:
130: }
131:
132: /**
133: * Listener invoked on the ajax request. This listener is invoked after the
134: * component's model has been updated.
135: *
136: * @param target
137: */
138: protected abstract void onUpdate(AjaxRequestTarget target);
139:
140: /**
141: * Called to handle any error resulting from updating form component. Errors
142: * thrown from {@link #onUpdate(AjaxRequestTarget)} will not be caught here.
143: *
144: * @param target
145: * @param e
146: */
147: protected void onError(AjaxRequestTarget target, RuntimeException e) {
148: throw e;
149: }
150: }
|