001: /* ***** BEGIN LICENSE BLOCK *****
002: * Version: MPL 1.1
003: * The contents of this file are subject to the Mozilla Public License Version
004: * 1.1 (the "License"); you may not use this file except in compliance with
005: * the License. You may obtain a copy of the License at
006: * http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: * for the specific language governing rights and limitations under the
011: * License.
012: *
013: * The Original Code is Riot.
014: *
015: * The Initial Developer of the Original Code is
016: * Neteye GmbH.
017: * Portions created by the Initial Developer are Copyright (C) 2006
018: * the Initial Developer. All Rights Reserved.
019: *
020: * Contributor(s):
021: * Felix Gnass [fgnass at neteye dot de]
022: *
023: * ***** END LICENSE BLOCK ***** */
024: package org.riotfamily.forms.element.select;
025:
026: import java.io.PrintWriter;
027: import java.util.ArrayList;
028: import java.util.Iterator;
029: import java.util.List;
030:
031: import org.riotfamily.common.beans.PropertyUtils;
032: import org.riotfamily.forms.AbstractEditorBase;
033: import org.riotfamily.forms.Editor;
034: import org.riotfamily.forms.ErrorUtils;
035: import org.riotfamily.forms.MessageUtils;
036: import org.riotfamily.forms.event.ChangeEvent;
037: import org.riotfamily.forms.event.ChangeListener;
038: import org.riotfamily.forms.event.JavaScriptEvent;
039: import org.riotfamily.forms.event.JavaScriptEventAdapter;
040: import org.springframework.util.Assert;
041:
042: /**
043: * Abstract superclass for elements that let the user choose from a set of
044: * options like selectboxes or radio button groups.
045: */
046: public abstract class AbstractSelectElement extends AbstractEditorBase
047: implements Editor, SelectElement, JavaScriptEventAdapter {
048:
049: private Object optionsModel;
050:
051: private String valueProperty;
052:
053: private String labelProperty;
054:
055: private String labelMessageKey;
056:
057: private boolean appendLabel;
058:
059: private OptionRenderer optionRenderer;
060:
061: private List options;
062:
063: private List listeners;
064:
065: public void setOptionRenderer(OptionRenderer optionRenderer) {
066: this .optionRenderer = optionRenderer;
067: }
068:
069: public void renderOption(Option option) {
070: optionRenderer.renderOption(option, getFormContext()
071: .getWriter());
072: }
073:
074: public void setValueProperty(String valueProperty) {
075: this .valueProperty = valueProperty;
076: }
077:
078: public void setLabelProperty(String labelProperty) {
079: this .labelProperty = labelProperty;
080: }
081:
082: public void setLabelMessageKey(String labelMessageKey) {
083: this .labelMessageKey = labelMessageKey;
084: }
085:
086: public void setAppendLabel(boolean appendLabelToMessageKey) {
087: this .appendLabel = appendLabelToMessageKey;
088: }
089:
090: public void setOptionsModel(Object optionsModel) {
091: this .optionsModel = optionsModel;
092: resetOptions();
093: setValue(null);
094: if (getFormListener() != null) {
095: getFormListener().elementChanged(this );
096: }
097: }
098:
099: public Object getOptionsModel() {
100: return optionsModel;
101: }
102:
103: public void render(PrintWriter writer) {
104: resetOptions();
105: super .render(writer);
106: }
107:
108: protected void resetOptions() {
109: options = null;
110: }
111:
112: protected final List getOptions() {
113: if (options == null) {
114: options = createOptions();
115: }
116: return options;
117: }
118:
119: protected List createOptions() {
120: List options = new ArrayList();
121: if (optionsModel != null) {
122: Iterator it = getForm().getOptionValues(optionsModel)
123: .iterator();
124: for (int i = 0; it.hasNext(); i++) {
125: Object item = it.next();
126: String label = getOptionLabel(item);
127: Object value = getOptionValue(item);
128: options.add(new Option(item, value, label, this ));
129: }
130: }
131: return options;
132: }
133:
134: protected String getOptionLabel(Object item) {
135: Object obj = item;
136: if (labelProperty != null) {
137: obj = PropertyUtils.getProperty(item, labelProperty);
138: }
139: String label = obj != null ? obj.toString() : null;
140: if (labelMessageKey != null) {
141: if (appendLabel) {
142: return MessageUtils.getMessage(this , labelMessageKey
143: + label, null, label);
144: } else {
145: return MessageUtils.getMessage(this , labelMessageKey,
146: new Object[] { obj }, label);
147: }
148: } else {
149: return label;
150: }
151: }
152:
153: protected Object getOptionValue(Object item) {
154: if (item == null) {
155: return null;
156: }
157: if (valueProperty != null) {
158: return PropertyUtils.getProperty(item, valueProperty);
159: } else {
160: return item;
161: }
162: }
163:
164: public int getOptionIndex(Option option) {
165: Assert.notNull(options);
166: return options.indexOf(option);
167: }
168:
169: protected abstract boolean hasSelection();
170:
171: protected void validate() {
172: if (isRequired() && !hasSelection()) {
173: ErrorUtils.rejectRequired(this );
174: }
175: }
176:
177: public int getEventTypes() {
178: if (listeners != null) {
179: return JavaScriptEvent.ON_CHANGE;
180: }
181: return 0;
182: }
183:
184: public void addChangeListener(ChangeListener listener) {
185: if (listeners == null) {
186: listeners = new ArrayList();
187: }
188: listeners.add(listener);
189: }
190:
191: protected void fireChangeEvent(Object newValue, Object oldValue) {
192: if (listeners != null) {
193: ChangeEvent event = new ChangeEvent(this , newValue,
194: oldValue);
195: Iterator it = listeners.iterator();
196: while (it.hasNext()) {
197: ChangeListener listener = (ChangeListener) it.next();
198: listener.valueChanged(event);
199: }
200: }
201: }
202:
203: }
|