View Javadoc

1   /*
2    * $Source: /usr/cvsroot/jal/src/main/java/org/paneris/jal/model/HTMLUtil.java,v $
3    * $Revision: 1.24 $
4    *
5    * Copyright (C) 2002 Paneris
6    */
7   package org.paneris.jal.model;
8   
9   import java.sql.Connection;
10  import java.sql.ResultSet;
11  import java.sql.ResultSetMetaData;
12  import java.sql.SQLException;
13  import java.sql.Statement;
14  import java.text.SimpleDateFormat;
15  import java.util.Calendar;
16  import java.util.Enumeration;
17  import java.util.Hashtable;
18  
19  import org.paneris.util.ExtendedHash;
20  
21  import org.apache.oro.text.regex.MalformedPatternException;
22  import org.apache.oro.text.regex.Pattern;
23  import org.apache.oro.text.regex.PatternCompiler;
24  import org.apache.oro.text.regex.PatternMatcher;
25  import org.apache.oro.text.regex.Perl5Compiler;
26  import org.apache.oro.text.regex.Perl5Matcher;
27  import org.apache.oro.text.regex.StringSubstitution;
28  import org.apache.oro.text.regex.Util;
29  
30  /**
31   * <p> 
32   * Output format (HTML) dependant formatters.
33   * </p>
34   *
35   * @author  Paneris
36   * @author  timp@paneris.org
37   **/
38  
39  
40  public final class HTMLUtil {
41  
42    private static final String[] months = {"dummy","Jan","Feb","Mar","Apr",
43                            "May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
44  
45  
46    /**
47     * Do basic escaping of html text
48     *
49     * @param htm   a String to escape
50     * @return      the escaped string
51     */
52    public static String escapeHTML(String htm) {
53      ExtendedHash escapeHash = new ExtendedHash();
54        escapeHash.put("&","&amp;");
55        escapeHash.put("<","&lt;");
56        escapeHash.put(">","&gt;");
57        escapeHash.put("\"","&quot;");
58      return escape(htm, escapeHash);
59    }
60  
61    public static String escapeJavascript(String s) {
62        ExtendedHash escapeHash = new ExtendedHash();
63        escapeHash.put("\"","\\\"");
64        return escape(s, escapeHash);
65    }
66  
67    public static String escape(String s, ExtendedHash h) {
68      PatternCompiler compiler = new Perl5Compiler();
69      PatternMatcher matcher = new Perl5Matcher();
70      String result = s;
71      for (Enumeration en = h.keys() ; en.hasMoreElements() ;) {
72        String regularExpression = (String) en.nextElement();
73        try {
74          Pattern pattern = compiler.compile(regularExpression);
75          result = Util.substitute(
76                    matcher, pattern, new StringSubstitution((String) h.get(regularExpression)), 
77                    result, Util.SUBSTITUTE_ALL);
78        } catch (MalformedPatternException e) {
79        throw new RuntimeException
80            ("MalformedPatternException: " + e.toString());
81        }
82      }
83      return result;
84    }
85  
86  
87  
88    /**
89     * Return a drop down list (HTML select tag) where the options
90     * are the rows of a ResultSet. When an option is selected its
91     * value is copied into the input box called name.
92     * <p>
93     * Each row of the ResultSet should have only one value
94     * Each row becomes an HTML option tag
95     * <P>
96     * Unique only puts an element into the select box if it's
97     * value is not already
98     * <P>
99     * Takes a selectvalue so that the correct option can be chosen
100    * <P>
101    * You can also add an extra option using allName and allValue
102    *
103    * @param rs          a list of value pairs
104    * @param name        the name of the input box to copy to
105    * @param unique      make sure that each entry has a different value
106    * @param allValue    the value of first option on select
107    * @param allName     the name of first value on select
108    * @param selectValue the entry to be selected by default
109    * @return            a HTML select tag
110    */
111   public static String getLinkedSelect(ResultSet rs, String name, 
112                    boolean unique, String allName, String selectValue) 
113     throws Exception {
114     return getLinkedSelect(rs,name,unique,"0",allName,selectValue);
115   }
116 
117   public static String getLinkedSelect(ResultSet rs, String name,
118                     boolean unique, 
119                     String allValue, String allName, String selectValue) 
120   throws Exception {
121     String result = "<select name=\""+name+"s\" onchange=\""+name+
122               ".value = options[selectedIndex].value;return true;\">\n";
123     if (allName != null) {
124       if (allValue == null) allValue = "";
125       result += "<option value=\"" + allValue + "\">" + 
126                                      allName + "</option>\n";
127     }
128     Hashtable values = new Hashtable();
129     while (rs.next()) {
130       String value = new String(rs.getString(1));
131       String display = value;
132       if (((ResultSetMetaData) rs.getMetaData()).getColumnCount() >= 2) {
133         display = new String(rs.getString(2));
134       } 
135       if (!unique || (unique && !values.containsKey(value))) {
136         values.put(value,display);
137         result += "<option value=\"" + value +"\"";
138         if (selectValue != null && value.equals(selectValue))
139           result += " selected";
140         result += ">" + display + "</option>\n";
141       }
142     }
143     result += "</select>";
144     return result;
145   }
146 
147 
148  /**
149   * Return a drop down list (select tag) from a DDField where the
150   * options are given by the possible values of that Field.
151   * <p>
152   * You can add another option using allName and allValue so long
153   * as mandatory is not set
154   * <p>
155   * The current value of the DDField is used to decide which option is
156   * selected by default
157   *
158   * @param dd        a DDField which we want to create a select box for
159   *                  This may be a field in a lookup table
160   * @param db        name of the database to query
161   * @param fieldname the name of the field (and the select tag)
162   *                  This may be the name of the field containing the lookup
163   * @param mandatory if 'false' then a default extra option ("None") is
164   *                  added, unless allName is set
165   * @param unique    ensure that each entry has a different value
166   * @param allValue  the value of first option on select
167   * @param allName   the name of first value on select
168   * @return          a HTML select tag
169   */
170   public static String getLinkedSelect(DDField ddf, String db, 
171                                      String fieldname, boolean mandatory, 
172                                      boolean unique, String allName)
173     throws Exception {
174       return getLinkedSelect(ddf,db,fieldname,mandatory,unique,"0",allName);
175   }
176 
177   public static String getLinkedSelect(DDField ddf, String db, 
178                                          String allName) throws Exception {
179     return getLinkedSelect(ddf,db,ddf.getMetaData().getFieldName(),
180                            allName==null,true,"0",allName);
181   }
182 
183   public static String getLinkedSelect(DDField ddf, String db, 
184                                      String fieldname,
185                                      boolean mandatory, boolean unique,
186                                      String allValue, String allName)
187     throws Exception {
188 
189       Connection conn = null;
190       Statement s = null;
191 
192       DBConnectionManager connMgr = DBConnectionManager.getInstance();
193       String returnString = "<select name=\""+fieldname+"s\" onchange=\""+
194                             fieldname+".value = " + 
195                             "options[selectedIndex].value;return true;\">\n";
196       if (!mandatory || allName != null) {
197         if (allName == null) allName = "None";
198         if (allValue == null) allValue = "";
199         returnString += "<option value=\"" + allValue + "\">" + 
200                         allName + "</option>\n";
201       }
202       try {
203         conn = connMgr.getConnection("HTMLUtil",db);
204         s = conn.createStatement();
205         String sqlString = new String("SELECT  ");
206         sqlString += ddf.getMetaData().getFieldName() + " FROM " + 
207                      ddf.getMetaData().getTableName();
208         if (!ddf.getMetaData().getType().equals("textarea") &&
209             !ddf.getMetaData().getType().equals("preformattedtextarea")) {
210           sqlString += " ORDER BY " + ddf.getMetaData().getFieldName();
211         }
212         ResultSet rs = s.executeQuery(sqlString);
213         while (rs.next()) {
214           String value = rs.getString(1);
215           if (value != null) {
216             value = value.trim();
217             returnString += "<option value=" + value;
218             if ((ddf.getValue() != null) && 
219                 (value.equals(ddf.getValue().toString())))
220                         returnString += " selected";
221             returnString += ">" + value + "</option>\n";
222           }
223         }
224         returnString += "</select>\n";
225         connMgr.freeConnection(db, conn);
226         return returnString;
227       } catch (Exception e) {
228         throw new Exception("Failed to build LinkedSelect:" + e.toString());
229       }  finally {
230         s.close();
231         connMgr.freeConnection(db, conn);
232       }
233     }
234 
235 
236 
237 
238     /**
239      * Return a drop down list (HTML select tag) where the options
240      * are defined by the records returned by an SQL query.
241      * <p>
242      * Unique only puts an element into the select box if it's
243      * value is not already
244      * <P>
245      *
246      * @param db          name of the database to query
247      * @param sqlString   the SQL query to evaluate
248      * @param name        the name of the select tag
249      * @param unique      make sure that each entry has a different value
250      * @param allValue    the value of first option on select
251      * @param allName     the name of first value on select
252      * @param selectValue the value which should be selected
253      * @return            a HTML select tag
254      */
255 
256     public static String getLinkedSelect(String db, String sqlString, 
257                        String name,
258                        boolean unique, String allName)
259       throws Exception {
260         return getLinkedSelect(db, sqlString, name, unique, "0", allName, null);
261     }
262 
263     public static String getLinkedSelect(String db, String sqlString, 
264                                          String name, boolean unique)
265       throws Exception {
266         return getLinkedSelect(db, sqlString, name, unique, null, null, null);
267     }
268 
269     public static String getLinkedSelect(String db, String sqlString, 
270                                          String name) 
271       throws Exception {
272         return getLinkedSelect(db, sqlString, name, false, null, null, null);
273     }
274     public static String getLinkedSelect(String db, String sqlString, 
275                                          String name, 
276                                          boolean unique, 
277                                          String allValue, String allName, 
278                                          String selectValue
279                                          )
280       throws Exception {
281         DBConnectionManager connMgr = DBConnectionManager.getInstance();
282         Connection conn = connMgr.getConnection("HTMLUtil",db);
283         if (conn == null) throw new RuntimeException("can't get connection: " + db);
284         Statement s = conn.createStatement();
285         ResultSet rs = null;
286         try {
287            rs = s.executeQuery(sqlString);
288         } catch (Exception e) {
289             throw new Exception("Problem with query (" + sqlString + "):" +e.toString());
290         }  finally {
291             s.close();
292             connMgr.freeConnection(db, conn);
293         }
294         connMgr.freeConnection(db, conn);
295         return getLinkedSelect(rs, name, unique, allValue, allName, selectValue);
296     }
297 
298   /**
299    * Return a drop down list (HTML select tag) where the options
300    * are the rows of a ResultSet.
301    * <p>
302    * It is assumed that each row of the ResultSet has at least
303    * 2 fields in it - the first is used as the value of the
304    * option, the 2nd is the displayed value. Each row becomes
305    * a HTML option tag
306    * <P>
307    * Unique only puts an element into the select box if it's
308    * value is not already
309    * <P>
310    * Takes a selectvalue so that the correct option can be chosen
311    * <P>
312    * You can also add an extra option using allName and allValue
313    *
314    * @param rs         a list of value/display pairs
315    * @param name       the name of the select tag
316    * @param unique     make sure that each entry has a different value
317    * @param allValue   the value of first option on select
318    * @param allName    the name of first value on select
319    * @param selectValue a String indicating the entry to be selected by default
320    * @return           a HTML select tag
321    */
322    public static String getDropDown(ResultSet rs, String name, boolean unique,
323                                      String allName, String selectValue) 
324      throws Exception {
325         return getDropDown(rs, name, unique, "0",  allName, selectValue);
326    } 
327    public static String getDropDown(ResultSet rs, String name, boolean unique,
328                                      String allName) 
329      throws Exception {
330        return getDropDown(rs, name, unique, "0",  allName, null);
331    }
332    public static String getDropDown(ResultSet rs, String name, boolean unique)
333      throws Exception {
334         return getDropDown(rs, name, unique, null, null,    null);
335    }
336    public static String getDropDown(ResultSet rs, String name) 
337      throws Exception {
338        return getDropDown(rs, name, false,  null, null,    null);
339    }
340 
341   public static String getDropDown(ResultSet rs, String name, boolean unique,
342                                     String allValue, String allName, 
343                                     String selectValue) 
344     throws Exception {
345       String result = "<select name=\""+name+"\">\n";
346       if (allValue == null) allValue = "";
347       if (allName != null) {
348         result += "<option value=\"" + allValue + "\">" + allName + 
349                   "</option>\n";
350       }
351       Hashtable values = new Hashtable();
352       try {
353         while (rs.next()) {
354           String value = new String(rs.getString(1));
355           String display = value;
356           if (((ResultSetMetaData) rs.getMetaData()).getColumnCount() >= 2) {
357             display = new String(rs.getString(2));
358           } 
359           if (!unique || (unique && !values.containsKey(value))) {
360             values.put(value,display);
361             result += "<option value=\"" + value +"\"";
362             if (selectValue != null && value.equals(selectValue))
363               result += " selected";
364               result += ">" + display + "</option>\n";
365             }
366          }
367          result += "</select>";
368        } catch (SQLException e) {
369          throw new Exception("More than one field required in getDropDown:" + 
370                               e.toString());
371        } 
372        return result;
373   }
374 
375 
376   /**
377    * Return a drop down list (HTML select tag) where the options
378    * are defined by the records returned by an SQL query.
379    * <p>
380    * It is assumed that the query returns a ResultSet in which
381    * each row has at least 2 fields in it - the first is used as
382    * the value of the option, the 2nd is the displayed value. Each
383    * row becomes a HTML option tag
384    * <P>
385    * Unique only puts an element into the select box if it's
386    * value is not already
387    * <P>
388    *
389    * @param db          name of the database to query
390    * @param sqlString   the SQL query to evaluate
391    * @param name        the name of the select tag
392    * @param unique      ensure that each entry has a different value
393    * @param allValue    the value of first option on select
394    * @param allName     the name of first value on select
395    * @param selectValue The String to be selected by default
396    * @return            a HTML select tag
397    */
398    public static String getDropDown(String db, String sqlString, String name) 
399      throws Exception {
400        return getDropDown(db, sqlString, name, false, null,null,null);
401    }
402    public static String getDropDown(String db, String sqlString, String name, 
403                                     boolean unique)
404      throws Exception {
405        return getDropDown(db, sqlString, name, unique, null, null, null);
406    }
407    public static String getDropDown(String db, String sqlString, String name, 
408                                     boolean unique, String allName)
409      throws Exception {
410        return getDropDown(db, sqlString, name, unique, "0", allName, null);
411    }
412    public static String getDropDown(String db, String sqlString, String name, 
413                                     boolean unique, String allName, 
414                                     String selectValue)
415      throws Exception {
416        return getDropDown(db, sqlString, name, unique, "0", allName, selectValue);
417    }
418 
419    public static String getDropDown(String db, String sqlString, String name, 
420                                     boolean unique, String allName, 
421                                     String allValue, String selectValue)
422      throws Exception {
423        DBConnectionManager connMgr = DBConnectionManager.getInstance();
424        Connection conn = connMgr.getConnection("HTMLUtil",db);
425        if (conn == null) throw 
426                           new RuntimeException("can't get connection: " + db);
427        Statement s = conn.createStatement();
428        ResultSet rs = null;
429        try {
430           rs = s.executeQuery(sqlString);
431           return getDropDown(rs, name, unique, allName, 
432                              allValue, selectValue);
433        } catch (Exception e) {
434            throw new Exception("Problem with query (" + sqlString + "):" +e.toString());
435        }  finally {
436            s.close();
437            connMgr.freeConnection(db, conn);
438        }
439    }
440 
441 
442 
443     /**
444      * Return a drop down list (select tag) from a DDField where the
445      * options are given by the possible values of that Field.
446      * <p>
447      * This field should be a field linked (in the datadictionary)
448      * to another table. The contents of (each record of) that table
449      * are used to create the select box. Also, the field could be
450      * a boolean field.
451      * <p>
452      * You can add another option using allName and allValue if mandatory is not set
453      * <p>
454      * The current value of the DDField is used to decide which option is
455      * selected by default
456      *
457      * @param ddf         a DDField which we want to create a select box for
458      *                      This is a field in a lookup table
459      * @param db        name of the database to query
460      * @param fieldname     the name of the field (and the select tag)
461      *                      This is the name of the field containing the lookup
462      * @param mandatory     if 'false' then a default extra option ("None") is
463      *                      added, unless allName is set
464      * @param allValue    the value of first option on select
465      * @param allName    the name of first value on select
466      * @return              a HTML select tag
467      */
468     public static String getDropDown(DDField ddf, String db, String allName) throws Exception {
469         return getDropDown(ddf,db,ddf.getMetaData().getFieldName(),allName==null,"0",allName);
470     }
471 
472     public static String getDropDown(DDField ddf, String db, String fieldname,
473                                      boolean mandatory, String allValue, String allName)
474                                                          throws Exception {
475 
476         Connection conn = null;
477         Statement s = null;
478 
479         DBConnectionManager connMgr = DBConnectionManager.getInstance();
480         String returnString = ("<select name=" + fieldname + ">\n");
481         if (!mandatory || allName != null) {
482             if (allName == null) allName = "None";
483             if (allValue == null) allValue = "";
484             returnString += "<option value=\"" + allValue + "\">" + allName + "</option>\n";
485         }
486         try {
487             conn = connMgr.getConnection("HTMLUtil",db);
488             s = conn.createStatement();
489             String sqlString = new String("SELECT id, ");
490             sqlString += ddf.getMetaData().getFieldName() + " FROM " + ddf.getMetaData().getTableName();
491             if (!ddf.getMetaData().getType().equals("textarea") &&
492                 !ddf.getMetaData().getType().equals("preformattedtextarea")
493                ) {
494                 sqlString += " ORDER BY " + ddf.getMetaData().getFieldName();
495             }
496             ResultSet rs = s.executeQuery(sqlString);
497             while (rs.next()) {
498                 String lookupId = rs.getString(1).trim();
499                 String lookupValue = rs.getString(2);
500                 if (lookupValue != null) {
501                     lookupValue = lookupValue.trim();
502                     returnString += "<option value=" + lookupId;
503                     if ((ddf.getValue() != null) && (lookupId.equals(ddf.getValue().toString())))
504                         returnString += " selected";
505                     returnString += ">" + lookupValue + "</option>\n";
506                 }
507             }
508             returnString += "</select>\n";
509             connMgr.freeConnection(db, conn);
510             return returnString;
511         } catch (SQLException e) {
512             throw new Exception("More than one field required in getDropDown:" + e.toString());
513         } catch (Exception e) {
514             throw new Exception("Failed to build Lookup list:" + e.toString());
515         }  finally {
516             s.close();
517             connMgr.freeConnection(db, conn);
518         }
519     }
520 
521 
522 
523 
524 
525 
526 
527 
528 
529 
530     /**
531      * Formats a DDField to be displayed on a html page as in input box of the correct type
532      *
533      * @param ddf             a DDField which we want to create an input box for
534      * @param db            name of the database to query
535      * @param dateFormatter     format for dates
536      * @param dateTimeFormatter format for date and times
537      * @return                  a HTML input tag
538      */
539     public static String getInputValue(DDField ddf, String db, SimpleDateFormat dateFormatter,
540                                        SimpleDateFormat datetimeFormatter, String allValue, String postfix) throws Exception {
541         String fieldname = ddf.getMetaData().getFieldName();
542         if (postfix != null) fieldname += postfix;
543         String returnString = "";
544         if (ddf.getMetaData().getRelationshipTable().equals("")) {
545 
546             // Textarea and preformattedtextarea
547             if (ddf.getMetaData().getType().equals("textarea") ||
548                 ddf.getMetaData().getType().equals("preformattedtextarea")
549                ) {
550                 returnString += "<textarea name=" + fieldname;
551                 returnString += " cols=";
552                 if (ddf.getMetaData().getSize() > 0) {
553                     returnString += ddf.getMetaData().getSize();
554                 } else {
555                     returnString += "40";
556                 }
557                 returnString += " rows=";
558                 if (ddf.getMetaData().getHeight() > 0) {
559                     returnString += ddf.getMetaData().getHeight();
560                 } else {
561                     returnString += "6";
562                 }
563                 returnString += " wrap=virtual>";
564                 if (ddf.getValue() != null) {
565                     returnString += escapeHTML(ddf.getValue().toString());
566                 }
567                 returnString += "</textarea>";
568                 return returnString;
569 
570             // boolean
571             } else if (ddf.getMetaData().getType().equals("boolean")) {
572                 returnString += "<input type=checkbox value=true name=" + fieldname;
573                 if ((ddf.getValue() != null) && ((Boolean)ddf.getValue()).booleanValue()) {
574                     returnString += " checked ";
575                 }
576                 returnString += ">";
577                 return returnString;
578 
579             // autorandom
580             } else if (ddf.getMetaData().getType().equals("autorandom")) {
581                 if (ddf.getValue() != null) {
582                     returnString += escapeHTML(ddf.getValue().toString());
583                 }
584                 returnString += " (read-only)";
585                 return returnString;
586 
587             // id
588             } else if (ddf.getMetaData().getType().equals("id")) {
589                 if (ddf.getValue() != null) {
590                     returnString += ddf.getValue().toString();
591                 }
592                 return returnString;
593 
594             // date
595             } else if (ddf.getMetaData().getType().equals("date")) {
596                 returnString += "<input type=text name=" + fieldname + " value=\"";
597                 if (ddf.getValue() != null) {
598                     returnString += dateFormatter.format((java.util.Date) ddf.getValue());
599                 }
600                 returnString += "\" size=" + ddf.getMetaData().getSize();
601                 returnString += "\"> (dd/mm/yyyy)";
602                 return returnString;
603 
604             // datedrop
605             } else if (ddf.getMetaData().getType().equals("datedrop")) {
606                 java.util.Date thisDate = (java.util.Date) ddf.getValue();
607                 Calendar calendar = Calendar.getInstance();
608                 if (thisDate != null) calendar.setTime(thisDate);
609 
610                 returnString += "<select name=" + fieldname + "_date>\n";
611                 for (int i=1;i<32;i++) {
612                     returnString += "<option";
613                     if (thisDate != null && calendar.get(Calendar.DAY_OF_MONTH) == i) returnString += " selected";
614                     returnString += ">"+i+"\n";
615                 }
616                 returnString += "</select>\n\n";
617                 returnString += "<select name=" + fieldname + "_month>\n";
618                 for (int i=1;i<13;i++) {
619                     returnString += "<option value="+i;
620                     if (thisDate != null && calendar.get(Calendar.MONTH)+1 == i) returnString += " selected";
621                     returnString += ">"+months[i]+"\n";
622                 }
623                 returnString += "</select>\n\n";
624                 returnString += "<select name=" + fieldname + "_year>\n";
625 
626                 int startyear;
627                 int endyear;
628                 try {
629                     SystemProperties sp = new SystemProperties(db);
630                     String start = sp.getProperty("startyear");
631                     String end = sp.getProperty("endyear");
632                     if (start.equals("") || end.equals(""))
633                         throw new Exception("Can't get startyear or endyear from SystemProperties");
634                     startyear = Integer.parseInt(start);
635                     endyear = Integer.parseInt(end);
636                 } catch (Exception e) {
637                     throw new Exception("Can't get startyear or endyear from SystemProperties: "+e.toString());
638                 }
639 
640                 for (int i=startyear;i<=endyear;i++) {
641                     returnString += "<option";
642                     if (thisDate != null && calendar.get(Calendar.YEAR) == i) returnString += " selected";
643                     returnString += ">"+i+"\n";
644                 }
645                 returnString += "</select>\n\n";
646                 return returnString;
647 
648             // datetime
649             } else if (ddf.getMetaData().getType().equals("datetime")) {
650                 returnString += "<input type=text name=" + fieldname + " value=\"";
651                 if (ddf.getValue() != null) {
652                     returnString += datetimeFormatter.format((java.util.Date) ddf.getValue());
653                 }
654                 returnString += "\" size=" + ddf.getMetaData().getSize();
655                 returnString += "\"> (dd/mm/yyyy hh:mm)";
656                 return returnString;
657 
658             // timestamp
659             } else if (ddf.getMetaData().getType().equals("timestamp")) {
660                 if (ddf.getValue() != null) {
661                     returnString += datetimeFormatter.format((java.util.Date) ddf.getValue());
662                 }
663                 return returnString;
664 
665             // datetimedrop
666             } else if (ddf.getMetaData().getType().equals("datetimedrop")) {
667                 java.util.Date thisDate = (java.util.Date) ddf.getValue();
668                 Calendar calendar = Calendar.getInstance();
669                 if (thisDate != null) calendar.setTime(thisDate);
670 
671                 returnString += "<select name=" + fieldname + "_date>\n";
672                 for (int i=1;i<32;i++) {
673                     returnString += "<option";
674                     if (thisDate != null && calendar.get(Calendar.DAY_OF_MONTH) == i) returnString += " selected";
675                     returnString += ">"+i+"\n";
676                 }
677                 returnString += "</select>\n\n";
678                 returnString += "<select name=" + fieldname + "_month>\n";
679                 for (int i=1;i<13;i++) {
680                     returnString += "<option value="+i;
681                     if (thisDate != null && calendar.get(Calendar.MONTH)+1 == i) returnString += " selected";
682                     returnString += ">"+months[i]+"\n";
683                 }
684                 returnString += "</select>\n\n";
685                 returnString += "<select name=" + fieldname + "_year>\n";
686                 for (int i=1999;i<2011;i++) {
687                     returnString += "<option";
688                     if (thisDate != null && calendar.get(Calendar.YEAR) == i) returnString += " selected";
689                     returnString += ">"+i+"\n";
690                 }
691                 returnString += "</select>\n\n";
692                 returnString += "<select name=" + fieldname + "_hour>\n";
693                 for (int i=0;i<24;i++) {
694                     returnString += "<option";
695                     if (thisDate != null && calendar.get(Calendar.HOUR) == i) returnString += " selected";
696                     returnString += ">"+i+"\n";
697                 }
698                 returnString += "</select>\n\n";
699                 returnString += "<select name=" + fieldname + "_minute>\n";
700                 for (int i=0;i<60;i++) {
701                     returnString += "<option";
702                     if (thisDate != null && calendar.get(Calendar.MINUTE) == i) returnString += " selected";
703                     returnString += ">"+i+"\n";
704                 }
705                 returnString += "</select>\n\n";
706                 return returnString;
707 
708             // text, password, uploadurl
709             } else {
710                 returnString += "<input type=";
711                 if (ddf.getMetaData().getType().equals("password")) {
712                     returnString += "password";
713                 } else {
714                     returnString += "text";
715                 }
716                 returnString += " name=" + fieldname + " value=\"";
717                 if (ddf.getValue() != null)  {
718                    
719         //28/01/2000 code reinstated as i don't think it should have been removed
720                 // display 0 numbers as blank
721                     if (ddf.getMetaData().getType().equals("integer") && ((Integer)ddf.getValue()).equals(new Integer(0))) {}
722                         else if ((ddf.getMetaData().getType().equals("number") || ddf.getMetaData().getType().equals("currency")) && ((Double)ddf.getValue()).equals(new Double(0))) {}
723                         else if (ddf.getMetaData().getType().equals("long") && ((Long)ddf.getValue()).equals(new Long(0))) {}
724                         else { 
725                         returnString += escapeHTML(ddf.getValue().toString().trim());
726                         }
727                 }
728                 returnString += "\" size=" + ddf.getMetaData().getSize();
729                 if (ddf.getMetaData().getMaxLength() > 0) {
730                     returnString += " maxlength=" + ddf.getMetaData().getMaxLength();
731                 }
732                 returnString += ">";
733                 return returnString;
734             }
735         } else {
736             if (ddf.getMetaData().getType().equals("lookupwindow")) {
737                 return "";
738             } else if (ddf.getMetaData().getType().equals("lookupnodrop")) {
739                 returnString += "<input type=text name=" + fieldname + " value=\"";
740                 DDRecord rs = ddf.getLookup();
741                 if (ddf.getValue() != null)  {
742                     DDField field = (DDField) rs.get("id");
743                     returnString += field.getDisplayValue();
744                 }
745                 returnString += "\" size=" + ddf.getMetaData().getSize() + ">";
746                 if (ddf.getValue() != null)  {
747                     DDField field = (DDField) rs.get(ddf.getMetaData().getRelationshipField());
748                     returnString += " " + field.getDisplayValue();
749                 }
750                 return returnString;
751             } else {
752                 DDRecord relationship = new DDRecord(db,ddf.getMetaData().getRelationshipTable());
753                 DDField field = (DDField) relationship.get(ddf.getMetaData().getRelationshipField());
754                 if (ddf.getValue() != null) {
755                     field.setValue(ddf.getValue().toString());
756                 }
757                 String lookup = field.getDropDown(fieldname,ddf.getMetaData().getMandatory(),allValue);
758                 return lookup;
759             }
760         }
761     }
762 
763     /**
764      * Formats a DDField to be displayed on a html page as a hidden field
765      *
766      * @param ddf               The DDField to create an input box for
767      * @param db                name of the database to query
768      * @param dateFormatter     format for dates
769      * @param dateTimeFormatter format for date and times
770      * @return                  a HTML input tag
771      */
772     public static String getHiddenValue(DDField ddf, String db, 
773                                        SimpleDateFormat dateFormatter,
774                                        SimpleDateFormat datetimeFormatter, 
775                                        String postfix) 
776       throws Exception {
777         String fieldname = ddf.getMetaData().getFieldName();
778         if (postfix != null) fieldname += postfix;
779         String returnString = "<input type=hidden name=" + fieldname + 
780                               " value=\"";
781         if (ddf.getValue() != null) {
782             if (ddf.getMetaData().getType().equals("date") ||
783                 ddf.getMetaData().getType().equals("datedrop") ) {
784                     returnString += dateFormatter.format(
785                                       (java.util.Date) ddf.getValue());
786             }
787             else if (ddf.getMetaData().getType().equals("datetime") ||
788                      ddf.getMetaData().getType().equals("datetimedrop") ) {
789                     returnString += datetimeFormatter.format(
790                                       (java.util.Date) ddf.getValue());
791             }
792             else
793                 returnString += ddf.getValue().toString().trim();
794         }
795         returnString += "\">";
796         return returnString;
797     }
798 
799 
800    /**
801     * Returns a JavaScript tag which will validate the field using JS
802     * (remember to include the relevant functions to handle the validation
803     * request in your template). This file is also the place to look for
804     * the most up-to-date documentation.
805     *<P>
806     * Presently the returned String should look like:
807     *<pre>
808     * <SCRIPT language="JavaScript1.2">
809     * add_rule("fieldname_1","Display Name",0,"^regular\\w expression$", "statements")
810     * </SCRIPT>
811     *</pre>
812     * The <b>first 2 arguments</b> are strings which contain the name of 
813     * the input field and what to call it. 
814     * These should be the params fieldname and displayname for
815     * this function, but remember to wrap quotes around them!
816     * <p>
817     * The <b>third argument<b> should be 0 if mand is false, 1 otherwise 
818     * (actually, javascript treats anything other than 0, "0", false and 
819     * the null object as true).
820     * <p>
821     * The fourth argument is a regular expression which any value entered 
822     * into the HTML form must match against for validation to succeed. 
823     * Note that this needs to have quotes wrapped around it. 
824     * Since this ends up as a JavaScript string, we also
825     * need to escape special characters with '\', 
826     * including '\' itself (hence the '\\w'
827     * in the example above - 
828     * we want the expression to contain the 2 characters '\w',
829     * not CTRL-w. 
830     * If you put brackets into your expression then JavaScript will allow
831     * you to access them through the global (to each window) variable RegExp as
832     * RegExp.$1 ... RegExp.$9. 
833     * You can leave this out if you only want to check if a
834     * a mandatory value is set or not.
835     * <p>
836     * The fifth argument is the body of JavaScript function. 
837     * You can use this to
838     * perform more general validation tests than just matching a regular 
839     * expression, or you can leave it out altogether. 
840     * It has access to one formal paramater,
841     * 'value' - the value of the input field being validated. It also
842     * has access to global variables such as RegExp.$1. 
843     * It should return nothing
844     * (or an empty string) if validation succeeds, otherwise it should return a
845     * string to be shown to the user explaining the problem. Remeber to print
846     * double quotes around it.
847     * <p>
848     * Because we've got to escape all these quotes and escapes in this 
849     * function, the strings are a bit messy, especially since there are 
850     * a few '\n's to improve readability in the HTML source. Be careful.
851     * <p>
852     * <b>ALTERNATIVELY</b>, 
853     * you can use some rules which are predefined in the javascript:
854     *   add_integer("fieldname_1", "Display Name", 0);
855     *   add_number("fieldname_1", "Display Name", 0);
856     *   add_date("fieldname_1", "Display Name", 0);
857     *   add_datetime("fieldname_1", "Display Name", 0);
858     *
859     *
860     * @param  ddf          A DDField representing a field in the datadictionary
861     * @param  fieldname    The name of the input tag to be validated
862     * @param  displayname  What to call the input field for the user's benefit
863     * @param  mand         Whether the field is mandatory (cannot be empty)
864     * @return A            JavaScript tag which will validate ddf on the 
865     *                      client side when the form is submitted. 
866     *
867     */
868     public static String getJSValidation(DDField ddf, String fieldname, 
869                                          String displayname, boolean mand) {
870 
871         String whichRule = "";
872         String mandatory    = (mand) ? "1":"0";
873 
874 /*
875     A demo of how to create a new validation field in java
876 
877         // Pretend fieldtype
878         if (ddf.getMetaData().getType().equals("time") {
879             return "<SCRIPT language=\"JavaScript1.2\">add_rule("
880                     +"\""+fieldname+"\", "
881                     +"\""+displayname+"\", "
882                     +mandatory+ ", "
883                     +"\"(\\d\\d):\\d\\d\", "
884                     +"\"return (RegExp.$1>23)?'There are only 24 hours in a day!':'';\""
885                    +")</SCRIPT>";
886         }
887 */
888         // No validation (incl. mandatory) for lookups
889 //        if (!ddf.getMetaData().getRelationshipTable().equals("")) { return ""; }
890         // No validation (incl. mandatory) for booleans
891         if (ddf.getMetaData().getType().equals("boolean")) { return ""; }
892         // No validation (incl. mandatory) for autorandom
893         if (ddf.getMetaData().getType().equals("autorandom")) { return ""; }
894         // No validation (incl. mandatory) for id
895         if (ddf.getMetaData().getType().equals("id")) { return ""; }
896         // No validation (incl. mandatory) for datedrop
897         if (ddf.getMetaData().getType().equals("datedrop")) { return ""; }
898         // No validation (incl. mandatory) for datetimedrop
899         if (ddf.getMetaData().getType().equals("datetimedrop")) { return ""; }
900 
901         if (ddf.getMetaData().getType().equals("date")) { whichRule = "add_date"; }
902         // Only check for mandatory for lookups
903         else if (!ddf.getMetaData().getRelationshipTable().equals("")) { whichRule = "add_rule"; }
904         else if (ddf.getMetaData().getType().equals("datetime")) { whichRule = "add_datetime"; }
905         else if (ddf.getMetaData().getType().equals("integer")) { whichRule = "add_integer"; }
906         else if (ddf.getMetaData().getType().equals("number") || ddf.getMetaData().getType().equals("currency"))   { whichRule = "add_number"; }
907 // Only check for mandatory in text, textarea, preformattedtextarea, 
908 // password, uploadurl
909         else { whichRule = "add_rule"; }
910 
911         return "<SCRIPT language=\"JavaScript1.2\">"+
912                whichRule+"(\""+fieldname+"\", \""+displayname+"\", "+mandatory+")</SCRIPT>";
913     }
914 
915 }
916