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