001: /*
002: * HBasicWidgets.java
003: *
004: * Created on March 21, 2006, 2:00 PM
005: *
006: * To change this template, choose Tools | Options and locate the template under
007: * the Source Creation and Management node. Right-click the template and choose
008: * Open. You can then make changes to the template in the Source Editor.
009: */
010:
011: package simpleorm.simplehtml;
012:
013: import java.util.LinkedHashMap;
014: import java.util.Map.Entry;
015:
016: /**
017: * Simple Widgets, used from HSuperRequestlet as w.*
018: * @author aberglas
019: */
020: public class HBasicWidgets {
021:
022: HSuperRequestlet sreq;
023: /** field name --> error messages. */
024: LinkedHashMap<String, String> errorMessages = new LinkedHashMap();
025:
026: HBasicWidgets(HSuperRequestlet sreq) {
027: this .sreq = sreq;
028: }
029:
030: private void outHtml(String html) {
031: sreq.outHtml(html);
032: }
033:
034: private void endTag(String extras) {
035: if (extras != null) {
036: outHtml(" ");
037: outHtml(extras);
038: }
039: outHtml(">\n");
040: }
041:
042: /** <INPUT NAME=name SIZE=size VALUE=request.name extras> */
043: public void input(String name, int length, String extras) {
044: outHtml("<INPUT name='");
045: sreq.outEscaped(name);
046: outHtml("' id='");
047: sreq.outEscaped(name);
048: outHtml("' size=" + length + " value='");
049: sreq.outEscaped(sreq.paramattr(name, ""));
050: outHtml("'");
051: endTag(extras);
052: }
053:
054: public void input(String name, int length) {
055: input(name, length, null);
056: }
057:
058: /** <INPUT TYPE=CHECKBOX NAME=name CHECKED=CHECKED if request.name != null> <p>
059: * Note that if there are multiple checkboxes they should each be given a unique name, not a value.
060: */
061: public void checkbox(String name, String extras) {
062: outHtml("<INPUT type=checkbox name='");
063: sreq.outEscaped(name);
064: outHtml("' id='");
065: sreq.outEscaped(name);
066: outHtml("'");
067: if (sreq.paramattr(name) != null)
068: outHtml(" checked=checked ");
069: endTag(extras);
070: }
071:
072: public void checkbox(String name) {
073: checkbox(name, null);
074: }
075:
076: /** <INPUT TYPE=RADIO NAME=name CHECKED=CHECKED if request.name == valuel> <p>
077: * Multiple radio buttons can be given the same name as only one can be checked.
078: * Value must not be null. id = name + '__' + value, must be unique for each button.
079: */
080: public void radio(String name, String value, String extras) {
081: outHtml("<INPUT type=radio name='");
082: sreq.outEscaped(name);
083: outHtml("' id='");
084: sreq.outEscaped(name + "__" + value);
085: outHtml("' value= '");
086: sreq.outEscaped(value);
087: outHtml("' ");
088: if (value.equals(sreq.paramattr(name)))
089: outHtml(" checked=checked ");
090: endTag(extras);
091: }
092:
093: public void radio(String name, String value) {
094: radio(name, value, null);
095: }
096:
097: /** select with escaped options. */
098: public void select(String name, String extras, String[] options) {
099: outHtml("<SELECT name='");
100: sreq.outEscaped(name);
101: outHtml("'");
102: endTag(extras);
103: for (int ox = 0; ox < options.length + 1; ox++) {
104: String option = ox == 0 ? "" : options[ox - 1];
105: outHtml(" <OPTION value='");
106: sreq.outEscaped(option);
107: outHtml("'");
108: if (option != null && option.equals(sreq.paramattr(name)))
109: outHtml(" selected=selected");
110: outHtml(">\n");
111: sreq.outEscaped(option);
112: outHtml("</OPTION>\n");
113: }
114: outHtml("</SELECT>\n");
115: }
116:
117: /** select with combo option. */
118: public void selectCombo(String name, String extras, String[] options) {
119: select(name, extras, options);
120: outHtml(" ");
121: input(name, 20, extras); // ### broken.
122: }
123:
124: /** Hidden input, to preserve state. NOT Encrypted or signed. */
125: public void hidden(String name, String value) {
126: outHtml("<INPUT type=hidden name='");
127: sreq.outEscaped(name);
128: outHtml("' id='");
129: sreq.outEscaped(name);
130: outHtml("' value='");
131: sreq.outEscaped(value);
132: outHtml("'>\n");
133: }
134:
135: /** <INPUT TYPE=SUBMIT NAME=name CHECKED=CHECKED if request.name == valuel> <p>
136: * Multiple radio buttons can be given the same name as only one can be checked.
137: * Value must not be null. Name + value must be unique for each button.
138: */
139: public void submit(String name, String value, String extras) {
140: outHtml("<INPUT type=submit name='");
141: sreq.outEscaped(name);
142: outHtml("' value= '");
143: sreq.outEscaped(value);
144: outHtml("' ");
145: endTag(extras);
146: }
147:
148: /** Default name is "f.submit" */
149: public void submit(String value) {
150: submit("f.submit", value, null);
151: }
152:
153: /** <FORM>
154: * Always posts back to current page.
155: */
156: public void form() {
157: outHtml("<FORM>\n"); // ### Change to POST in production, but get is handy!
158: }
159:
160: public void _form() {
161: outHtml("</FORM>\n");
162: }
163:
164: public void p() {
165: outHtml("<P>\n");
166: }
167:
168: public void br() {
169: outHtml("<br>\n");
170: }
171:
172: public void hr() {
173: outHtml("<hr>\n");
174: }
175:
176: /** p hr p */
177: public void phr() {
178: outHtml("<p><hr><p>\n");
179: }
180:
181: public void center() {
182: outHtml("<center>");
183: }
184:
185: public void _center() {
186: outHtml("</center>\n");
187: }
188:
189: /**
190: * Produces an a to requestlet clazz with description from
191: * its getShortTitle.
192: */
193: public void a(Class clazz) {
194: HSuperRequestlet req = sreq.registeredInstance(clazz);
195: a(req.this Url(), req.getShortTitle());
196: }
197:
198: /** Just output an achor.
199: * displayHtml escaped but defaults to the url itself. Both with spaces as nbsp;
200: */
201: public void a(String url, String displayHtml) {
202: outHtml("<a href='");
203: outHtml(url);
204: outHtml("'>");
205: if (displayHtml != null)
206: sreq.outEscaped(displayHtml, true);
207: else
208: sreq.outEscaped(url, true);
209: outHtml("</a>\n");
210: }
211:
212: /** Currently just outputs html, but could check nesting levels later. */
213: public void table() {
214: outHtml("<table>\n");
215: }
216:
217: public void table(String extras) {
218: outHtml("<table " + extras + ">\n");
219: }
220:
221: public void table_border() {
222: outHtml("<table border=1 cellspacing=0 cellpadding=5>\n");
223: }
224:
225: public void table_border(String extras) {
226: outHtml("<table border=1 cellspacing=0 cellpadding=4 " + extras
227: + ">\n");
228: }
229:
230: public void _table() {
231: outHtml("</table>\n");
232: }
233:
234: public void tr() {
235: outHtml("<tr>");
236: }
237:
238: public void _tr() {
239: outHtml("</tr>\n");
240: }
241:
242: public void td() {
243: outHtml("<td>");
244: }
245:
246: public void td(String extras) {
247: outHtml("<td " + (extras != null ? extras : "") + ">");
248: }
249:
250: public void td_top() {
251: outHtml("<td valign=top>");
252: }
253:
254: public void td_top(String extras) {
255: outHtml("<td valign=top " + (extras != null ? extras : "")
256: + ">");
257: }
258:
259: public void td_right() {
260: outHtml("<td align=right>");
261: }
262:
263: public void td_center() {
264: outHtml("<td align=center>");
265: }
266:
267: public void td_center(String extras) {
268: outHtml("<td align=center " + extras + ">");
269: }
270:
271: public void _td() {
272: outHtml("</td>\n");
273: }
274:
275: public void tableHeadings(String... headings) {
276: tr();
277: for (String head : headings) {
278: td_top();
279: prompt(head);
280: _td();
281: }
282: _tr();
283: }
284:
285: /** outputs <IMG with name localized using localUrl. */
286: public void localImg(String name, String extras) {
287: outHtml("<img src='");
288: outHtml(sreq.localUrl(name));
289: outHtml("'");
290: if (extras != null)
291: outHtml(extras);
292: outHtml(">");
293: }
294:
295: public void localImg(String name) {
296: localImg(name, null);
297: }
298:
299: /**
300: * Outputs escaped data values, wrapped in <CITE>
301: */
302: public void data(String data) {
303: outHtml("<cite>");
304: if (data != null)
305: sreq.outEscaped(data);
306: else
307: sreq.outHtml(" "); // for within tables.
308: outHtml("</cite>");
309: }
310:
311: /**
312: * Outputs escaped weak Data values, wrapped in <CITE class=weak-data>
313: */
314: public void weakData(String data) {
315: outHtml("<cite class=weak-data>");
316: if (data != null)
317: sreq.outEscaped(data);
318: else
319: sreq.outHtml(" "); // for within tables.
320: outHtml("</cite>");
321: }
322:
323: /**
324: * Outputs escaped data with class=strong-data.
325: */
326: public void strongData(String data) {
327: strongData(data, false);
328: }
329:
330: public void strongData(String data, boolean nbsp) {
331: outHtml("<cite class=strong-data>");
332: sreq.outEscaped(data, nbsp);
333: outHtml("</cite>");
334: }
335:
336: /**
337: * Outputs preformatted values, wrapped in a PRE, escaped.
338: */
339: public void preformatted(String data) {
340: outHtml("<pre>");
341: sreq.outEscaped(data);
342: outHtml("</pre>");
343: }
344:
345: /** Heading (H3), not escaped. */
346: public void subheading(String head) {
347: outHtml("<h4>" + head + "</h4>\n");
348: }
349:
350: /**
351: *Outputs a prompt, wrapping in <EM>
352: *NOT escaped
353: */
354: public void prompt(String prompt) {
355: outHtml("<em>");
356: outHtml(prompt);
357: outHtml("</em>");
358: }
359:
360: /**
361: *Outputs a bold prompt, wrapping in <EM class=strong-prompt>
362: *NOT escaped
363: */
364: public void strongPrompt(String prompt) {
365: outHtml("<em class=strong-prompt>");
366: outHtml(prompt);
367: outHtml("</em>");
368: }
369:
370: /**
371: *Outputs a bold prompt, wrapping in <EM class=stronger-prompt>
372: *NOT escaped
373: */
374: public void strongerPrompt(String prompt) {
375: outHtml("<em class=stronger-prompt>");
376: outHtml(prompt);
377: outHtml("</em>");
378: }
379:
380: /** Just output message with class=error-message. Escaped.*/
381: public void errorMessage(String message) {
382: outHtml("<span class=error-message>");
383: sreq.outEscaped(message);
384: outHtml("</span>\n");
385: }
386:
387: /** Mark field with an error message which will be displayed later by fieldPrompt etc.
388: * Message should end in a "." so that others can be appended. Escaped.
389: * The message is recorded in errorMessages. */
390: public void addFieldError(String field, String message) {
391: String prev = errorMessages.get(field);
392: String msg = (prev == null ? "" : (prev + " ")) + message;
393: errorMessages.put(field, msg);
394: }
395:
396: /** Add an error not associated with a field.
397: * Just displayed at front.
398: */
399: public void addError(String message) {
400: String key = NON_FIELD + errorMessages.size() + 1;
401: errorMessages.put(key, message);
402: }
403:
404: private static final String NON_FIELD = "_NonField_";
405:
406: /** Outputs any error messages for field that were recorded by addFieldError. */
407: public void outputFieldErrorMessages(String field) {
408: String msg = errorMessages.get(field);
409: if (msg != null)
410: errorMessage(msg);
411: }
412:
413: /** Outputs all error messages, as would happen at the top of a form.
414: * class=all-errors */
415: public void outputAllErrorMessages() {
416: boolean any = false;
417: for (Entry<String, String> ent : errorMessages.entrySet()) {
418: if (!any)
419: outHtml("<Div class=all-errors>\n");
420: any = true;
421: String field = ent.getKey();
422: if (!field.startsWith(NON_FIELD)) {
423: sreq.outEscaped(field);
424: outHtml(":   ");
425: }
426: sreq.outEscaped(ent.getValue());
427: outHtml("<br>\n");
428: }
429: if (any)
430: outHtml("</Div><P>\n");
431: }
432:
433: public boolean hasErrors() {
434: return errorMessages.size() > 0;
435: }
436:
437: /** Fixed size prompt for a field (uses a float).
438: * name used to set label for=, good for disabilities?
439: */
440: public void fieldPrompt(String prompt, String inputName) {
441: outHtml("<label class=field-label for='");
442: sreq.outEscaped(inputName);
443: outHtml("'>");
444: prompt(prompt);
445: outHtml("</label>");
446: }
447:
448: /** Prompt defaults to input name. */
449: public void fieldPrompt(String inputName) {
450: fieldPrompt(inputName, inputName);
451: }
452:
453: /**
454: * Prompt + Input field. spaced out on a line.
455: * For more complex UIs use the building blocks!.
456: */
457: public void field(String inputName, int length, String prompt) {
458: fieldPrompt(prompt, inputName);
459: input(inputName, length, "style='margin:1'");
460: outHtml(" ");
461: outputFieldErrorMessages(inputName);
462: outHtml("<br>\n");
463: }
464:
465: /** Prompt defaults to inputName, the normal case.
466: * (input name is used for error messages etc.)
467: */
468: public void field(String inputName, int length) {
469: field(inputName, length, inputName);
470: }
471: }
|