001: /* TextField.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: May 23, 2007 7:05:38 PM, Created by henrichen
010: }}IS_NOTE
011:
012: Copyright (C) 2007 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019:
020: package org.zkoss.mil.impl;
021:
022: import org.zkoss.lang.Objects;
023: import org.zkoss.mil.Item; //import org.zkoss.util.logging.Log;
024: import org.zkoss.xml.HTMLs;
025: import org.zkoss.zk.ui.WrongValueException;
026: import org.zkoss.zk.ui.event.Events;
027: import org.zkoss.zk.ui.ext.client.Inputable;
028:
029: /**
030: * TextField related component.
031: * @author henrichen
032: */
033: abstract public class InputElement extends Item {
034: protected static final int ANY = 0;
035: protected static final int EMAILADDR = 1;
036: protected static final int NUMERIC = 2;
037: protected static final int PHONENUMBER = 3;
038: protected static final int URL = 4;
039: protected static final int DECIMAL = 5;
040:
041: protected static final int PASSWORD = 0x10000;
042: protected static final int UNEDITABLE = 0x20000;
043: protected static final int SENSITIVE = 0x40000;
044: protected static final int NON_PREDICTIVE = 0x80000;
045: protected static final int INITIAL_CAPS_WORD = 0x100000;
046: protected static final int INITIAL_CAPS_SENTENCE = 0x200000;
047:
048: protected static final int CONSTRAINT_MASK = 0xffff;
049:
050: // private static final Log log = Log.lookup(InputElement.class);
051:
052: /** The value. */
053: private Object _value;
054: /** Used by setTextByClient() to disable sending back the value */
055: private String _txtByClient;
056: private int _maxlength = 32;
057: private boolean _readonly;
058:
059: /** Returns whether it is readonly.
060: * <p>Default: false.
061: */
062: public boolean isReadonly() {
063: return _readonly;
064: }
065:
066: /** Sets whether it is readonly.
067: */
068: public void setReadonly(boolean readonly) {
069: if (_readonly != readonly) {
070: _readonly = readonly;
071: smartUpdateConstraints();
072: }
073: }
074:
075: /** Returns the value in the String format.
076: * In most case, you shall use the setValue method instead, e.g.,
077: * {@link org.zkoss.mil.Textbox#getValue}.
078: *
079: * <p>It invokes {@link #coerceToString} to convert the stored value
080: * into a string.
081: *
082: * @exception WrongValueException if user entered a wrong value
083: */
084: public String getText() throws WrongValueException {
085: return coerceToString(_value);
086: }
087:
088: /** Sets the value in the String format.
089: * In most case, you shall use the setValue method instead, e.g.,
090: * {@link org.zkoss.mil.Textbox#setValue}.
091: *
092: * <p>It invokes {@link #coerceFromString}.
093: * Derives might override them for type conversion and special
094: * validation.
095: *
096: * @param value the value; If null, it is considered as empty.
097: */
098: public void setText(String value) throws WrongValueException {
099: final Object val = coerceFromString(value);
100:
101: if (!Objects.equals(_value, val)) {
102: _value = val;
103:
104: final String fmtval = coerceToString(_value);
105: if (_txtByClient == null
106: || !Objects.equals(_txtByClient, fmtval)) {
107: _txtByClient = null; //only once
108: smartUpdate("tx", fmtval); //text
109: }
110: //being sent back to the server.
111: } else if (_txtByClient != null) {
112: //value equals but formatted result might differ because
113: //our parse is more fault tolerant
114: final String fmtval = coerceToString(_value);
115: if (!Objects.equals(_txtByClient, fmtval)) {
116: _txtByClient = null; //only once
117: smartUpdate("tx", fmtval); //text
118: }
119: }
120: }
121:
122: /** Internal type of this InputElement (ANY, EMAILADDR, NUMERIC, PHONENUMBER,
123: * URL, or DECIMAL). */
124: abstract protected int getInternalType();
125:
126: /** Coerces the value passed to {@link #setText}.
127: *
128: * <p>Deriving note:<br>
129: * If you want to store the value in other type, say BigDecimal,
130: * you have to override {@link #coerceToString} and {@link #coerceFromString}
131: * to convert between a string and your targeting type.
132: *
133: * <p>Moreover, when {@link org.zkoss.mil.Textbox} is called, it calls this method
134: * with value = null. Derives shall handle this case properly.
135: */
136: abstract protected Object coerceFromString(String value)
137: throws WrongValueException;
138:
139: /** Coerces the value passed to {@link #setText}.
140: *
141: * <p>Default: convert null to an empty string.
142: *
143: * <p>Deriving note:<br>
144: * If you want to store the value in other type, say BigDecimal,
145: * you have to override {@link #coerceToString} and {@link #coerceFromString}
146: * to convert between a string and your targeting type.
147: */
148: abstract protected String coerceToString(Object value);
149:
150: /** Returns the maxlength.
151: * <p>Default: 32.
152: */
153: public int getMaxlength() {
154: return _maxlength;
155: }
156:
157: /** Sets the maxlength.
158: */
159: public void setMaxlength(int maxlength) {
160: if (_maxlength != maxlength) {
161: _maxlength = maxlength;
162:
163: smartUpdate("xs", maxlength); //maxSize
164: }
165: }
166:
167: /** Returns the type.
168: * <p>Default: text.
169: */
170: public String getType() {
171: return "text";
172: }
173:
174: //-- super --//
175: public String getInnerAttrs() {
176: final StringBuffer sb = new StringBuffer(64).append(super
177: .getInnerAttrs());
178:
179: HTMLs.appendAttribute(sb, "tx", coerceToString(_value)); //text, string
180: HTMLs.appendAttribute(sb, "xs", _maxlength); //maxSize
181: HTMLs.appendAttribute(sb, "cs", getConstraints()); //constraints
182:
183: return sb.toString();
184: }
185:
186: protected int getConstraints() {
187: int constraints = getInternalType();
188: if ("password".equals(getType())) {
189: constraints |= PASSWORD;
190: }
191: if (isReadonly()) {
192: constraints |= UNEDITABLE;
193: }
194: return constraints;
195: }
196:
197: protected void smartUpdateConstraints() {
198: smartUpdate("cs", getConstraints());
199: }
200:
201: public String getOuterAttrs() {
202: final StringBuffer sb = new StringBuffer(64).append(super
203: .getOuterAttrs());
204:
205: appendAsapAttr(sb, "onChange");
206: appendAsapAttr(sb, "onChanging");
207:
208: return sb.toString();
209: }
210:
211: /** Returns the value in the targeting type.
212: *
213: * @exception WrongValueException if the user entered a wrong value
214: * @see #getText
215: */
216: protected Object getTargetValue() throws WrongValueException {
217: return _value;
218: }
219:
220: /** Returns the raw value directly with checking whether any
221: * error message not yet fixed.
222: *
223: * @see #getRawText
224: * @see #getText
225: * @see #setRawValue
226: */
227: public Object getRawValue() {
228: return _value;
229: }
230:
231: /** Returns the text directly without checking whether any error
232: * message not yet fixed.
233: *
234: * @see #getRawValue
235: * @see #getText
236: */
237: public String getRawText() {
238: return coerceToString(_value);
239: }
240:
241: /** Sets the raw value directly. The caller must make sure the value
242: * is correct (or intend to be incorrect), because this method
243: * doesn't do any validation.
244: *
245: * <p>If you feel confusing with setValue, such as {@link org.zkoss.mil.Textbox#setValue},
246: * it is usually better to use setValue instead. This method
247: * is reserved for developer that really want to set an 'illegal'
248: * value (such as an empty string to a textbox with no-empty contraint).
249: *
250: * <p>Like setValue, the result is returned back to the server
251: * by calling {@link #getText}.
252: *
253: * @see #getRawValue
254: */
255: public void setRawValue(Object value) {
256: if (!Objects.equals(_value, value)) {
257: _value = value;
258: smartUpdate("value", coerceToString(_value));
259: }
260: }
261:
262: //-- ComponentCtrl --//
263: protected Object newExtraCtrl() {
264: return new ExtraCtrl();
265: }
266:
267: /** A utility class to implement {@link #getExtraCtrl}.
268: * It is used only by component developers.
269: */
270: protected class ExtraCtrl implements Inputable {
271: //-- Inputable --//
272: public void setTextByClient(String value)
273: throws WrongValueException {
274: _txtByClient = value;
275: try {
276: setText(value);
277: } catch (WrongValueException ex) {
278: throw ex;
279: } finally {
280: _txtByClient = null;
281: }
282: }
283: }
284: }
|