001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: // Copyright (C) 1999 - 2002, Salmon LLC
004: //
005: // This program is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU General Public License version 2
007: // as published by the Free Software Foundation;
008: //
009: // This program is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: // GNU General Public License for more details.
013: //
014: // You should have received a copy of the GNU General Public License
015: // along with this program; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: // For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020: package com.salmonllc.html;
021:
022: import com.salmonllc.html.events.*;
023:
024: /////////////////////////
025: //$Archive: /SOFIA/SourceCode/com/salmonllc/html/HtmlListBox.java $
026: //$Author: Dan $
027: //$Revision: 31 $
028: //$Modtime: 4/12/04 3:19p $
029: /////////////////////////
030: import com.salmonllc.properties.Props;
031:
032: import com.salmonllc.sql.DBConnection;
033:
034: import com.salmonllc.util.MessageLog;
035:
036: import java.util.Hashtable;
037:
038: /**
039: * This class is used to allow for the selection of items from a list.
040: */
041: public class HtmlListBox extends HtmlFormComponent {
042: private OptionsSort _options = new OptionsSort();
043: private String _fontTagEnd;
044: private String _fontTagStart;
045: private String _onChange;
046: private String _onClick;
047: private String _onFocus;
048: private String _onLoseFocus;
049: private boolean _multi = true;
050: private int _size = 5;
051: private Integer _tabIndex;
052: private String _accessKey;
053: private String _style;
054:
055: /**
056: * Constructs a new HtmlListBox component.
057: *
058: * @param name The name of the component
059: * @param p The page the component will be placed in.
060: */
061: public HtmlListBox(String name, com.salmonllc.html.HtmlPage p) {
062: this (name, null, p);
063: }
064:
065: /**
066: * Constructs a new HtmlListBox component.
067: *
068: * @param name The name of the component
069: * @param theme The theme to use for loading properties.
070: * @param p The page the component will be placed in.
071: */
072: public HtmlListBox(String name, String theme,
073: com.salmonllc.html.HtmlPage p) {
074: super (name, theme, p);
075: }
076:
077: /**
078: * Creates a list box based on a simple table with an <BR> integer primary key column and a string column. Typically the integer is a type value <BR> and the string is a description. A simplifying assumption is that each of the following <BR> is the same: <BR> - name of column in the main table which refers to the simple table <BR> - name of integer column in simple table <BR>
079: *
080: * @param name DOCUMENT ME!
081: * @param theme DOCUMENT ME!
082: * @param page com.salmonllc.html.HtmlPage The page hold the new component
083: * @param table - name of table to look up keys and displays from
084: * @param keyColumn - column to get key values from
085: * @param dispColumn - column to get display values from
086: */
087: public HtmlListBox(String name, String theme, HtmlPage page,
088: String table, String keyColumn, String dispColumn) {
089: super (name, theme, page);
090:
091: /**
092: * srufle 04-02-2002 using initialize method now should be functionally the same
093: */
094: initialize(table, keyColumn, dispColumn, null, false);
095:
096: // try {
097: // HtmlComponentFactory f = new HtmlComponentFactory(page, null, null);
098: // DataStore ds = f.getDataStore();
099: // f.newIntegerDisplay(table, keyColumn, true);
100: // f.newStringDisplay(table, dispColumn, false);
101: // ds.setOrderBy(dispColumn);
102: // ds.retrieve();
103: // ds.waitForRetrieve();
104: // String vCol = table + "." + keyColumn;
105: // String dCol = table + "." + dispColumn;
106: // if (ds.gotoFirst()) {
107: // do {
108: // addOption(new Integer(ds.getInt(vCol)).toString(), ds.getString(dCol));
109: // } while (ds.gotoNext());
110: // }
111: // } catch (Exception e) {
112: // MessageLog.writeErrorMessage(e, this);
113: // }
114: }
115:
116: /**
117: * Selects or deselects all items in the list
118: *
119: * @param selected DOCUMENT ME!
120: */
121: public void setAll(boolean selected) {
122: int count = getOptionCount();
123:
124: for (int i = 0; i < count; i++) {
125: setOptionSelected(i, selected);
126: }
127: }
128:
129: /**
130: * This method sets the end font tag for the component.
131: *
132: * @param value DOCUMENT ME!
133: */
134: public void setFontEndTag(String value) {
135: _fontTagEnd = value;
136: }
137:
138: /**
139: * This method gets the end font tag for the component.
140: *
141: * @return DOCUMENT ME!
142: */
143: public String getFontEndTag() {
144: return _fontTagEnd;
145: }
146:
147: /**
148: * This method sets the start font tag for the component.
149: *
150: * @param value DOCUMENT ME!
151: */
152: public void setFontStartTag(String value) {
153: _fontTagStart = value;
154: }
155:
156: /**
157: * This method gets the start font tag for the component.
158: *
159: * @return DOCUMENT ME!
160: */
161: public String getFontStartTag() {
162: return _fontTagStart;
163: }
164:
165: /**
166: * This method sets the whether or not the user can select multiple rows from the component.
167: *
168: * @param multi DOCUMENT ME!
169: */
170: public void setMulti(boolean multi) {
171: _multi = multi;
172: }
173:
174: /**
175: * This method returns whether or not the user can select multiple rows from the component.
176: *
177: * @return DOCUMENT ME!
178: */
179: public boolean getMulti() {
180: return _multi;
181: }
182:
183: /**
184: * This method sets the javascript to be executed when the value of the text in the component changes.
185: *
186: * @param value DOCUMENT ME!
187: */
188: public void setOnChange(String value) {
189: _onChange = value;
190: }
191:
192: /**
193: * This method gets the javascript to be executed when the value of the text in the component changes.
194: *
195: * @return DOCUMENT ME!
196: */
197: public String getOnChange() {
198: return _onChange;
199: }
200:
201: /**
202: * This method sets the javascript to be executed when the component is clicked on.
203: *
204: * @param value DOCUMENT ME!
205: */
206: public void setOnClick(String value) {
207: _onClick = value;
208: }
209:
210: /**
211: * This method gets the javascript to be executed when the component is clicked on.
212: *
213: * @return DOCUMENT ME!
214: */
215: public String getOnClick() {
216: return _onClick;
217: }
218:
219: /**
220: * This method sets the javascript to be executed when the component gains focus.
221: *
222: * @param value DOCUMENT ME!
223: */
224: public void setOnFocus(String value) {
225: _onFocus = value;
226: }
227:
228: /**
229: * This method gets the javascript to be executed when the component gets focus.
230: *
231: * @return DOCUMENT ME!
232: */
233: public String getOnFocus() {
234: return _onFocus;
235: }
236:
237: /**
238: * This method sets the javascript to be executed when the component loses focus.
239: *
240: * @param value DOCUMENT ME!
241: */
242: public void setOnLoseFocus(String value) {
243: _onLoseFocus = value;
244: }
245:
246: /**
247: * This method gets the javascript to be executed when the component loses focus.
248: *
249: * @return DOCUMENT ME!
250: */
251: public String getOnLoseFocus() {
252: return _onLoseFocus;
253: }
254:
255: /**
256: * This method returns the number of options in the component.
257: *
258: * @return DOCUMENT ME!
259: */
260: public int getOptionCount() {
261: return _options.size();
262: }
263:
264: /**
265: * Use this method get the value of the key at index.
266: *
267: * @param index DOCUMENT ME!
268: *
269: * @return DOCUMENT ME!
270: */
271: public String getOptionKey(int index) {
272: if ((index < 0) || (index >= _options.size())) {
273: return null;
274: }
275:
276: HtmlOption opt = (HtmlOption) _options.elementAt(index);
277:
278: return opt.getKey();
279: }
280:
281: /**
282: * Use this method set whether an option is selected.
283: *
284: * @param index DOCUMENT ME!
285: * @param selected DOCUMENT ME!
286: */
287: public void setOptionSelected(int index, boolean selected) {
288: if ((index < 0) || (index >= _options.size())) {
289: return;
290: }
291:
292: HtmlOption opt = (HtmlOption) _options.elementAt(index);
293: opt.setSelected(selected);
294: }
295:
296: /**
297: * Use this method to find out if an option is selected.
298: *
299: * @param index DOCUMENT ME!
300: *
301: * @return DOCUMENT ME!
302: */
303: public boolean getOptionSelected(int index) {
304: if ((index < 0) || (index >= _options.size())) {
305: return false;
306: }
307:
308: HtmlOption opt = (HtmlOption) _options.elementAt(index);
309:
310: return opt.isSelected();
311: }
312:
313: /**
314: * Use this method to set the value of the option at index.
315: *
316: * @param index DOCUMENT ME!
317: * @param value DOCUMENT ME!
318: */
319: public void setOptionValue(int index, String value) {
320: if ((index < 0) || (index >= _options.size())) {
321: return;
322: }
323:
324: HtmlOption opt = (HtmlOption) _options.elementAt(index);
325: opt.setDisplay(value);
326: }
327:
328: /**
329: * Use this method get the value of the option at index.
330: *
331: * @param index DOCUMENT ME!
332: *
333: * @return DOCUMENT ME!
334: */
335: public String getOptionValue(int index) {
336: if ((index < 0) || (index >= _options.size())) {
337: return null;
338: }
339:
340: HtmlOption opt = (HtmlOption) _options.elementAt(index);
341:
342: return opt.getDisplay();
343: }
344:
345: /**
346: * Returns a list of keys corresponding to the selected values
347: *
348: * @param separator DOCUMENT ME!
349: *
350: * @return java.lang.String
351: */
352: public String getSelectedList(String separator) {
353: String list = "";
354: int count = getOptionCount();
355:
356: for (int i = 0; i < count; i++) {
357: if (getOptionSelected(i)) {
358: list += (separator + getOptionKey(i));
359: }
360: }
361:
362: if (!list.equals("")) {
363: list = list.substring(separator.length());
364: }
365:
366: return list;
367: }
368:
369: /**
370: * This method sets the display size for the component in characters.
371: *
372: * @param size DOCUMENT ME!
373: */
374: public void setSize(int size) {
375: _size = size;
376: }
377:
378: /**
379: * This method gets the display size for the component in characters.
380: *
381: * @return DOCUMENT ME!
382: */
383: public int getSize() {
384: return _size;
385: }
386:
387: /**
388: * This method sets the property theme for the component.
389: *
390: * @param theme The theme to use.
391: */
392: public void setTheme(String theme) {
393: super .setTheme(theme);
394:
395: Props props = getPage().getPageProperties();
396: _fontTagStart = props.getThemeProperty(theme, Props.FONT_DDLB
397: + Props.TAG_START);
398: _fontTagEnd = props.getThemeProperty(theme, Props.FONT_DDLB
399: + Props.TAG_END);
400: }
401:
402: /**
403: * Use this method to add new choices to the list.
404: *
405: * @param key The internal name of the item (must be unique)
406: * @param disp The value to be displayed on the list.
407: */
408: public void addOption(String key, String disp) {
409: addOption(key, disp, false);
410: }
411:
412: /**
413: * Use this method to add new choices to the list.
414: *
415: * @param key The internal name of the item (must be unique)
416: * @param disp The value to be displayed on the list.
417: * @param selected DOCUMENT ME!
418: */
419: public void addOption(String key, String disp, boolean selected) {
420: HtmlOption opt = new HtmlOption(key, disp, selected);
421: _options.addElement(opt);
422: }
423:
424: /**
425: * Deselects all items in the list
426: */
427: public void deselectAll() {
428: setAll(false);
429: }
430:
431: /**
432: * This method returns the index of the option with the specified key.
433: *
434: * @param key DOCUMENT ME!
435: *
436: * @return The index of the key or -1 if not found.
437: */
438: public int findOptionIndexOf(String key) {
439: int optionsSize = _options.size();
440: HtmlOption opt = null;
441:
442: for (int i = 0; i < optionsSize; i++) {
443: opt = (HtmlOption) _options.elementAt(i);
444:
445: if (key.equals(opt.getKey())) {
446: return i;
447: }
448: }
449:
450: return -1;
451: }
452:
453: public void generateHTML(java.io.PrintWriter p, int rowNo)
454: throws Exception {
455: if (!_visible) {
456: return;
457: }
458:
459: String name = getFullName();
460:
461: if (rowNo > -1) {
462: name += ("_" + rowNo);
463: }
464:
465: String value = getValue(rowNo, true);
466:
467: if (_dsBuff != null) {
468: if (value == null) {
469: setInternalValue(null);
470: } else {
471: setInternalValue(value.toString());
472: }
473: }
474:
475: String tag = "<SELECT NAME=\"" + name + "\"";
476: tag += (" SIZE=\"" + _size + "\"");
477:
478: if (_multi) {
479: tag += " MULTIPLE";
480: }
481:
482: if (_onChange != null) {
483: tag += (" onChange=\"" + _onChange + "\"");
484: }
485:
486: if (_onFocus != null) {
487: tag += (" onFocus=\"" + _onFocus + "\"");
488: }
489:
490: if (_onLoseFocus != null) {
491: tag += (" onBlur=\"" + _onLoseFocus + "\"");
492: }
493:
494: if (_onClick != null) {
495: tag += (" onClick=\"" + _onClick + "\"");
496: }
497:
498: if (_class != null) {
499: tag += (" class=\"" + _class + "\"");
500: }
501:
502: if (_style != null) {
503: tag += (" style=\"" + _style + "\"");
504: }
505:
506: if ((!_enabled) && useDisabledAttribute()) {
507: tag += " disabled=\"true\"";
508: }
509:
510: if (_tabIndex != null)
511: tag += " tabindex=\"" + _tabIndex + "\"";
512:
513: if (_accessKey != null)
514: tag += " accesskey=\"" + _accessKey + "\"";
515:
516: tag += ">";
517:
518: StringBuffer b = new StringBuffer();
519: int optionsSize = _options.size();
520:
521: for (int i = 0; i < optionsSize; i++) {
522: HtmlOption opt = (HtmlOption) _options.elementAt(i);
523: b.append("<OPTION VALUE=\"");
524: b.append(opt.getKey());
525: b.append("_");
526: b.append(i);
527: b.append("\"");
528:
529: if (opt.isSelected()) {
530: b.append(" SELECTED");
531: }
532:
533: if (opt.getDisplay() == null) {
534: b.append("></OPTION>");
535: } else {
536: b.append(">");
537: b.append(opt.getDisplay());
538: b.append("</OPTION>");
539: }
540: }
541:
542: tag += b.toString();
543: tag += "</SELECT>";
544:
545: if (_fontTagStart != null) {
546: tag = _fontTagStart + tag + _fontTagEnd;
547: }
548:
549: p.println(tag);
550: writeFocusScript(p, rowNo);
551: }
552:
553: /**
554: * Creates a list box based on a table with an <BR> integer primary key column (typically an id) and a string column.<BR> A simplifying assumption is that each of the following <BR> is the same: <BR> - name of column in the main table which refers to the simple table <BR> - name of integer column in simple table <BR>
555: *
556: * @param table - name of table to look up keys and displays from
557: * @param keyColumn - column to get key values from
558: * @param dispColumn - column to get display values from
559: * @param criteria - optional selection criteria
560: * @param inputVersion - optional value that allows for a null to be placed at the top
561: */
562: public void initialize(String table, String keyColumn,
563: String dispColumn, String criteria, boolean inputVersion) {
564: initialize(table, keyColumn, dispColumn, criteria,
565: inputVersion, false);
566: }
567:
568: /**
569: * Creates a list box based on a table with an <BR> integer primary key column (typically an id) and a string column.<BR> A simplifying assumption is that each of the following <BR> is the same: <BR> - name of column in the main table which refers to the simple table <BR> - name of integer column in simple table <BR>
570: *
571: * @param table - name of table to look up keys and displays from
572: * @param keyColumn - column to get key values from
573: * @param dispColumn - column to get display values from
574: * @param criteria - optional selection criteria
575: * @param inputVersion - optional value that allows for a null to be placed at the top
576: * @param trimResults - optional value that trims the rtesults before adding the options
577: */
578: public void initialize(String table, String keyColumn,
579: String dispColumn, String criteria, boolean inputVersion,
580: boolean trimResults) {
581: initialize(table, keyColumn, dispColumn, criteria,
582: inputVersion, trimResults, false);
583: }
584:
585: /**
586: * Creates a list box based on a table with an <BR> integer primary key column (typically an id) and a string column.<BR> A simplifying assumption is that each of the following <BR> is the same: <BR> - name of column in the main table which refers to the simple table <BR> - name of integer column in simple table <BR>
587: *
588: * @param table - name of table to look up keys and displays from
589: * @param keyColumn - column to get key values from
590: * @param dispColumn - column to get display values from
591: * @param criteria - optional selection criteria
592: * @param inputVersion - optional value that allows for a null to be placed at the top
593: * @param trimResults - optional value that trims the rtesults before adding the options
594: * @param toUpper - optional value that makes the option's kays and display values all upper case
595: */
596: public void initialize(String table, String keyColumn,
597: String dispColumn, String criteria, boolean inputVersion,
598: boolean trimResults, boolean toUpper) {
599: resetOptions();
600:
601: if (inputVersion) {
602: addOption(null, "");
603: }
604:
605: DBConnection connection = null;
606:
607: try {
608: connection = DBConnection.getConnection(getPage()
609: .getApplicationName());
610:
611: java.sql.Statement s = connection.createStatement();
612: String query = null;
613:
614: if (criteria != null) {
615: query = "SELECT " + keyColumn + "," + dispColumn
616: + " FROM " + table + " WHERE " + criteria
617: + " ORDER BY ";
618:
619: if (toUpper) {
620: query = query + "UPPER(" + dispColumn + ")";
621: } else {
622: query += dispColumn;
623: }
624: } else {
625: query = "SELECT " + keyColumn + "," + dispColumn
626: + " FROM " + table + " ORDER BY ";
627:
628: if (toUpper) {
629: query = query + "UPPER(" + dispColumn + ")";
630: } else {
631: query += dispColumn;
632: }
633: }
634:
635: java.sql.ResultSet r = s.executeQuery(query);
636:
637: int cols = r.getMetaData().getColumnCount();
638: String key, display;
639: if (r.next()) {
640: do {
641: key = "";
642: display = "";
643: if (trimResults) {
644: key = r.getObject(1).toString().trim();
645: for (int i = 2; i <= cols; i++)
646: display = display
647: + r.getObject(i).toString().trim()
648: + " ";
649:
650: addOption(key, display);
651: } else {
652: key = r.getObject(1).toString();
653: for (int i = 2; i <= cols; i++)
654: display = display
655: + r.getObject(i).toString() + " ";
656: addOption(key, display);
657: }
658: } while (r.next());
659: }
660:
661: r.close();
662: s.close();
663: } catch (java.sql.SQLException se) {
664: MessageLog.writeErrorMessage("initialize", se, null);
665: } catch (Exception e) {
666: MessageLog.writeErrorMessage("initialize", e, this );
667: } finally {
668: if (connection != null) {
669: connection.freeConnection();
670: }
671: }
672: }
673:
674: public boolean processParms(Hashtable parms, int rowNo)
675: throws Exception {
676: Object oldValue = _value;
677: String name = getFullName();
678:
679: if (rowNo > -1) {
680: name += ("_" + rowNo);
681:
682: if (_dsBuff != null) {
683: oldValue = _dsBuff.getAny(rowNo, _dsColNo);
684: }
685: } else {
686: if (_dsBuff != null) {
687: oldValue = _dsBuff.getAny(_dsColNo);
688: }
689: }
690:
691: String val[] = (String[]) parms.get(name);
692: int optionsSize = _options.size();
693: HtmlOption opt = null;
694:
695: for (int i = 0; i < optionsSize; i++) {
696: opt = (HtmlOption) _options.elementAt(i);
697: opt.setSelected(false);
698: }
699:
700: if (val != null) {
701: int index = -1;
702:
703: for (int i = 0; i < val.length; i++) {
704: index = Integer.parseInt(val[i].substring(val[i]
705: .lastIndexOf("_") + 1));
706: if (index < _options.size()) {
707: opt = (HtmlOption) _options.elementAt(index);
708: opt.setSelected(true);
709: }
710: }
711: }
712:
713: if (!_multi)
714: _value = getInternalValue();
715: else
716: _value = getSelectedList(",");
717:
718: if (!valuesEqual(oldValue, _value)) {
719: String s = null;
720:
721: if (oldValue != null) {
722: s = oldValue.toString();
723: }
724:
725: ValueChangedEvent e = new ValueChangedEvent(getPage(),
726: this , getName(), getFullName(), s, _value, rowNo,
727: _dsColNo, _dsBuff);
728: addEvent(e);
729: }
730:
731: return false;
732: }
733:
734: /**
735: * Use this method to remove an option from the list.
736: *
737: * @param index The index of the option to remove.
738: */
739: public void removeOption(int index) {
740: if ((index < 0) || (index >= _options.size())) {
741: return;
742: }
743:
744: _options.removeElementAt(index);
745: }
746:
747: /**
748: * This method removes all options from the component.
749: */
750: public void resetOptions() {
751: _options.removeAllElements();
752: }
753:
754: /**
755: * Selects all items in the list
756: */
757: public void selectAll() {
758: setAll(true);
759: }
760:
761: /**
762: * Claudio Pi (4-01-2003) This method sorts the dropdown list based on its options values in the default order direction.
763: */
764: public void sort() {
765: _options.sort();
766: }
767:
768: /**
769: * Claudio Pi (4-01-2003) This method sorts the dropdown list based on its options values in the given order direction.
770: *
771: * @param dir direction in which the options will be sorted (0=Ascending or 1=Descending order)
772: */
773: public void sort(int dir) {
774: _options.setSortDir(dir);
775: _options.sort();
776: }
777:
778: /**
779: * This method sets the first selected option in the list box to the one with the key.
780: *
781: * @param value DOCUMENT ME!
782: */
783: private void setInternalValue(String value) {
784:
785: int optionsSize = _options.size();
786: HtmlOption opt = null;
787: String key = null;
788: boolean selected = false;
789:
790: //
791: for (int i = 0; i < optionsSize; i++) {
792: opt = (HtmlOption) _options.elementAt(i);
793: key = opt.getKey();
794: selected = false;
795:
796: if (key != null) {
797: if (key.equals(value)) {
798: selected = true;
799: }
800: }
801:
802: opt.setSelected(selected);
803: }
804: }
805:
806: /**
807: * This method returns the key of the first selected option in the list box..
808: *
809: * @return DOCUMENT ME!
810: */
811: private String getInternalValue() {
812: int optionsSize = _options.size();
813: HtmlOption opt = null;
814:
815: for (int i = 0; i < optionsSize; i++) {
816: opt = (HtmlOption) _options.elementAt(i);
817:
818: if (opt.isSelected()) {
819: return opt.getKey();
820: }
821: }
822:
823: return null;
824: }
825:
826: /**
827: * @return the access key html attribute
828: */
829: public String getAccessKey() {
830: return _accessKey;
831: }
832:
833: /**
834: * @return the tab index html attribute
835: */
836: public int getTabIndex() {
837: if (_tabIndex == null)
838: return -1;
839: return _tabIndex.intValue();
840: }
841:
842: /**
843: * @param string sets the access key html attribute
844: */
845: public void setAccessKey(String string) {
846: _accessKey = string;
847: }
848:
849: /**
850: * @param val sets the tab index html attribute. You can also pass TAB_INDEX_DEFAULT to use the default tab index for the component or TAB_INDEX_NONE to keep this component from being tabbed to
851: */
852: public void setTabIndex(int val) {
853: if (val == -1)
854: _tabIndex = null;
855: else
856: _tabIndex = new Integer(val);
857: }
858:
859: /**
860: * This method sets the property style (allows for the inlining of style attributes like color:#666666;) for the component.
861: *
862: * @param style - The style text to use.
863: */
864: public void setStyle(String style) {
865: _style = style;
866: }
867:
868: /**
869: * This method gets the property style (allows for the inlining of style attributes like color:#666666;) for the component.
870: *
871: * @return DOCUMENT ME!
872: */
873: public String getStyle() {
874: return _style;
875: }
876:
877: }
|