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 java.util.List;
020:
021: import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
022: import org.apache.wicket.markup.ComponentTag;
023: import org.apache.wicket.model.IModel;
024:
025: /**
026: * A choice implemented as a dropdown menu/list.
027: * <p>
028: * Java:
029: *
030: * <pre>
031: * List SITES = Arrays.asList(new String[] { "The Server Side", "Java Lobby", "Java.Net" });
032: *
033: * // Add a dropdown choice component that uses Input's 'site' property to designate the
034: * // current selection, and that uses the SITES list for the available options.
035: * // Note that when the selection is null, Wicket will lookup a localized string to
036: * // represent this null with key: "id + '.null'". In this case, this is 'site.null'
037: * // which can be found in DropDownChoicePage.properties
038: * form.add(new DropDownChoice("site", SITES));
039: * </pre>
040: *
041: * HTML:
042: *
043: * <pre>
044: * <select wicket:id="site">
045: * <option>site 1</option>
046: * <option>site 2</option>
047: * </select>
048: * </pre>
049: *
050: * </p>
051: *
052: * <p>
053: * You can can extend this class and override method
054: * wantOnSelectionChangedNotifications() to force server roundtrips on each
055: * selection change.
056: * </p>
057: *
058: * @author Jonathan Locke
059: * @author Eelco Hillenius
060: * @author Johan Compagner
061: */
062: public class DropDownChoice extends AbstractSingleSelectChoice
063: implements IOnChangeListener {
064: private static final long serialVersionUID = 1L;
065:
066: /**
067: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String)
068: */
069: public DropDownChoice(final String id) {
070: super (id);
071: }
072:
073: /**
074: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String, List)
075: */
076: public DropDownChoice(final String id, final List choices) {
077: super (id, choices);
078: }
079:
080: /**
081: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String,
082: * List,IChoiceRenderer)
083: */
084: public DropDownChoice(final String id, final List data,
085: final IChoiceRenderer renderer) {
086: super (id, data, renderer);
087: }
088:
089: /**
090: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String,
091: * IModel, List)
092: */
093: public DropDownChoice(final String id, IModel model,
094: final List choices) {
095: super (id, model, choices);
096: }
097:
098: /**
099: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String,
100: * IModel, List, IChoiceRenderer)
101: */
102: public DropDownChoice(final String id, IModel model,
103: final List data, final IChoiceRenderer renderer) {
104: super (id, model, data, renderer);
105: }
106:
107: /**
108: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String,
109: * IModel)
110: */
111: public DropDownChoice(String id, IModel choices) {
112: super (id, choices);
113: }
114:
115: /**
116: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String,
117: * IModel,IModel)
118: */
119: public DropDownChoice(String id, IModel model, IModel choices) {
120: super (id, model, choices);
121: }
122:
123: /**
124: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String,
125: * IModel,IChoiceRenderer)
126: */
127: public DropDownChoice(String id, IModel choices,
128: IChoiceRenderer renderer) {
129: super (id, choices, renderer);
130: }
131:
132: /**
133: * @see org.apache.wicket.markup.html.form.AbstractChoice#AbstractChoice(String,
134: * IModel, IModel,IChoiceRenderer)
135: */
136: public DropDownChoice(String id, IModel model, IModel choices,
137: IChoiceRenderer renderer) {
138: super (id, model, choices, renderer);
139: }
140:
141: /**
142: * Called when a selection changes.
143: */
144: public final void onSelectionChanged() {
145: convertInput();
146: updateModel();
147: onSelectionChanged(getModelObject());
148: }
149:
150: /**
151: * Processes the component tag.
152: *
153: * @param tag
154: * Tag to modify
155: * @see org.apache.wicket.Component#onComponentTag(org.apache.wicket.markup.ComponentTag)
156: */
157: protected void onComponentTag(final ComponentTag tag) {
158: checkComponentTag(tag, "select");
159:
160: // Should a roundtrip be made (have onSelectionChanged called) when the
161: // selection changed?
162: if (wantOnSelectionChangedNotifications()) {
163: // url that points to this components IOnChangeListener method
164: final CharSequence url = urlFor(IOnChangeListener.INTERFACE);
165:
166: Form form = (Form) findParent(Form.class);
167: if (form != null) {
168: tag.put("onchange", form.getJsForInterfaceUrl(url));
169: } else {
170: tag
171: .put(
172: "onchange",
173: "window.location.href='"
174: + url
175: + "&"
176: + getInputName()
177: + "=' + this.options[this.selectedIndex].value;");
178: }
179: }
180:
181: super .onComponentTag(tag);
182: }
183:
184: /**
185: * Template method that can be overriden by clients that implement
186: * IOnChangeListener to be notified by onChange events of a select element.
187: * This method does nothing by default.
188: * <p>
189: * Called when a option is selected of a dropdown list that wants to be
190: * notified of this event. This method is to be implemented by clients that
191: * want to be notified of selection events.
192: *
193: * @param newSelection
194: * The newly selected object of the backing model NOTE this is
195: * the same as you would get by calling getModelObject() if the
196: * new selection were current
197: */
198: protected void onSelectionChanged(final Object newSelection) {
199: }
200:
201: /**
202: * Whether this component's onSelectionChanged event handler should be
203: * called using javascript <tt>window.location</tt> if the selection
204: * changes. If true, a roundtrip will be generated with each selection
205: * change, resulting in the model being updated (of just this component) and
206: * onSelectionChanged being called. This method returns false by default. If
207: * you wish to use Ajax instead, let
208: * {@link #wantOnSelectionChangedNotifications()} return false and add an
209: * {@link AjaxFormComponentUpdatingBehavior} to the component using the
210: * <tt>onchange</tt> event.
211: *
212: * @return True if this component's onSelectionChanged event handler should
213: * called using javascript if the selection changes
214: */
215: protected boolean wantOnSelectionChangedNotifications() {
216: return false;
217: }
218:
219: /**
220: * @see org.apache.wicket.MarkupContainer#getStatelessHint()
221: */
222: protected boolean getStatelessHint() {
223: if (wantOnSelectionChangedNotifications()) {
224: return false;
225: }
226: return super.getStatelessHint();
227: }
228: }
|