0001: //** Copyright Statement ***************************************************
0002: //The Salmon Open Framework for Internet Applications (SOFIA)
0003: // Copyright (C) 1999 - 2002, Salmon LLC
0004: //
0005: // This program is free software; you can redistribute it and/or
0006: // modify it under the terms of the GNU General Public License version 2
0007: // as published by the Free Software Foundation;
0008: //
0009: // This program is distributed in the hope that it will be useful,
0010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
0011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0012: // GNU General Public License for more details.
0013: //
0014: // You should have received a copy of the GNU General Public License
0015: // along with this program; if not, write to the Free Software
0016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0017: //
0018: // For more information please visit http://www.salmonllc.com
0019: //** End Copyright Statement ***************************************************
0020: package com.salmonllc.forms;
0021:
0022: /////////////////////////
0023: //$Archive: /sofia/sourcecode/com/salmonllc/forms/DetailForm.java $
0024: //$Author: Deepak $
0025: //$Revision: 76 $
0026: //$Modtime: 8/11/03 9:43a $
0027: /////////////////////////
0028:
0029: import java.io.File;
0030: import java.io.FileOutputStream;
0031: import java.util.Enumeration;
0032: import java.util.Vector;
0033:
0034: import com.salmonllc.html.*;
0035: import com.salmonllc.html.events.*;
0036: import com.salmonllc.properties.Props;
0037: import com.salmonllc.sql.DataStore;
0038: import com.salmonllc.sql.DataStoreBuffer;
0039: import com.salmonllc.util.MessageLog;
0040:
0041: /**
0042: * Implements Detail form.
0043: * A display box is created containing a table with entry fields. Also created are submit
0044: * buttons as follows:<BR>
0045: * - "Delete": the current row is removed from the database. <BR>
0046: * - "Save": the database is updated with the contents of the current row. <BR>
0047: * The form is implemented as a container to go within an instance of (a subclass of)
0048: * HtmlPage. Specify as many data store columns as you want using the addColumn* methods. <BR>
0049: * To hook key activities such as the "Delete" button, implement the DetailFormListener
0050: * interface and call addListener.
0051: * NOTE: The addColumn* methods assume the new column is non-primary. Typically the client
0052: * should explicitly specify the primary keys. For example, <BR>
0053: <PRE>
0054: DetailForm form = new DetailForm(this, "UserDetailPage");
0055: DataStore ds = form.getDataStore();
0056: add(form);
0057: form.addColumn(_table, "user_id", "ID#", DataStore.DATATYPE_STRING, true, true);
0058: ds.setPrimaryKey(_table + ".user_id", true);
0059: // add other columns ...
0060: </PRE>
0061: */
0062: public class DetailForm extends BaseForm implements SubmitListener,
0063: ValueChangedListener, FileUploadListener {
0064:
0065: /** addColumn flags parameter: Field is required. */
0066: public static final int IS_REQUIRED = 1 << 0;
0067: /** addColumn flags parameter: Do not insert a line break, keep on same table row. */
0068: public static final int SAME_ROW = 1 << 1;
0069: /** addColumn flags parameter: Component is read-only or display only. */
0070: public static final int READ_ONLY = 1 << 2;
0071: /** addColumn flags parameter: Column is primary key. */
0072: public static final int PRIMARY_KEY = 1 << 3;
0073: /** addColumn flags parameter: Do not create a datastore column. */
0074: public static final int NO_DATASTORE = 1 << 4;
0075: /** addColumn flags parameter: Create a bucket using "column" parameter. */
0076: public static final int BUCKET = 1 << 5;
0077:
0078: /** constructor flags parameter: Do not create the default "Save" button. */
0079: public static final int INIT_NO_SAVE_BUTTON = 1 << 0;
0080: /** constructor flags parameter: Do not create the default "Delete" button. */
0081: public static final int INIT_NO_DELETE_BUTTON = 1 << 1;
0082: /** constructor flags parameter: Do not process page requests. */
0083: public static final int INIT_NO_PROCESSING = 1 << 2;
0084:
0085: /** constructor flags parameter: Do not create the default "Delete" button. */
0086: public static final int INIT_NO_CANCEL_BUTTON = 1 << 3;
0087:
0088: // Other
0089: private HtmlDisplayBox _box;
0090: protected HtmlComponent _btnDelete = null;
0091: protected HtmlComponent _btnSave = null;
0092: protected HtmlComponent _btnCancel = null;
0093: //
0094: private HtmlTable _tbl;
0095: private int _row = -1;
0096: private int _col = -1;
0097: private Vector _listeners = new Vector();
0098: protected String _mode;
0099: private HtmlContainer _displayContainer;
0100: private DataStore _dsVerify;
0101: private boolean _initVerifyDone = false;
0102: private boolean _initPageRequestDone = false;
0103: private Vector _primaryFormComponents = new Vector();
0104: private int _nameCount = 0;
0105: private HtmlTableCellProperties _propAlignRight;
0106: protected boolean _noProcessing = false;
0107: public static final int ERROR_DUPLICATE_ROW = 0;
0108: public static final int ERROR_EMPTY_FIELD = 1;
0109: public static final int ERROR_INVALID_ENTRY = 2;
0110: public static final int ERROR_ANY = 99;
0111: // Information on components in form is stored in a vector of objects of type
0112: // FormComponent.
0113: private Vector _formComponents = new Vector();
0114:
0115: //Set the directory to process the fileUploaded() method.
0116: private String _fileUploadDirectory = null;
0117:
0118: // Message Component
0119: public HtmlText htErrorMessageComp = null;
0120:
0121: /**
0122: * Constructor for DetailForm..
0123: * This variant creates a default data store.
0124: * @param page com.salmonllc.html.HtmlPage Page containing the form.
0125: */
0126: public DetailForm(HtmlPage page) {
0127: this (page, null, 0);
0128: }
0129:
0130: /**
0131: * Constructor for DetailForm..
0132: * @param page com.salmonllc.html.HtmlPage Page containing the form.
0133: * @param ds DataStore DataStore to use; if null then create one.
0134: */
0135: public DetailForm(HtmlPage page, DataStore ds) {
0136: this (page, ds, 0);
0137: }
0138:
0139: /**
0140: * Constructor for DetailForm..
0141: * @param page Page containing the form.
0142: * @param ds DataStore to use; if null then create one.
0143: * @param flags Bitwise-OR combination of INIT_NO_SAVE_BUTTON, etc.
0144: */
0145: public DetailForm(HtmlPage page, DataStore ds, int flags) {
0146: super ("", page, ds);
0147: page.addPageListener(this );
0148:
0149: htErrorMessageComp = new HtmlText("", page);
0150: htErrorMessageComp.setVisible(false);
0151: add(htErrorMessageComp);
0152:
0153: // Define Detail display box
0154: add(_box = new HtmlDisplayBox("box", page));
0155: _box.setWidth(-1);
0156: _box.setHeadingCaption("Detail");
0157:
0158: // Create buttons regardless of flags, to avoid checking for null everywhere.
0159:
0160: _btnCancel = new HtmlSubmitButton("btnCancel", "Cancel", page);
0161: if ((flags & INIT_NO_CANCEL_BUTTON) == 0) {
0162: HtmlSubmitButton cancelBut = new HtmlSubmitButton(
0163: "btnCancel", "Cancel", page);
0164: cancelBut.addSubmitListener(this );
0165: _box.addHeadingComponent(_btnCancel = cancelBut);
0166: }
0167:
0168: _btnDelete = new HtmlSubmitButton("btnDelete", "Delete", page);
0169: if ((flags & INIT_NO_DELETE_BUTTON) == 0) {
0170: HtmlSubmitButton delBut = new HtmlSubmitButton("btnDelete",
0171: "Delete", page);
0172: delBut.addSubmitListener(this );
0173: _box.addHeadingComponent(_btnDelete = delBut);
0174: }
0175: _btnSave = new HtmlSubmitButton("btnSave", "Save", page);
0176: if ((flags & INIT_NO_SAVE_BUTTON) == 0) {
0177: HtmlSubmitButton savBut = new HtmlSubmitButton("btnSave",
0178: "Save", page);
0179: savBut.addSubmitListener(this );
0180: _box.addHeadingComponent(_btnSave = savBut);
0181: }
0182: _box.setBoxComponent(_displayContainer = new HtmlContainer("",
0183: page));
0184: // Name = dft = Detail Form Table
0185: _displayContainer.add(_tbl = new HtmlTable("dft", page));
0186: add(_line_break);
0187: // As a favor to client classes, add page as listener if appropriate
0188: if (page instanceof DetailFormListener)
0189: addListener((DetailFormListener) page);
0190: // Initialize datastore to use for primary-key verification
0191: _dsVerify = new DataStore(page.getApplicationName());
0192: // Other
0193: (_propAlignRight = new HtmlTableCellProperties())
0194: .setAlign(HtmlTable.ALIGN_RIGHT);
0195: _noProcessing = (flags & INIT_NO_PROCESSING) != 0;
0196: }
0197:
0198: /**
0199: * Adds a bucket to the datastore and bind a given entry field, and add it to table.
0200: * @param bucket Name of bucket to add.
0201: * @param caption String Text of caption to use preceding entry field. If null, none.
0202: * @param type int Type of datastore column--use DataStore.DATATYPE_* values.
0203: * @param flags int Flags.
0204: * @param component Use the given component for entry or display; if null then
0205: * create a text entry field.
0206: * @param propCaption Properties for caption table cell.
0207: * @param prop Properties for data table cell.
0208: */
0209: public HtmlComponent addBucket(String bucket, String caption,
0210: int type, int flags, HtmlComponent component,
0211: HtmlTableCellProperties propCaption,
0212: HtmlTableCellProperties prop) throws Exception {
0213:
0214: return addColumn(bucket, null, caption, type, flags | BUCKET,
0215: component, propCaption, prop);
0216: }
0217:
0218: /**
0219: * Adds given caption to table, followed by ':'.
0220: * @param caption java.lang.String
0221: */
0222: protected HtmlText addCaption(String caption, int flags,
0223: HtmlTableCellProperties prop) {
0224: HtmlText result = null;
0225: if (caption != null) {
0226: String s = "";
0227: if (caption.length() > 0) {
0228: s += caption;
0229: if ((flags & IS_REQUIRED) != 0)
0230: s += "*";
0231: if (!s.endsWith(":") && !s.endsWith("?"))
0232: s += ":";
0233: }
0234: if (prop != null) {
0235: _tbl
0236: .setComponentAt(_row, ++_col,
0237: result = new HtmlText(s,
0238: HtmlText.FONT_COLUMN_CAPTION,
0239: getPage()), prop);
0240: /* BUGBUG: see HtmlTable.generateHtml
0241: _col += prop.getColumnSpan() - 1;
0242: */
0243: if (prop.getColumnSpan() > 1)
0244: _col += prop.getColumnSpan();
0245: } else
0246: _tbl
0247: .setComponentAt(_row, ++_col,
0248: result = new HtmlText(s,
0249: HtmlText.FONT_COLUMN_CAPTION,
0250: getPage()));
0251: }
0252: return result;
0253: }
0254:
0255: /**
0256: * Adds a column to the datastore and create a corresponding entry or display field in the table,
0257: * bound to the datastore.
0258: * @param table String Name of table to add
0259: * @param column String Name of column to add
0260: * @param caption String Text of caption to use preceding entry field. If null, none.
0261: * @param type int Type of datastore column--use DataStore.DATATYPE_* values.
0262: * @param flags int Flags
0263: */
0264: public HtmlComponent addColumn(String table, String column,
0265: String caption, int type, int flags) throws Exception {
0266: return addColumn(table, column, caption, type, flags, null,
0267: null, null);
0268: }
0269:
0270: /**
0271: * Adds a column to the datastore and bind a given entry field, and add it to table.
0272: * @param table String Name of table to add
0273: * @param column String Name of column to add
0274: * @param caption String Text of caption to use preceding entry field. If null, none.
0275: * @param type int Type of datastore column--use DataStore.DATATYPE_* values.
0276: * @param flags int Flags.
0277: * @param component Use the given component for the entry or display field.
0278: */
0279: public HtmlComponent addColumn(String table, String column,
0280: String caption, int type, int flags, HtmlComponent component)
0281: throws Exception {
0282: return addColumn(table, column, caption, type, flags,
0283: component, null, null);
0284: }
0285:
0286: /**
0287: * Adds a column to the datastore and bind a given entry field, and add it to table.
0288: * @param table String Name of table or bucket to add, or null if no DataStore binding.
0289: * @param column String Name of column to add.
0290: * @param caption String Text of caption to use preceding entry field. If null, none.
0291: * @param type int Type of datastore column--use DataStore.DATATYPE_* values.
0292: * @param flags int Flags.
0293: * @param component Use the given component for entry or display; if null then
0294: * create a text entry field.
0295: * @param propCaption Properties for caption table cell.
0296: * @param prop Properties for data table cell.
0297: */
0298: public HtmlComponent addColumn(String table, String column,
0299: String caption, int type, int flags,
0300: HtmlComponent component,
0301: HtmlTableCellProperties propCaption,
0302: HtmlTableCellProperties prop) throws Exception {
0303:
0304: String format = null;
0305: String fullColName; // Full name of DataStore column
0306: boolean noDS = ((flags & NO_DATASTORE) != 0) || (table == null);
0307: boolean doFormat = false;
0308: String componentName;
0309:
0310: if ((flags & BUCKET) != 0) {
0311: fullColName = table;
0312: if (!noDS && (_ds.getColumnIndex(fullColName) == -1)) {
0313: _ds.addBucket(fullColName, type);
0314: doFormat = true;
0315: }
0316: componentName = fullColName;
0317: } else {
0318: fullColName = table + "." + column;
0319: if (!noDS && (_ds.getColumnIndex(fullColName) == -1)) {
0320: _ds.addColumn(table, column, type,
0321: (flags & PRIMARY_KEY) != 0, true);
0322: doFormat = true;
0323: }
0324: componentName = makeName(table, column);
0325: }
0326: if (doFormat) {
0327: // For certain data types, set format according to page properties.
0328: Props props = getPage().getPageProperties();
0329: switch (type) {
0330: case DataStore.DATATYPE_DATETIME:
0331: format = props.getProperty(Props.DATETIME_FORMAT);
0332: break;
0333: case DataStore.DATATYPE_DATE:
0334: format = props.getProperty(Props.DATE_FORMAT);
0335: break;
0336: case DataStore.DATATYPE_TIME:
0337: format = props.getProperty(Props.TIME_FORMAT);
0338: break;
0339: }
0340: if (format != null)
0341: _ds.setFormat(fullColName, format);
0342: }
0343: if (((flags & SAME_ROW) == 0) || (_row == -1)) {
0344: _row++;
0345: _col = -1;
0346: }
0347: HtmlText htCaption = addCaption(caption, flags, propCaption);
0348: if (component == null) {
0349: if ((flags & READ_ONLY) != 0) {
0350: HtmlText ht = new HtmlText(componentName, getPage());
0351: if (table != null) {
0352: if (format != null)
0353: ht.setExpression(_ds, fullColName, format);
0354: else
0355: ht.setExpression(_ds, fullColName);
0356: }
0357: component = ht;
0358: } else {
0359: HtmlTextEdit hte = new HtmlTextEdit(componentName,
0360: getPage());
0361: hte.setMaxLength(25);
0362: switch (type) {
0363: case DataStore.DATATYPE_STRING:
0364: hte.setSize(20);
0365: hte.setMaxLength(50);
0366: break;
0367: case DataStore.DATATYPE_DATETIME:
0368: hte.setSize(20);
0369: break;
0370: case DataStore.DATATYPE_DATE:
0371: hte.setSize(15);
0372: break;
0373: case DataStore.DATATYPE_TIME:
0374: hte.setSize(15);
0375: break;
0376: case DataStore.DATATYPE_INT:
0377: case DataStore.DATATYPE_FLOAT:
0378: case DataStore.DATATYPE_DOUBLE:
0379: hte.setSize(5);
0380: break;
0381: default:
0382: hte.setSize(5);
0383: break;
0384: }
0385: if (table != null)
0386: hte.setColumn(_ds, fullColName);
0387: component = hte;
0388: }
0389: } else if ((component instanceof HtmlFormComponent) && !noDS)
0390: ((HtmlFormComponent) component).setColumn(_ds, fullColName);
0391: if (prop != null) {
0392: _tbl.setComponentAt(_row, ++_col, component, prop);
0393: /* BUGBUG: see HtmlTable.generateHtml
0394: _col += prop.getColumnSpan() - 1;
0395: */
0396: _col += prop.getColumnSpan();
0397: } else
0398: _tbl.setComponentAt(_row, ++_col, component);
0399: addFormComponent(htCaption, component, flags);
0400: return component;
0401: }
0402:
0403: /**
0404: * Adds a column to the datastore and create a corresponding entry or display field in the table,
0405: * bound to the datastore.
0406: * @param table String Name of table to add
0407: * @param column String Name of column to add
0408: * @param caption String Text of caption to use preceding entry field. If null, none.
0409: * @param type int Type of datastore column--use DataStore.DATATYPE_* values.
0410: * @param flags int Flags
0411: */
0412: public HtmlComponent addColumn(String table, String column,
0413: String caption, String defaultValue, int type, int flags)
0414: throws Exception {
0415: return addColumn(table, column, caption, defaultValue, type,
0416: flags, null, null, null);
0417: }
0418:
0419: /**
0420: * Adds a column to the datastore and bind a given entry field, and add it to table.
0421: * @param table String Name of table or bucket to add, or null if no DataStore binding.
0422: * @param column String Name of column to add.
0423: * @param caption String Text of caption to use preceding entry field. If null, none.
0424: * @param type int Type of datastore column--use DataStore.DATATYPE_* values.
0425: * @param flags int Flags.
0426: * @param component Use the given component for entry or display; if null then
0427: * create a text entry field.
0428: * @param propCaption Properties for caption table cell.
0429: * @param prop Properties for data table cell.
0430: */
0431: public HtmlComponent addColumn(String table, String column,
0432: String caption, String defaultValue, int type, int flags,
0433: HtmlComponent component,
0434: HtmlTableCellProperties propCaption,
0435: HtmlTableCellProperties prop) throws Exception {
0436:
0437: String format = null;
0438: String fullColName; // Full name of DataStore column
0439: boolean noDS = ((flags & NO_DATASTORE) != 0) || (table == null);
0440: boolean doFormat = false;
0441: String componentName;
0442:
0443: if ((flags & BUCKET) != 0) {
0444: fullColName = table;
0445: if (!noDS && (_ds.getColumnIndex(fullColName) == -1)) {
0446: _ds.addBucket(fullColName, type);
0447: doFormat = true;
0448: }
0449: componentName = fullColName;
0450: } else {
0451: fullColName = table + "." + column;
0452: if (!noDS && (_ds.getColumnIndex(fullColName) == -1)) {
0453: _ds.addColumn(table, column, type,
0454: (flags & PRIMARY_KEY) != 0, true);
0455: doFormat = true;
0456: } else {
0457: format = _ds.getFormat(fullColName);
0458: }
0459: componentName = makeName(table, column);
0460: }
0461: if (doFormat) {
0462: // For certain data types, set format according to page properties.
0463: Props props = getPage().getPageProperties();
0464: switch (type) {
0465: case DataStore.DATATYPE_DATETIME:
0466: format = props.getProperty(Props.DATETIME_FORMAT);
0467: break;
0468: case DataStore.DATATYPE_DATE:
0469: format = props.getProperty(Props.DATE_FORMAT);
0470: break;
0471: case DataStore.DATATYPE_TIME:
0472: format = props.getProperty(Props.TIME_FORMAT);
0473: break;
0474: }
0475: if (format != null)
0476: _ds.setFormat(fullColName, format);
0477: }
0478: if (((flags & SAME_ROW) == 0) || (_row == -1)) {
0479: _row++;
0480: _col = -1;
0481: }
0482: HtmlText htCaption = addCaption(caption, flags, propCaption);
0483: if (component == null) {
0484: if ((flags & READ_ONLY) != 0) {
0485: HtmlText ht = new HtmlText(componentName, getPage());
0486: if (table != null) {
0487: if (format != null)
0488: ht.setExpression(_ds, fullColName, format);
0489: else
0490: ht.setExpression(_ds, fullColName);
0491: }
0492: component = ht;
0493: } else {
0494: HtmlTextEdit hte = new HtmlTextEdit(componentName,
0495: getPage());
0496: hte.setValue(defaultValue);
0497: hte.setMaxLength(25);
0498: switch (type) {
0499: case DataStore.DATATYPE_STRING:
0500: hte.setSize(20);
0501: hte.setMaxLength(50);
0502: break;
0503: case DataStore.DATATYPE_DATETIME:
0504: hte.setSize(20);
0505: break;
0506: case DataStore.DATATYPE_DATE:
0507: hte.setSize(15);
0508: break;
0509: case DataStore.DATATYPE_TIME:
0510: hte.setSize(15);
0511: break;
0512: case DataStore.DATATYPE_INT:
0513: case DataStore.DATATYPE_FLOAT:
0514: case DataStore.DATATYPE_DOUBLE:
0515: hte.setSize(5);
0516: break;
0517: default:
0518: hte.setSize(5);
0519: break;
0520: }
0521: if (table != null)
0522: hte.setColumn(_ds, fullColName);
0523:
0524: component = hte;
0525: }
0526: } else if ((component instanceof HtmlFormComponent) && !noDS)
0527: ((HtmlFormComponent) component).setColumn(_ds, fullColName);
0528: if (prop != null) {
0529: _tbl.setComponentAt(_row, ++_col, component, prop);
0530: /* BUGBUG: see HtmlTable.generateHtml
0531: _col += prop.getColumnSpan() - 1;
0532: */
0533: _col += prop.getColumnSpan();
0534: } else
0535: _tbl.setComponentAt(_row, ++_col, component);
0536: addFormComponent(htCaption, component, flags);
0537: return component;
0538: }
0539:
0540: /**
0541: * Add a component to current position in table, without any data store processing.
0542: * @param caption String Caption to precede table cell, or null
0543: * @param component HtmlComponent Component to add
0544: * @param flags int Flags
0545: */
0546: public void addComponent(String caption, HtmlComponent component,
0547: int flags) throws Exception {
0548: addComponent(caption, component, flags, null, null);
0549: }
0550:
0551: /**
0552: * Add a component to current position in table, without any data store processing.
0553: * @param caption Caption to precede table cell, or null
0554: * @param component Component to add
0555: * @param flags Flags
0556: * @param propCaption Table cell properties for caption, or null
0557: * @param prop Table cell properties for data, or null
0558: */
0559: public void addComponent(String caption, HtmlComponent component,
0560: int flags, HtmlTableCellProperties propCaption,
0561: HtmlTableCellProperties prop) throws Exception {
0562: addColumn(null, null, caption, 0, flags, component,
0563: propCaption, prop);
0564: }
0565:
0566: /**
0567: * Add a custom form component to the detail form. The regular addColumn just adds HtmlTextEdit's
0568: * @param caption java.lang.String
0569: * @param component com.salmonllc.html.HtmlComponent
0570: * @param flags int
0571: * @param name java.lang.String
0572: */
0573: protected void addFormComponent(HtmlText caption,
0574: HtmlComponent component, int flags) {
0575: _formComponents.addElement(new FormComponent(caption,
0576: component, flags));
0577: addValueChangedListener(component);
0578: // if(component instanceof HtmlFileUpload)
0579: // ((HtmlFileUpload)component).addFileUploadListener(this);
0580: }
0581:
0582: /**
0583: * Adds a column to the datastore, using integer-type radio button group.
0584: * @param table String Name of table to add
0585: * @param column String Name of column to add
0586: * @param caption String Text of caption to use preceding entry field. If null, none.
0587: * @param flags int Flags
0588: * @param int[] values A list of values for the column.
0589: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
0590: */
0591: public HtmlDropDownList addIntegerDropDown(String table,
0592: String column, String caption, int flags, int values[],
0593: String displayValues[]) throws Exception {
0594: return (HtmlDropDownList) addColumn(table, column, caption,
0595: DataStore.DATATYPE_INT, flags,
0596: newIntegerDropDown(makeName(table, column), values,
0597: displayValues), null, null);
0598: }
0599:
0600: /**
0601: * Adds a column to the datastore, using integer-type radio button group.
0602: * @param table String Name of table to add
0603: * @param column String Name of column to add
0604: * @param caption String Text of caption to use preceding entry field. If null, none.
0605: * @param flags int Flags
0606: * @param int[] values A list of values for the column.
0607: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
0608: * @param propCaption Table cell properties for caption, or null
0609: * @param prop Table cell properties for data, or null
0610: */
0611: public HtmlDropDownList addIntegerDropDown(String table,
0612: String column, String caption, int flags, int values[],
0613: String displayValues[],
0614: HtmlTableCellProperties propCaption,
0615: HtmlTableCellProperties prop) throws Exception {
0616: HtmlDropDownList ddl = newIntegerDropDown(makeName(table,
0617: column), values, displayValues);
0618: if ((flags & READ_ONLY) != 0)
0619: ddl.setEnabled(false);
0620: return (HtmlDropDownList) addColumn(table, column, caption,
0621: DataStore.DATATYPE_INT, flags, ddl, propCaption, prop);
0622: }
0623:
0624: /**
0625: * Adds a column to the datastore, using integer-type radio button group.
0626: * @param table String Name of table to add
0627: * @param column String Name of column to add
0628: * @param caption String Text of caption to use preceding entry field. If null, none.
0629: * @param flags int Flags
0630: * @param int[] values A list of values for the column.
0631: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
0632: */
0633: public HtmlDropDownList addIntegerDropDown(String table,
0634: String column, String caption, int flags, int values[],
0635: String displayValues[], boolean isMandatory)
0636: throws Exception {
0637:
0638: HtmlDropDownList ddl = (HtmlDropDownList) addColumn(table,
0639: column, caption, DataStore.DATATYPE_INT, flags,
0640: newIntegerDropDown(makeName(table, column), values,
0641: displayValues), null, null);
0642:
0643: if (isMandatory)
0644: ddl.removeOption("");
0645: return ddl;
0646: }
0647:
0648: /**
0649: * Adds a column to the datastore, using an integer-type radio button group.
0650: * @param table String Name of table to add
0651: * @param column String Name of column to add
0652: * @param caption String Text of caption to use preceding entry field. If null, none.
0653: * @param flags int Flags
0654: * @param int[] values A list of values for the column.
0655: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
0656: */
0657: public HtmlRadioButtonGroup addIntegerRadioButtonGroup(
0658: String table, String column, String caption, int flags,
0659: int values[], String displayValues[]) throws Exception {
0660: HtmlRadioButtonGroup rbg = new HtmlRadioButtonGroup(makeName(
0661: table, column), getPage());
0662: // This allows less work having to be done in the loop every iteration
0663: String value = null;
0664: String displayValue = null;
0665: int valLength = values.length;
0666: int displayValuesLength = displayValues.length;
0667: //
0668: for (int i = 0; i < valLength; i++) {
0669: value = new Integer(values[i]).toString();
0670: displayValue = "Value " + i;
0671: if (i < displayValuesLength) {
0672: displayValue = displayValues[i];
0673: }
0674: rbg.addOption(value, displayValue);
0675: }
0676: //
0677: if ((flags & READ_ONLY) != 0)
0678: rbg.setEnabled(false);
0679: return (HtmlRadioButtonGroup) addColumn(table, column, caption,
0680: DataStore.DATATYPE_INT, flags, rbg, null, null);
0681: }
0682:
0683: /**
0684: * Adds a column to the datastore, using an integer-type radio button group.
0685: * @param table String Name of table to add
0686: * @param column String Name of column to add
0687: * @param caption String Text of caption to use preceding entry field. If null, none.
0688: * @param flags int Flags
0689: * @param int[] values A list of values for the column.
0690: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
0691: * @param propCaption Properties for caption table cell.
0692: * @param prop Properties for data table cell.
0693: */
0694: public HtmlRadioButtonGroup addIntegerRadioButtonGroup(
0695: String table, String column, String caption, int flags,
0696: int values[], String displayValues[],
0697: HtmlTableCellProperties propCaption,
0698: HtmlTableCellProperties prop) throws Exception {
0699: HtmlRadioButtonGroup rbg = new HtmlRadioButtonGroup(makeName(
0700: table, column), getPage());
0701:
0702: // This allows less work having to be done in the loop every iteration
0703: String value = null;
0704: String displayValue = null;
0705: int valLength = values.length;
0706: int displayValuesLength = displayValues.length;
0707: //
0708: for (int i = 0; i < valLength; i++) {
0709: value = new Integer(values[i]).toString();
0710: displayValue = "Value " + i;
0711: if (i < displayValuesLength) {
0712: displayValue = displayValues[i];
0713: }
0714: rbg.addOption(value, displayValue);
0715: }
0716: if ((flags & READ_ONLY) != 0)
0717: rbg.setEnabled(false);
0718: return (HtmlRadioButtonGroup) addColumn(table, column, caption,
0719: DataStore.DATATYPE_INT, flags, rbg, propCaption, prop);
0720: }
0721:
0722: /**
0723: * Adds a DetailFormListener.
0724: * @param listener com.salmonllc.forms.DetailFormListener
0725: */
0726: public void addListener(DetailFormListener listener) {
0727: // Make sure listener is not added twice
0728: int listenersSize = _listeners.size();
0729: for (int i = 0; i < listenersSize; i++)
0730: if (((DetailFormListener) _listeners.elementAt(i)) == listener)
0731: return;
0732: _listeners.addElement(listener);
0733: }
0734:
0735: /**
0736: * Adds a column to the data store and list box, search box, or both.
0737: * The column is of type integer and the display is a drop-down list which is
0738: * preinitialized from a second table structured in a particular way.
0739: *
0740: * @param table Name of table for datastore
0741: * @param column Name of column for datastore
0742: * @param caption Caption for search box and/or list box, or null
0743: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
0744: * @param initName Name of table used to initialized, also name of its primary integer column.
0745: * @param descName Name of description column in initialization table.
0746: */
0747: public HtmlDropDownList addPreInitDropDown(String table,
0748: String column, String caption, int flags, String initName,
0749: String descName, HtmlTableCellProperties propCaption,
0750: HtmlTableCellProperties prop) throws Exception {
0751: return addPreInitDropDown(table, column, caption, flags,
0752: initName, initName, descName, propCaption, prop);
0753: }
0754:
0755: /**
0756: * Adds a column to the data store and list box, search box, or both.
0757: * The column is of type integer and the display is a drop-down list which is
0758: * preinitialized from a second table structured in a particular way.
0759: *
0760: * @param table Name of table for datastore
0761: * @param column Name of column for datastore
0762: * @param caption Caption for search box and/or list box, or null
0763: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
0764: * @param initName Name of table used to initialized.
0765: * @param initColumn Name of primary integer column of initName table.
0766: * @param descName Name of description column in initialization table.
0767: */
0768: public HtmlDropDownList addPreInitDropDown(String table,
0769: String column, String caption, int flags, String initName,
0770: String initColumn, String descName,
0771: HtmlTableCellProperties propCaption,
0772: HtmlTableCellProperties prop) throws Exception {
0773: HtmlDropDownList ddl;
0774: HtmlPage page = getPage();
0775:
0776: // Load secondary data store.
0777: DataStore ds = new DataStore(page.getApplicationName());
0778: ds.addColumn(initName, initColumn,
0779: DataStoreBuffer.DATATYPE_INT, true, false);
0780: ds.addColumn(initName, descName,
0781: DataStoreBuffer.DATATYPE_STRING, false, false);
0782: ds.setOrderBy(initName + "." + descName);
0783:
0784: ds.retrieve();
0785: ds.waitForRetrieve();
0786: int n = ds.getRowCount();
0787: if (n < 1)
0788: throw new FormException("Row count < 1");
0789: int values[] = new int[n];
0790: String displayValues[] = new String[n];
0791: n = 0;
0792: while (ds.gotoNext()) {
0793: values[n] = ds.getInt(initName + "." + initColumn);
0794: displayValues[n] = ds.getString(initName + "." + descName);
0795: n++;
0796: }
0797: ddl = newIntegerDropDown(table + "_" + column, values,
0798: displayValues);
0799: if ((flags & READ_ONLY) != 0)
0800: ddl.setEnabled(false);
0801: addColumn(table, column, caption, DataStoreBuffer.DATATYPE_INT,
0802: flags, ddl, propCaption, prop);
0803: return ddl;
0804: }
0805:
0806: /**
0807: * Adds a column to the data store and list box, search box, or both.
0808: * The column is of type integer and the display is a drop-down list which is
0809: * preinitialized from a second table structured in a particular way.
0810: *
0811: * @param table Name of table for datastore
0812: * @param column Name of column for datastore
0813: * @param caption Caption for search box and/or list box, or null
0814: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
0815: * @param initName Name of table used to initialized.
0816: * @param initColumn Name of primary integer column of initName table.
0817: * @param descName Name of description column in initialization table.
0818: */
0819: public HtmlRadioButtonGroup addPreInitRadioButtonGroup(
0820: String table, String column, String caption, int flags,
0821: String initName, String initColumn, String descName,
0822: HtmlTableCellProperties propCaption,
0823: HtmlTableCellProperties prop) throws Exception {
0824:
0825: HtmlPage page = getPage();
0826:
0827: // Load secondary data store.
0828: DataStore ds = new DataStore(page.getApplicationName());
0829: ds.addColumn(initName, initColumn,
0830: DataStoreBuffer.DATATYPE_INT, true, false);
0831: ds.addColumn(initName, descName,
0832: DataStoreBuffer.DATATYPE_STRING, false, false);
0833: ds.setOrderBy(initName + "." + descName);
0834: ds.retrieve();
0835: ds.waitForRetrieve();
0836: int n = ds.getRowCount();
0837: if (n < 1)
0838: throw new FormException("Row count < 1");
0839: int values[] = new int[n];
0840: String displayValues[] = new String[n];
0841: n = 0;
0842: while (ds.gotoNext()) {
0843: values[n] = ds.getInt(initName + "." + initColumn);
0844: displayValues[n] = ds.getString(initName + "." + descName);
0845: n++;
0846: }
0847: return addIntegerRadioButtonGroup(table, column, caption,
0848: flags, values, displayValues, propCaption, prop);
0849: }
0850:
0851: /**
0852: * Adds a column to the data store and list box, search box, or both.
0853: * The column is of type integer and the display is a drop-down list which is
0854: * preinitialized from a second table structured in a particular way.
0855: *
0856: * @param table Name of table for datastore
0857: * @param column Name of column for datastore
0858: * @param caption Caption for search box and/or list box, or null
0859: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
0860: * @param initName Name of table used to initialized, also name of its primary integer column.
0861: * @param descName Name of description column in initialization table.
0862: */
0863: public HtmlDropDownList addPreInitStringDropDown(String table,
0864: String column, String caption, int flags, String initName,
0865: String descName) throws Exception {
0866: return addPreInitStringDropDown(table, column, caption, flags,
0867: initName, initName, descName, null, null);
0868: }
0869:
0870: /**
0871: * Adds a column to the data store and list box, search box, or both.
0872: * The column is of type integer and the display is a drop-down list which is
0873: * preinitialized from a second table structured in a particular way.
0874: *
0875: * @param table Name of table for datastore
0876: * @param column Name of column for datastore
0877: * @param caption Caption for search box and/or list box, or null
0878: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
0879: * @param initName Name of table used to initialized, also name of its primary integer column.
0880: * @param descName Name of description column in initialization table.
0881: */
0882: public HtmlDropDownList addPreInitStringDropDown(String table,
0883: String column, String caption, int flags, String initName,
0884: String descName, HtmlTableCellProperties propCaption,
0885: HtmlTableCellProperties prop) throws Exception {
0886: return addPreInitStringDropDown(table, column, caption, flags,
0887: initName, initName, descName, propCaption, prop);
0888: }
0889:
0890: /**
0891: * Adds a column to the data store and list box, search box, or both.
0892: * The column is of type integer and the display is a drop-down list which is
0893: * preinitialized from a second table structured in a particular way.
0894: *
0895: * @param table Name of table for datastore
0896: * @param column Name of column for datastore
0897: * @param caption Caption for search box and/or list box, or null
0898: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
0899: * @param initName Name of table used to initialized, also name of its primary integer column.
0900: * @param descName Name of description column in initialization table.
0901: */
0902: public HtmlDropDownList addPreInitStringDropDown(String table,
0903: String column, String caption, int flags, String tableName,
0904: String initName, String descName) throws Exception {
0905: return addPreInitStringDropDown(table, column, caption, flags,
0906: tableName, initName, descName, null, null);
0907: }
0908:
0909: /**
0910: * Adds a column to the data store and list box, search box, or both.
0911: * The column is of type integer and the display is a drop-down list which is
0912: * preinitialized from a second table structured in a particular way.
0913: *
0914: * @param table Name of table for datastore
0915: * @param column Name of column for datastore
0916: * @param caption Caption for search box and/or list box, or null
0917: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
0918: * @param initName Name of table used to initialized.
0919: * @param initColumn Name of primary integer column of initName table.
0920: * @param descName Name of description column in initialization table.
0921: */
0922: public HtmlDropDownList addPreInitStringDropDown(String table,
0923: String column, String caption, int flags, String initName,
0924: String initColumn, String descName,
0925: HtmlTableCellProperties propCaption,
0926: HtmlTableCellProperties prop) throws Exception {
0927: HtmlDropDownList ddl;
0928: HtmlPage page = getPage();
0929:
0930: // Load secondary data store.
0931: DataStore ds = new DataStore(page.getApplicationName());
0932: ds.addColumn(initName, initColumn,
0933: DataStoreBuffer.DATATYPE_STRING, true, false);
0934: ds.addColumn(initName, descName,
0935: DataStoreBuffer.DATATYPE_STRING, false, false);
0936: ds.setOrderBy(initName + "." + descName);
0937:
0938: ds.retrieve();
0939: ds.waitForRetrieve();
0940: int n = ds.getRowCount();
0941: if (n < 1)
0942: throw new FormException("Row count < 1");
0943: String values[] = new String[n];
0944: String displayValues[] = new String[n];
0945: n = 0;
0946: while (ds.gotoNext()) {
0947: values[n] = ds.getString(initName + "." + initColumn);
0948: displayValues[n] = ds.getString(initName + "." + descName);
0949: n++;
0950: }
0951: ddl = newStringDropDown(table + "_" + column, values,
0952: displayValues);
0953: if ((flags & READ_ONLY) != 0)
0954: ddl.setEnabled(false);
0955: addColumn(table, column, caption,
0956: DataStoreBuffer.DATATYPE_STRING, flags, ddl,
0957: propCaption, prop);
0958: return ddl;
0959: }
0960:
0961: /**
0962: * Adds a column to the data store and list box, search box, or both.
0963: * The column is of type integer and the display is a drop-down list which is
0964: * preinitialized from a second table structured in a particular way.
0965: *
0966: * @param table Name of table for datastore
0967: * @param column Name of column for datastore
0968: * @param caption Caption for search box and/or list box, or null
0969: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
0970: * @param initName Name of table used to initialized.
0971: * @param initColumn Name of primary integer column of initName table.
0972: * @param descName Name of description column in initialization table.
0973: */
0974: public HtmlRadioButtonGroup addPreInitStringRadioButtonGroup(
0975: String table, String column, String caption, int flags,
0976: String initName, String initColumn, String descName)
0977: throws Exception {
0978:
0979: HtmlPage page = getPage();
0980:
0981: DataStore ds = new DataStore(page.getApplicationName());
0982: ds.addColumn(initName, initColumn,
0983: DataStoreBuffer.DATATYPE_STRING, true, false);
0984: ds.addColumn(initName, descName,
0985: DataStoreBuffer.DATATYPE_STRING, false, false);
0986: ds.setOrderBy(initName + "." + descName);
0987: ds.retrieve();
0988: ds.waitForRetrieve();
0989: int n = ds.getRowCount();
0990: if (n < 1)
0991: throw new FormException("Row count < 1");
0992: String values[] = new String[n];
0993: String displayValues[] = new String[n];
0994: n = 0;
0995: while (ds.gotoNext()) {
0996: values[n] = ds.getString(initName + "." + initColumn);
0997: displayValues[n] = ds.getString(initName + "." + descName);
0998: n++;
0999: }
1000: return addStringRadioButtonGroup(table, column, caption, flags,
1001: values, displayValues, null, null);
1002: }
1003:
1004: /**
1005: * Adds a column to the data store and list box, search box, or both.
1006: * The column is of type integer and the display is a drop-down list which is
1007: * preinitialized from a second table structured in a particular way.
1008: *
1009: * @param table Name of table for datastore
1010: * @param column Name of column for datastore
1011: * @param caption Caption for search box and/or list box, or null
1012: * @param flags Bitwise-OR combination of PRIMARY_KEY, etc. 0 = default.
1013: * @param initName Name of table used to initialized.
1014: * @param initColumn Name of primary integer column of initName table.
1015: * @param descName Name of description column in initialization table.
1016: */
1017: public HtmlRadioButtonGroup addPreInitStringRadioButtonGroup(
1018: String table, String column, String caption, int flags,
1019: String initName, String initColumn, String descName,
1020: HtmlTableCellProperties propCaption,
1021: HtmlTableCellProperties prop) throws Exception {
1022:
1023: HtmlPage page = getPage();
1024:
1025: DataStore ds = new DataStore(page.getApplicationName());
1026: ds.addColumn(initName, initColumn,
1027: DataStoreBuffer.DATATYPE_STRING, true, false);
1028: ds.addColumn(initName, descName,
1029: DataStoreBuffer.DATATYPE_STRING, false, false);
1030: ds.setOrderBy(initName + "." + descName);
1031: ds.retrieve();
1032: ds.waitForRetrieve();
1033: int n = ds.getRowCount();
1034: if (n < 1)
1035: throw new FormException("Row count < 1");
1036: String values[] = new String[n];
1037: String displayValues[] = new String[n];
1038: n = 0;
1039: while (ds.gotoNext()) {
1040: values[n] = ds.getString(initName + "." + initColumn);
1041: displayValues[n] = ds.getString(initName + "." + descName);
1042: n++;
1043: }
1044: return addStringRadioButtonGroup(table, column, caption, flags,
1045: values, displayValues, propCaption, prop);
1046: }
1047:
1048: /**
1049: * Adds a column to the datastore, using integer-type radio button group.
1050: * @param table String Name of table to add
1051: * @param column String Name of column to add
1052: * @param caption String Text of caption to use preceding entry field. If null, none.
1053: * @param flags int Flags
1054: * @param int[] values A list of values for the column.
1055: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
1056: */
1057: public HtmlDropDownList addStringDropDown(String table,
1058: String column, String caption, int flags, String values[],
1059: String displayValues[]) throws Exception {
1060: return (HtmlDropDownList) addColumn(table, column, caption,
1061: DataStore.DATATYPE_STRING, flags,
1062: newStringDropDown(makeName(table, column), values,
1063: displayValues), null, null);
1064: }
1065:
1066: /**
1067: * Adds a column to the datastore, using integer-type radio button group.
1068: * @param table String Name of table to add
1069: * @param column String Name of column to add
1070: * @param caption String Text of caption to use preceding entry field. If null, none.
1071: * @param flags int Flags
1072: * @param int[] values A list of values for the column.
1073: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
1074: */
1075: public HtmlDropDownList addStringDropDown(String table,
1076: String column, String caption, int flags, String values[],
1077: String displayValues[], boolean isMandatory)
1078: throws Exception {
1079: HtmlDropDownList ddl = (HtmlDropDownList) addColumn(table,
1080: column, caption, DataStore.DATATYPE_STRING, flags,
1081: newStringDropDown(makeName(table, column), values,
1082: displayValues), null, null);
1083: if (isMandatory)
1084: ddl.removeOption("");
1085: return ddl;
1086: }
1087:
1088: /**
1089: * Adds a column to the datastore, using an integer-type radio button group.
1090: * @param table String Name of table to add
1091: * @param column String Name of column to add
1092: * @param caption String Text of caption to use preceding entry field. If null, none.
1093: * @param flags int Flags
1094: * @param int[] values A list of values for the column.
1095: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
1096: */
1097: public HtmlRadioButtonGroup addStringRadioButtonGroup(String table,
1098: String column, String caption, int flags, String values[],
1099: String displayValues[]) throws Exception {
1100: HtmlRadioButtonGroup rbg = new HtmlRadioButtonGroup(makeName(
1101: table, column), getPage());
1102: // This allows less work having to be done in the loop every iteration
1103: String value = null;
1104: String displayValue = null;
1105: int valLength = values.length;
1106: int displayValuesLength = displayValues.length;
1107: //
1108: for (int i = 0; i < valLength; i++) {
1109: value = values[i];
1110: displayValue = "Value " + i;
1111: if (i < displayValuesLength) {
1112: displayValue = displayValues[i];
1113: }
1114: rbg.addOption(value, displayValue);
1115: }
1116: //
1117: if ((flags & READ_ONLY) != 0)
1118: rbg.setEnabled(false);
1119: return (HtmlRadioButtonGroup) addColumn(table, column, caption,
1120: DataStore.DATATYPE_STRING, flags, rbg, null, null);
1121: }
1122:
1123: /**
1124: * Adds a column to the datastore, using an integer-type radio button group.
1125: * @param table String Name of table to add
1126: * @param column String Name of column to add
1127: * @param caption String Text of caption to use preceding entry field. If null, none.
1128: * @param flags int Flags
1129: * @param int[] values A list of values for the column.
1130: * @param String[] dispValues A list of corresponding display values for each of the values for the column.
1131: * @param propCaption Properties for caption table cell.
1132: * @param prop Properties for data table cell.
1133: */
1134: public HtmlRadioButtonGroup addStringRadioButtonGroup(String table,
1135: String column, String caption, int flags, String values[],
1136: String displayValues[],
1137: HtmlTableCellProperties propCaption,
1138: HtmlTableCellProperties prop) throws Exception {
1139: HtmlRadioButtonGroup rbg = new HtmlRadioButtonGroup(makeName(
1140: table, column), getPage());
1141:
1142: // This allows less work having to be done in the loop every iteration
1143: String value = null;
1144: String displayValue = null;
1145: int valLength = values.length;
1146: int displayValuesLength = displayValues.length;
1147: //
1148: for (int i = 0; i < valLength; i++) {
1149: value = values[i];
1150: displayValue = "Value " + i;
1151: if (i < displayValuesLength) {
1152: displayValue = displayValues[i];
1153: }
1154: rbg.addOption(value, displayValue);
1155: }
1156: if ((flags & READ_ONLY) != 0)
1157: rbg.setEnabled(false);
1158: return (HtmlRadioButtonGroup) addColumn(table, column, caption,
1159: DataStore.DATATYPE_STRING, flags, rbg, propCaption,
1160: prop);
1161: }
1162:
1163: /**
1164: * Recursively adds ValueChangedListener.
1165: * @param c com.salmonllc.html.HtmlComponent
1166: */
1167: protected void addValueChangedListener(HtmlComponent c) {
1168: if (c instanceof HtmlFormComponent)
1169: ((HtmlFormComponent) c).addValueChangedListener(this );
1170: else if (c instanceof HtmlContainer) {
1171: Enumeration e = ((HtmlContainer) c).getComponents();
1172: while (e.hasMoreElements())
1173: addValueChangedListener((HtmlComponent) e.nextElement());
1174: }
1175: }
1176:
1177: /**
1178: * Used to find a previously added component.
1179: * @return FormComponent
1180: * @param name java.lang.String
1181: */
1182: protected FormComponent findFormComponent(HtmlComponent component) {
1183: int formCompSize = _formComponents.size();
1184: FormComponent fc = null;
1185: for (int i = 0; i < formCompSize; i++) {
1186: fc = (FormComponent) _formComponents.elementAt(i);
1187: if ((fc.getFormComponent() == component) //
1188: || ((fc.getFormComponent() instanceof HtmlContainer //
1189: && hasComponent((HtmlContainer) fc
1190: .getFormComponent(), component))))
1191: return fc;
1192: }
1193: return null;
1194: }
1195:
1196: /**
1197: * Get the cation component associated with the passed in HtmlComponent.
1198: * @return FormComponent
1199: * @param name java.lang.String
1200: */
1201: public HtmlText getCaption(HtmlComponent component) {
1202: FormComponent fc = findFormComponent(component);
1203: if (fc != null)
1204: return fc.getCaptionTextComp();
1205: else
1206: return null;
1207: }
1208:
1209: /**
1210: * Used to get the current column index.
1211: * @return int
1212: */
1213: public int getCol() {
1214: return _col;
1215: }
1216:
1217: /**
1218: * Return the internal DataStore object.
1219: * @return com.salmonllc.sql.DataStore
1220: */
1221: public DataStore getDataStore() {
1222: return _ds;
1223: }
1224:
1225: /**
1226: * Returns the display box component.
1227: * @return com.salmonllc.html.HtmlDisplayBox
1228: */
1229: public HtmlDisplayBox getDisplayBox() {
1230: return _box;
1231: }
1232:
1233: /**
1234: * Returns container component which is main part of display box.
1235: * @return com.salmonllc.html.HtmlContainer
1236: */
1237: public HtmlContainer getDisplayContainer() {
1238: return _displayContainer;
1239: }
1240:
1241: /**
1242: * Insert the method's description here.
1243: * Creation date: (5/7/02 5:29:03 PM)
1244: * @return com.salmonllc.html.HtmlText
1245: */
1246: public com.salmonllc.html.HtmlText getErrorMessageComp() {
1247: return htErrorMessageComp;
1248: }
1249:
1250: /**
1251: * Used to get the current row index.
1252: * @return int
1253: */
1254: public int getRow() {
1255: return _row;
1256: }
1257:
1258: /**
1259: * Returns the display table component.
1260: * @return com.salmonllc.html.HtmlTable
1261: */
1262: public HtmlTable getTable() {
1263: return _tbl;
1264: }
1265:
1266: /**
1267: * Recursively determins whether a container contains a component.
1268: * @return boolean
1269: * @param cont com.salmonllc.html.HtmlContainer
1270: * @param component com.salmonllc.html.HtmlComponent
1271: */
1272: protected boolean hasComponent(HtmlContainer cont,
1273: HtmlComponent component) {
1274: Enumeration e = cont.getComponents();
1275: HtmlComponent c = null;
1276: while (e.hasMoreElements()) {
1277: c = (HtmlComponent) e.nextElement();
1278: if (c == component)
1279: return true;
1280: else if (c instanceof HtmlContainer) {
1281: if (hasComponent((HtmlContainer) c, component))
1282: return true;
1283: }
1284: }
1285: return false;
1286: }
1287:
1288: /**
1289: * Constructs a component name from table, column names.
1290: * @return java.lang.String
1291: * @param table java.lang.String
1292: * @param column java.lang.String
1293: */
1294: public String makeName(String table, String column) {
1295: if (table != null) {
1296: if (column != null)
1297: return table + "_" + column;
1298: else
1299: return table;
1300: } else if (column != null) {
1301: return column;
1302: } else
1303: return "comp" + _nameCount++;
1304: }
1305:
1306: /**
1307: * This event will get fired each time a page is requested by the browser.
1308: */
1309: public void pageRequested(PageEvent p) throws Exception {
1310: super .pageRequested(p);
1311: if (_noProcessing || !getVisible())
1312: return;
1313: HtmlPage page = getPage();
1314: if (!_initPageRequestDone) {
1315: // Accumulate list of form components bound to primary keys in data store
1316: Enumeration e = _tbl.getComponents();
1317: Object o = null;
1318: HtmlFormComponent hfc = null;
1319: while (e.hasMoreElements()) {
1320: o = e.nextElement();
1321: if (o instanceof HtmlFormComponent) {
1322: hfc = (HtmlFormComponent) o;
1323: int colnum;
1324: if (((colnum = hfc.getColumnNumber()) != -1)
1325: && _ds.isPrimaryKey(colnum))
1326: _primaryFormComponents.addElement(hfc);
1327: }
1328: }
1329: _initPageRequestDone = true;
1330: }
1331: // Set up the display
1332: if (!page.isReferredByCurrentPage()) {
1333: String mode = page.getParameter("mode");
1334: if (mode == null)
1335: return;
1336: else
1337: _mode = mode;
1338: if (_mode.equals("add")) {
1339: _btnDelete.setVisible(false);
1340: _btnSave.setVisible(true);
1341: _btnCancel.setVisible(true);
1342: setEnabled(true);
1343: } else if (_mode.equals("view")) {
1344: _btnDelete.setVisible(false);
1345: _btnSave.setVisible(false);
1346: _btnCancel.setVisible(false);
1347: setEnabled(false);
1348: } else if (_mode.equals("update")) {
1349: _btnDelete.setVisible(true);
1350: _btnSave.setVisible(true);
1351: _btnCancel.setVisible(true);
1352: setEnabled(true);
1353: // Disable form components associated with primary keys, else there will
1354: // be an SQL error if the user tries to change them then save.
1355: int primaryFormCompsSize = _primaryFormComponents
1356: .size();
1357: for (int i = 0; i < primaryFormCompsSize; i++)
1358: ((HtmlFormComponent) _primaryFormComponents
1359: .elementAt(i)).setEnabled(false);
1360: } else {
1361: return;
1362: }
1363: }
1364: // Call pre-processing listeners
1365: int listenersSize = _listeners.size();
1366: for (int i = 0; i < listenersSize; i++)
1367: if (!((DetailFormListener) _listeners.elementAt(i))
1368: .preDetailRequest())
1369: return;
1370: if (!page.isReferredByCurrentPage()) {
1371: // sr 10-15-2000 if we used _mode.intern()=="add" it might be faster
1372: // as per page 106 performance tuning book by o'reilly
1373: if (_mode.equals("add")) {
1374: _ds.reset();
1375: _ds.insertRow();
1376: } else if (_mode.equals("update") || _mode.equals("view")) {
1377: // Process page parameters associated with primary keys to identify
1378: // row to retrieve.
1379: CriteriaString cr = new CriteriaString();
1380: int colCount = _ds.getColumnCount();
1381: String name = null;
1382: String s = null;
1383: for (int i = 0; i < colCount; i++) {
1384: if (!_ds.isPrimaryKey(i))
1385: continue;
1386: name = _ds.getColumnName(i);
1387: int dot = name.indexOf('.');
1388: // Check for table.column form even thought it should always be OK
1389: if (dot == -1)
1390: continue;
1391: s = page.getParameter(name.substring(dot + 1));
1392: if (s == null) {
1393: // No matching primary-key parameter, so continue and hope the retrieve
1394: // will work anyway.
1395: continue;
1396: }
1397: switch (_ds.getColumnDataType(i)) {
1398: case DataStore.DATATYPE_INT:
1399: case DataStore.DATATYPE_SHORT:
1400: case DataStore.DATATYPE_LONG:
1401: case DataStore.DATATYPE_FLOAT:
1402: case DataStore.DATATYPE_DOUBLE:
1403: cr.and(name + "=" + s);
1404: break;
1405: case DataStore.DATATYPE_STRING:
1406: case DataStore.DATATYPE_DATETIME:
1407: cr.and(name + "='" + s + "'");
1408: break;
1409: default:
1410: throw new FormException("Unknown datatype: "
1411: + _ds.getColumnDataType(i)
1412: + "\nColumn:" + _ds.getColumnName(i));
1413: }
1414: }
1415: // we are getting here early. we have no columns set up so we throw an exception
1416: // this seems to have happened in a jsp.
1417:
1418: // the fix
1419: if (_ds.getColumnCount() <= 0) {
1420: return;
1421: }
1422: _ds.retrieve(cr.toString());
1423: _ds.gotoFirst();
1424: } else {
1425: throw new FormException("unknown mode: " + _mode);
1426: }
1427: }
1428: //
1429: // listenersSize already initialized from above
1430: for (int i = 0; i < listenersSize; i++)
1431: if (!((DetailFormListener) _listeners.elementAt(i))
1432: .postDetailRequest())
1433: return;
1434: }
1435:
1436: /**
1437: * Process a user error condition.
1438: * @param code int
1439: * @param caption java.lang.String
1440: * @param component com.salmonllc.html.HtmlComponent
1441: * @return int If true, continue event processing.
1442: */
1443: protected boolean processError(int code, String caption,
1444: HtmlComponent component) {
1445: int listenersSize = _listeners.size();
1446: if (listenersSize == 0)
1447: return true;
1448: String text = null;
1449: switch (code) {
1450: case DetailFormListener.ERROR_DUPLICATE_ROW:
1451: text = "Row in database already exists with same primary key";
1452: break;
1453: case DetailFormListener.ERROR_EMPTY_FIELD:
1454: if ((component instanceof HtmlDropDownList)
1455: || (component instanceof HtmlRadioButtonGroup))
1456: text = "Please select a value";
1457: else
1458: text = "Please enter a value";
1459: break;
1460: case DetailFormListener.ERROR_INVALID_ENTRY:
1461: text = "Please enter a valid value";
1462: break;
1463: }
1464: if (text == null) {
1465: text = caption;
1466: } else if (caption != null) {
1467: text += " for " + caption;
1468: }
1469:
1470: if (text != null)
1471: text += ".";
1472: for (int i = 0; i < listenersSize; i++)
1473: if (!((DetailFormListener) _listeners.elementAt(i))
1474: .onDetailError(code, text, component))
1475: return false;
1476: return true;
1477: }
1478:
1479: /**
1480: * Sets display name for Delete button.
1481: *
1482: * @param String name
1483: */
1484: public void setDeleteButtonDisplay(String name) throws Exception {
1485: if (_btnDelete != null) {
1486: if (_btnDelete instanceof HtmlSubmitButton) {
1487: ((HtmlSubmitButton) _btnDelete).setDisplayName(name);
1488: } else {
1489: throw new FormException(
1490: "_btnSaveis not a submit button");
1491: }
1492: }
1493: }
1494:
1495: /**
1496: * Replaces default search button (if any) with an image button
1497: * @param imageUrl URL of image.
1498: */
1499: public void setDeleteImage(HtmlSubmitImage img) {
1500: // Delete Button
1501: if (_btnDelete != null) {
1502: _box.removeHeadingComponent(_btnDelete);
1503: }
1504: img.addSubmitListener(this );
1505: _box.addHeadingComponent(_btnDelete = img);
1506: }
1507:
1508: /**
1509: * Replaces default search button (if any) with an image button
1510: * @param imageUrl URL of image.
1511: */
1512: public void setDeleteImage(String imageUrl) {
1513: if (_btnDelete != null)
1514: _box.removeHeadingComponent(_btnDelete);
1515: HtmlSubmitImage i = new HtmlSubmitImage("btnDelete", imageUrl,
1516: getPage());
1517: i.addSubmitListener(this );
1518: _box.addHeadingComponent(_btnDelete = i);
1519: }
1520:
1521: /**
1522: * Insert the method's description here.
1523: * Creation date: (5/7/02 5:29:03 PM)
1524: * @param newErrorMessageComp com.salmonllc.html.HtmlText
1525: */
1526: public void setErrorMessageComp(
1527: com.salmonllc.html.HtmlText newErrorMessageComp) {
1528: htErrorMessageComp = newErrorMessageComp;
1529: }
1530:
1531: /**
1532: * This method sets the text for the heading on the component
1533: */
1534: public void setHeadingCaption(String text) {
1535: _box.setHeadingCaption(text);
1536: }
1537:
1538: /**
1539: * Sets display name for Save button.
1540: * @param text java.lang.String
1541: */
1542: public void setSaveButtonDisplay(String name) throws Exception {
1543: if (_btnSave != null) {
1544: if (_btnSave instanceof HtmlSubmitButton) {
1545: ((HtmlSubmitButton) _btnSave).setDisplayName(name);
1546: } else {
1547: throw new FormException(
1548: "_btnSave is not a submit button");
1549: }
1550: }
1551: }
1552:
1553: /**
1554: * Replaces default add button (if any) with an image button
1555: * @param imageUrl URL of image.
1556: */
1557: public void setSaveImage(HtmlSubmitImage img) {
1558: // Save Button
1559: if (_btnSave != null) {
1560: _box.removeHeadingComponent(_btnSave);
1561: }
1562: img.addSubmitListener(this );
1563: _box.addHeadingComponent(_btnSave = img);
1564: }
1565:
1566: /**
1567: * Sets the directory to upload the file.
1568: * @param String sDirectory directory name.
1569: */
1570: public void setFileUploadDirectory(String sDirectory) {
1571: _fileUploadDirectory = sDirectory;
1572: }
1573:
1574: /**
1575: * Replaces default add button (if any) with an image button
1576: * @param imageUrl URL of image.
1577: */
1578: public void setSaveImage(String imageUrl) {
1579: if (_btnSave != null)
1580: _box.removeHeadingComponent(_btnSave);
1581: HtmlSubmitImage i = new HtmlSubmitImage("btnSave", imageUrl,
1582: getPage());
1583: i.addSubmitListener(this );
1584: _box.addHeadingComponent(_btnSave = i);
1585: }
1586:
1587: /**
1588: * Sets the visiblility of the default Delete button.
1589: * @param visible boolean
1590: */
1591: public void showDeleteButton(boolean visible) {
1592: if (_btnDelete != null) {
1593: _btnDelete.setVisible(visible);
1594: }
1595: }
1596:
1597: /**
1598: * Sets the visiblility of the default Save button.
1599: * @param visible boolean
1600: */
1601: public void showSaveButton(boolean visible) {
1602: if (_btnSave != null) {
1603: _btnSave.setVisible(visible);
1604: }
1605: }
1606:
1607: /**
1608: * Inherited abstract method.
1609: * @return boolean
1610: * @param e com.salmonllc.html.events.SubmitEvent
1611: */
1612: public boolean submitPerformed(SubmitEvent e) throws Exception {
1613: //
1614: MessageLog.writeDebugMessage(
1615: " submitPerformed (SubmitEvent e)", this );
1616: HtmlComponent c = e.getComponent();
1617: int listenersSize = _listeners.size();
1618: if (c == _btnSave) {
1619:
1620: // Verification passed, go ahead with update.
1621:
1622: for (int i = 0; i < listenersSize; i++)
1623: if (!((DetailFormListener) _listeners.elementAt(i))
1624: .preDetailSave())
1625: return false;
1626: if (!validate())
1627: return false;
1628: _ds.update();
1629: for (int i = 0; i < listenersSize; i++)
1630: ((DetailFormListener) _listeners.elementAt(i))
1631: .postDetailSave();
1632: } else if (c == _btnDelete) {
1633: for (int i = 0; i < listenersSize; i++)
1634: if (!((DetailFormListener) _listeners.elementAt(i))
1635: .preDetailDelete())
1636: return false;
1637: _ds.deleteRow();
1638: _ds.update();
1639: for (int i = 0; i < listenersSize; i++)
1640: ((DetailFormListener) _listeners.elementAt(i))
1641: .postDetailDelete();
1642: } else if (c == _btnCancel) {
1643: int formComponentsSize = _formComponents.size();
1644: HtmlComponent htmlComp = null;
1645:
1646: for (int i = 0; i < formComponentsSize; i++) {
1647: htmlComp = ((FormComponent) _formComponents
1648: .elementAt(i)).getFormComponent();
1649: if (htmlComp instanceof HtmlFormComponent) {
1650: ((HtmlFormComponent) htmlComp).setValue(null);
1651: }
1652: }
1653: }
1654:
1655: return true;
1656: }
1657:
1658: /**
1659: * Validates entry fields according to current mode.
1660: * @return True if validation was successful.
1661: */
1662: public boolean validate() throws Exception {
1663: String mode = _mode == null ? "" : _mode;
1664: if (mode.equals("add")) {
1665: // Verify row with duplicate primary key combination does not exist.
1666: CriteriaString cr = new CriteriaString();
1667: //
1668: int colCount = _ds.getColumnCount();
1669: String name = null;
1670: //
1671: for (int i = 0; i < colCount; i++) {
1672: if (!_ds.isPrimaryKey(i))
1673: continue;
1674: name = _ds.getColumnName(i);
1675: switch (_ds.getColumnDataType(i)) {
1676: case DataStore.DATATYPE_STRING:
1677: cr.and(name + "='" + _ds.getString(i) + "'");
1678: break;
1679: case DataStore.DATATYPE_INT:
1680: cr.and(name + "=" + _ds.getInt(i));
1681: break;
1682: case DataStore.DATATYPE_LONG:
1683: cr.and(name + "=" + _ds.getLong(i));
1684: break;
1685: case DataStore.DATATYPE_SHORT:
1686: cr.and(name + "=" + _ds.getShort(i));
1687: break;
1688: case DataStore.DATATYPE_DOUBLE:
1689: cr.and(name + "=" + _ds.getDouble(i));
1690: break;
1691: case DataStore.DATATYPE_DATETIME:
1692: cr.and(name + "='" + _ds.getDateTime(i) + "'");
1693: break;
1694: default:
1695: throw new FormException("Unknown datatype");
1696: }
1697: if (!_initVerifyDone) {
1698: // Copy an arbirary column into _dsVerify so we can do a retrieve on it.
1699: int dot = name.lastIndexOf('.');
1700: // Check for table.column form even thought it should always be OK
1701: if (dot != -1) {
1702: _dsVerify.addColumn(name.substring(0, dot),
1703: name.substring(dot + 1), _ds
1704: .getColumnDataType(i), _ds
1705: .isPrimaryKey(i), false);
1706: _initVerifyDone = true;
1707: }
1708: }
1709: }
1710: String s = cr.toString();
1711: if ((s != null) && _initVerifyDone) {
1712: _dsVerify.retrieve(s);
1713: if (_dsVerify.gotoNext()) {
1714: if (!processError(
1715: DetailFormListener.ERROR_DUPLICATE_ROW,
1716: null, null))
1717: return false;
1718: }
1719: }
1720: }
1721: // Verify all required fields
1722: if (!mode.equals("view")) {
1723: int formComponentsSize = _formComponents.size();
1724: FormComponent fc = null;
1725: HtmlComponent c = null;
1726: String caption = null;
1727: for (int i = 0; i < formComponentsSize; i++) {
1728: fc = (FormComponent) _formComponents.elementAt(i);
1729: if ((fc.getFlags() & IS_REQUIRED) == 0)
1730: continue;
1731: c = fc.getFormComponent();
1732: if (fc.getCaptionTextComp() != null) {
1733: caption = fc.getCaptionString();
1734: if (caption.endsWith(":"))
1735: caption = caption.substring(0,
1736: caption.length() - 1);
1737: if (caption.startsWith("*"))
1738: caption = caption.substring(1);
1739: if (caption.endsWith("*"))
1740: caption = caption.substring(0,
1741: caption.length() - 1);
1742: } else
1743: caption = null;
1744: if ((c != null)
1745: && !validateComponent((HtmlComponent) c,
1746: caption))
1747: return false;
1748: }
1749: }
1750: return true;
1751: }
1752:
1753: /**
1754: * Perform validation recursively on a component.
1755: * @return boolean
1756: * @param comp com.salmonllc.html.HtmlComponent
1757: * @param caption java.lang.String
1758: */
1759: protected boolean validateComponent(HtmlComponent comp, String name) {
1760: if (comp instanceof HtmlFormComponent) {
1761: HtmlFormComponent hfc = (HtmlFormComponent) comp;
1762: if (hfc.getValue() == null) {
1763: if (!processError(DetailFormListener.ERROR_EMPTY_FIELD,
1764: name, hfc))
1765: return false;
1766: }
1767: if (!hfc.isValid()) {
1768: if (!processError(
1769: DetailFormListener.ERROR_INVALID_ENTRY, name,
1770: hfc))
1771: return false;
1772: }
1773: } else if (comp instanceof HtmlContainer) {
1774: Enumeration e = ((HtmlContainer) comp).getComponents();
1775: while (e.hasMoreElements())
1776: if (!validateComponent((HtmlComponent) e.nextElement(),
1777: name))
1778: return false;
1779: }
1780: return true;
1781: }
1782:
1783: /**
1784: * This method checks the entered value to see if it passes validation test.
1785: * @return boolean
1786: * @param e com.salmonllc.html.events.ValueChangedEvent
1787: */
1788: public boolean valueChanged(ValueChangedEvent e) throws Exception {
1789: DataStoreBuffer ds = e.getDataStore();
1790: if (ds == null)
1791: return true;
1792: if (!ds.isFormattedStringValid(e.getColumn(), e.getNewValue())) {
1793: String msg = "Invalid value entered";
1794: FormComponent fc = findFormComponent(e.getComponent());
1795: if (fc != null)
1796: msg += " for " + fc.getCaptionString();
1797: if (!processError(ERROR_ANY, msg, e.getComponent())) {
1798: e
1799: .setAcceptValue(ValueChangedEvent.PROCESSING_NOTENTERED);
1800: return false;
1801: } else
1802: return true;
1803: } else
1804: return true;
1805: }
1806:
1807: public void fileUploaded(FileUploadEvent e) {
1808: if (_fileUploadDirectory == null)
1809: return;
1810: try {
1811:
1812: byte[] bContent = e.getContent();
1813: String sFileName = e.getShortFileName();
1814:
1815: if (bContent == null || bContent.length == 0) {
1816: return;
1817: }
1818: File f = null;
1819: FileOutputStream fos = null;
1820: if (sFileName != null) {
1821: f = new File(_fileUploadDirectory + File.separator
1822: + sFileName);
1823:
1824: if (f.exists())
1825: f.delete();
1826:
1827: fos = new FileOutputStream(f);
1828: fos.write(bContent);
1829: fos.flush();
1830: fos.close();
1831: }
1832: } catch (Exception ex) {
1833: System.out.println("Exception at Upload a file."
1834: + ex.getMessage());
1835: ex.printStackTrace();
1836: return;
1837: }
1838: }
1839:
1840: /**
1841: * Replaces default cancel button (if any) with an image button
1842: * @param imageUrl URL of image.
1843: */
1844: public void setCancelImage(HtmlSubmitImage img) {
1845: // Cancel Button
1846: if (_btnCancel != null) {
1847: _box.removeHeadingComponent(_btnCancel);
1848: }
1849: img.addSubmitListener(this );
1850: _box.addHeadingComponent(_btnCancel = img);
1851: }
1852:
1853: /**
1854: * Replaces default cancel button (if any) with an image button
1855: * @param imageUrl URL of image.
1856: */
1857: public void setCancelImage(String imageUrl) {
1858: if (_btnCancel != null)
1859: _box.removeHeadingComponent(_btnCancel);
1860: HtmlSubmitImage i = new HtmlSubmitImage("btnCancel", imageUrl,
1861: getPage());
1862: i.addSubmitListener(this);
1863: _box.addHeadingComponent(_btnCancel = i);
1864: }
1865: }
|