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.markup.html.form;
018:
019: import org.apache.wicket.WicketRuntimeException;
020: import org.apache.wicket.markup.ComponentTag;
021: import org.apache.wicket.model.IModel;
022: import org.apache.wicket.util.convert.ConversionException;
023: import org.apache.wicket.util.string.StringValueConversionException;
024: import org.apache.wicket.util.string.Strings;
025:
026: /**
027: * HTML checkbox input component.
028: * <p>
029: * Java:
030: *
031: * <pre>
032: * form.add(new CheckBox("bool"));
033: * </pre>
034: *
035: * HTML:
036: *
037: * <pre>
038: * <input type="checkbox" wicket:id="bool" />
039: * </pre>
040: *
041: * </p>
042: * <p>
043: * You can can extend this class and override method
044: * wantOnSelectionChangedNotifications() to force server roundtrips on each
045: * selection change.
046: * </p>
047: *
048: * @author Jonathan Locke
049: */
050: public class CheckBox extends FormComponent implements
051: IOnChangeListener {
052: private static final long serialVersionUID = 1L;
053:
054: /**
055: * @see org.apache.wicket.Component#Component(String)
056: */
057: public CheckBox(final String id) {
058: super (id);
059: }
060:
061: /**
062: * @see org.apache.wicket.Component#Component(String, IModel)
063: */
064: public CheckBox(final String id, IModel model) {
065: super (id, model);
066: }
067:
068: /**
069: * @see org.apache.wicket.markup.html.form.IOnChangeListener#onSelectionChanged()
070: */
071: public void onSelectionChanged() {
072: convertInput();
073: updateModel();
074: onSelectionChanged(getModelObject());
075: }
076:
077: /**
078: * Template method that can be overriden by clients that implement
079: * IOnChangeListener to be notified by onChange events of a select element.
080: * This method does nothing by default.
081: * <p>
082: * Called when a option is selected of a dropdown list that wants to be
083: * notified of this event. This method is to be implemented by clients that
084: * want to be notified of selection events.
085: *
086: * @param newSelection
087: * The newly selected object of the backing model NOTE this is
088: * the same as you would get by calling getModelObject() if the
089: * new selection were current
090: */
091: protected void onSelectionChanged(Object newSelection) {
092: }
093:
094: /**
095: * Whether this component's onSelectionChanged event handler should called
096: * using javascript if the selection changes. If true, a roundtrip will be
097: * generated with each selection change, resulting in the model being
098: * updated (of just this component) and onSelectionChanged being called.
099: * This method returns false by default.
100: *
101: * @return True if this component's onSelectionChanged event handler should
102: * called using javascript if the selection changes
103: */
104: protected boolean wantOnSelectionChangedNotifications() {
105: return false;
106: }
107:
108: /**
109: * @see org.apache.wicket.MarkupContainer#getStatelessHint()
110: */
111: protected boolean getStatelessHint() {
112: if (wantOnSelectionChangedNotifications()) {
113: return false;
114: }
115: return super .getStatelessHint();
116: }
117:
118: /**
119: * Processes the component tag.
120: *
121: * @param tag
122: * Tag to modify
123: * @see org.apache.wicket.Component#onComponentTag(ComponentTag)
124: */
125: protected final void onComponentTag(final ComponentTag tag) {
126: checkComponentTag(tag, "input");
127: checkComponentTagAttribute(tag, "type", "checkbox");
128:
129: final String value = getValue();
130: if (value != null) {
131: try {
132: if (Strings.isTrue(value)) {
133: tag.put("checked", "checked");
134: } else {
135: // In case the attribute was added at design time
136: tag.remove("checked");
137: }
138: } catch (StringValueConversionException e) {
139: throw new WicketRuntimeException(
140: "Invalid boolean value \"" + value + "\"", e);
141: }
142: }
143:
144: // Should a roundtrip be made (have onSelectionChanged called) when the
145: // checkbox is clicked?
146: if (wantOnSelectionChangedNotifications()) {
147: final CharSequence url = urlFor(IOnChangeListener.INTERFACE);
148:
149: Form form = (Form) findParent(Form.class);
150: if (form != null) {
151: tag.put("onclick", form.getJsForInterfaceUrl(url));
152: } else {
153: // NOTE: do not encode the url as that would give invalid
154: // JavaScript
155: tag.put("onclick", "window.location.href='" + url
156: + "&" + getInputName()
157: + "=' + this.checked;");
158: }
159:
160: }
161:
162: super .onComponentTag(tag);
163: }
164:
165: /**
166: * @see FormComponent#supportsPersistence()
167: */
168: protected final boolean supportsPersistence() {
169: return true;
170: }
171:
172: /**
173: * @see org.apache.wicket.markup.html.form.FormComponent#convertValue(String[])
174: */
175: protected Object convertValue(String[] value) {
176: String tmp = value != null && value.length > 0 ? value[0]
177: : null;
178: try {
179: return Strings.toBoolean(tmp);
180: } catch (StringValueConversionException e) {
181: throw new ConversionException(
182: "Invalid boolean input value posted \""
183: + getInput() + "\"", e)
184: .setTargetType(Boolean.class);
185: }
186: }
187: }
|