001 // Copyright (c) 2001 Hursh Jain (http://www.mollypages.org)
002 // The Molly framework is freely distributable under the terms of an
003 // MIT-style license. For details, see the molly pages web site at:
004 // http://www.mollypages.org/. Use, modify, have fun !
005
006 package fc.web.forms;
007
008 import javax.servlet.*;
009 import javax.servlet.http.*;
010 import java.io.*;
011 import java.util.*;
012 import java.util.regex.*;
013
014 import fc.jdbc.*;
015 import fc.io.*;
016 import fc.util.*;
017
018 /**
019 A HTML TextArea
020 */
021 public final class TextArea extends AbstractText
022 {
023 private WrapType wrap;
024 private int rows = 0;
025 private int cols = 0;
026 //private String classname = getClass().getName();
027
028 /**
029 Creates a new textarea element with a initial value of "" (the
030 empty string). No initial rows/cols are specified which will have
031 the effect of rendering this field with the browsers default.
032 **/
033 public TextArea(String name)
034 {
035 this(name, "", 0, 0);
036 }
037
038 /**
039 Creates a new textarea element with a initial value of "" and
040 the specified rows/cols.
041 **/
042 public TextArea(String name, int rows, int cols)
043 {
044 this(name, "", rows, cols);
045 }
046
047 /**
048 Creates a new text element with the specified initial value.
049 If the specified value is <tt>null</tt>, then the initial
050 value is set to "" (the empty string)
051 **/
052 public TextArea(String name, String value)
053 {
054 this(name, value, 0, 0);
055 }
056
057 /**
058 Creates a new text element with the specified initial value
059 and rows/cols.
060 **/
061 public TextArea(String name, String value, int rows, int cols)
062 {
063 super(name, value);
064 this.rows = rows;
065 this.cols = cols;
066 }
067
068 public Field.Type getType() {
069 return Field.Type.TEXTAREA;
070 }
071
072 public void renderImpl(FormData fd, Writer writer) throws IOException
073 {
074 String value = getRenderValue(fd);
075
076 writer.write("<textarea ");
077
078 if (! enabled || ! isEnabled(fd)) {
079 writer.write(" disabled");
080 }
081
082 writer.write(" name='");
083 writer.write(name);
084 writer.write("'");
085
086 if (rows > 0) {
087 writer.write(" rows='");
088
089 // this is tricky, Writer != PrintWriter
090 // and a int value will be treated as a character code
091 // so writer.write(10) will write a newline, not '10'
092 // writer.write(rows);
093 writer.write(String.valueOf(rows));
094 writer.write("'");
095 }
096
097 if (cols > 0) {
098 writer.write(" cols='");
099 writer.write(String.valueOf(cols));
100 writer.write("'");
101 }
102
103 if (wrap != null) {
104 writer.write(" wrap='");
105 writer.write(wrap.type);
106 writer.write("'");
107 }
108
109 if (renderStyleTag) {
110 writer.write(" style='");
111 writer.write(styleTag);
112 writer.write("'");
113 }
114
115 final int arlen = arbitraryString.size();
116 for (int n = 0; n < arlen; n++) {
117 writer.write(" ");
118 writer.write(arbitraryString.get(n).toString());
119 }
120
121 writer.write(">");
122 writer.write(sanitizedValue(value));
123 writer.write("</textarea>");
124 }
125
126
127 /**
128 This value (if set) is rendered as the html <tt>COLS</tt> tag.
129
130 @return this object for method chaining convenience
131 **/
132 public TextArea setCols(int cols) {
133 this.cols = cols;
134 return this;
135 }
136
137 /**
138 This value (if set) is rendered as the html <tt>ROWS</tt> tag.
139
140 @return this object for method chaining convenience
141 **/
142 public TextArea setRows(int rows) {
143 this.rows = rows;
144 return this;
145 }
146
147 /**
148 Sets the wrapping mode of this text box. This value (if set) is
149 rendered as the html <tt>WRAP</tt> tag. By default the wrap
150 value is not set (and hence not rendered).
151
152 @return this object for method chaining convenience
153 **/
154 public TextArea setWrap(WrapType wrap) {
155 this.wrap = wrap;
156 return this;
157 }
158
159 //we need to sanitize our value since if we set to "</textarea>"
160 //the browser will think the value indicates the end of the
161 //textarea
162 static final Pattern pat = Pattern.compile("(?i)</textarea>");
163 private String sanitizedValue(String value)
164 {
165 if ( value == null || value.equals("") ) {
166 return "";
167 }
168
169 Matcher matcher = pat.matcher(value);
170 String newval = matcher.replaceAll("</textarea>");
171 return newval;
172 }
173
174 /**
175 From the HTML spec:
176 <br>
177 <ol>
178 <li>OFF disables word wrap. Text the user types is
179 displayed with the exact line breaks that the user types.
180 If the user explicitly inserts a line break, however, the
181 break is included as part of the text area's value. The
182 user has to scroll horizontally to see the ends of lines
183 that do not fit in the text area element.
184 <li>HARD causes word wrap, and the line breaks are
185 included when the form is submitted. The text wraps inside
186 the text area element, and that the user does not need to
187 scroll horizontally.
188 <li>SOFT causes word wrap, but the line breaks are not
189 included when the form is submitted
190 </ol>
191 **/
192 public static class WrapType {
193 private String type;
194 private WrapType(String type) { this.type = type; }
195 public static final WrapType OFF = new WrapType ("off");
196 public static final WrapType HARD = new WrapType ("hard");
197 public static final WrapType SOFT = new WrapType ("soft");
198 }
199
200 } //~class TextArea