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