001: package com.salmonllc.html;
002:
003: /////////////////////////
004: //$Archive: /SOFIA/SourceCode/com/salmonllc/html/HtmlTelephoneComponent.java $
005: //$Author: Dan $
006: //$Revision: 37 $
007: //$Modtime: 3/17/04 2:01p $
008: /////////////////////////
009:
010: import java.util.Hashtable;
011:
012: import com.salmonllc.html.events.ValueChangedEvent;
013:
014: /**
015: * Creates a component for editing a telephone number
016: */
017:
018: public class HtmlTelephoneComponent extends HtmlFormComponent {
019: protected HtmlContainer _cont;
020: protected HtmlTextEdit _editAreaCode, _editPhoneStart,
021: _editPhoneEnd;
022:
023: private HtmlText _txtAreaCodeStart;
024: private HtmlText _txtAreaCodeEnd;
025: private HtmlText _txtSeparator;
026:
027: private String _sAreaCode, _sPhoneStart, _sPhoneEnd;
028: private String _sPhoneSeparator, _sAreaCodeStart, _sAreaCodeEnd;
029:
030: private boolean _bApplyStyle;
031: private boolean _autoTab;
032:
033: /**
034: * HtmlTelephoneComponent constructor comment.
035: *
036: * @param name Name of component.
037: * @param p Page containing component.
038: */
039: public HtmlTelephoneComponent(String name, HtmlPage p) {
040: this (name, p, "-", "(", ")", true);
041: }
042:
043: /**
044: * HtmlTelephoneComponent constructor comment.
045: *
046: * @param name Name of component.
047: * @param p Page containing component.
048: * @param phoneSeparator character to display between the 3rd & 4th digit of the phone.
049: * @param areaCodeStart character to display before an area code
050: * @param areaCodeEnd character to display after an area code
051: * @param bApplyStyle boolean to elect to apply the style to the static elements of the phone component, i.e. ()-
052: */
053: public HtmlTelephoneComponent(String name, HtmlPage p,
054: String phoneSeparator, String areaCodeStart,
055: String areaCodeEnd, boolean bApplyStyle) {
056: super (name, p);
057:
058: boolean netscape6or7 = (getPage().getBrowserType() == HtmlPage.BROWSER_NETSCAPE)
059: && (getPage().getBrowserVersion() >= 6);
060: _sAreaCodeStart = areaCodeStart;
061: _sAreaCodeEnd = areaCodeEnd;
062: _sPhoneSeparator = phoneSeparator;
063:
064: // 10/01/03 - BYD - Added the option to not apply a style to the static elements of a telephone #
065: // such as () and -
066: // The main reason is to avoid unsightly border when border is added to style
067: // The default is to apply the style ... for backward compatibility
068: _bApplyStyle = bApplyStyle;
069:
070: _txtAreaCodeStart = new HtmlText(areaCodeStart, getPage());
071: _txtAreaCodeEnd = new HtmlText(areaCodeEnd, getPage());
072: _txtSeparator = new HtmlText(phoneSeparator, getPage());
073:
074: _cont = new HtmlContainer(name, p);
075: // starting area code char
076: if (areaCodeStart != null && !areaCodeStart.trim().equals("")) {
077: _cont.add(_txtAreaCodeStart);
078: }
079:
080: // area code field
081: _cont.add(_editAreaCode = new HtmlTextEdit("areaCode", p));
082: _editAreaCode.setGenerateNewline(false);
083: _editAreaCode.setSize(netscape6or7 ? 5 : 3);
084: _editAreaCode.setMaxLength(3);
085:
086: // ending area code char
087: if (areaCodeEnd != null && !areaCodeEnd.trim().equals("")) {
088: _cont.add(_txtAreaCodeEnd);
089: }
090: //first three digits of hone number
091: _cont.add(_editPhoneStart = new HtmlTextEdit("phoneStart", p));
092: _editPhoneStart.setGenerateNewline(false);
093: _editPhoneStart.setSize(netscape6or7 ? 5 : 3);
094: _editPhoneStart.setMaxLength(3);
095:
096: // separator
097: if (phoneSeparator != null && !phoneSeparator.trim().equals("")) {
098: _cont.add(_txtSeparator);
099: }
100:
101: // last four digits
102: _cont.add(_editPhoneEnd = new HtmlTextEdit("phoneEnd", p));
103: _editPhoneEnd.setGenerateNewline(false);
104: _editPhoneEnd.setSize(netscape6or7 ? 7 : 4);
105: _editPhoneEnd.setMaxLength(4);
106:
107: }
108:
109: public void generateHTML(java.io.PrintWriter p, int row)
110: throws Exception {
111: // It is essential to call getValue() here because there may be a ValueChanged
112: // event in the queue for this object, which needs to be removed, which getValue()
113: // does. The secondary calls to getValue() from the container will not
114: // do this because there are no events associated with them.
115: String val = getValue(row, true);
116: if (val == null || val.trim().equals("")) {
117: _editAreaCode.setValue(null, row);
118: _editPhoneStart.setValue(null, row);
119: _editPhoneEnd.setValue(null, row);
120: } else {
121: String sVal;
122: if (_dsBuff != null) {
123: if (row >= 0)
124: sVal = _dsBuff.getString(row, _dsColNo);
125: else
126: sVal = _dsBuff.getString(_dsColNo);
127: } else
128: sVal = val;
129:
130: /* If user enters inc=valid value like "'$&@!$%^()* " val is not null but the value in the
131: datastore is null. Therefore sVal is null.*/
132: if (sVal != null && sVal.length() == 10) {
133: _editAreaCode.setValue(sVal.substring(0, 3), row);
134: _editPhoneStart.setValue(sVal.substring(3, 6), row);
135: _editPhoneEnd.setValue(sVal.substring(6), row);
136: }
137: if (sVal != null && sVal.length() == 7) {
138: _editAreaCode.setValue(null, row);
139: _editPhoneStart.setValue(sVal.substring(0, 3), row);
140: _editPhoneEnd.setValue(sVal.substring(3), row);
141: }
142: if (sVal != null && sVal.length() != 10
143: && sVal.length() != 7) {
144: _editAreaCode.setValue(_sAreaCode);
145: _editPhoneStart.setValue(_sPhoneStart);
146: _editPhoneEnd.setValue(_sPhoneEnd);
147: }
148:
149: }
150: if (_enabled && _autoTab) {
151: _editAreaCode.setOnKeyUp("return " + getFullName()
152: + "_autoTab(this, 3, event);");
153: _editPhoneStart.setOnKeyUp("return " + getFullName()
154: + "_autoTab(this, 3, event);");
155: } else {
156: _editAreaCode.setOnKeyUp(null);
157: _editPhoneStart.setOnKeyUp(null);
158: }
159:
160: if (_enabled || useDisabledAttribute() || val != null)
161: _cont.generateHTML(p, row);
162:
163: if (_visible && _enabled) {
164: p.println("");
165: if (_autoTab)
166: generateAutoTabJavaScript(p);
167: }
168: }
169:
170: /**
171: * 10/01/03 - BYD - Added the option to not apply a style to the static elements of a telephone #
172: * such as () and -
173: * The main reason is to avoid unsightly border when border is added to style
174: *
175: * Gets the Apply Style boolean
176: * @return boolean
177: */
178: public boolean getApplyStyle() {
179: return _bApplyStyle;
180: }
181:
182: /**
183: * 10/01/03 - BYD - Added the option to not apply a style to the static elements of a telephone #
184: * such as () and -
185: * The main reason is to avoid unsightly border when border is added to style
186: *
187: * Sets the Apply Style boolean for static elements of the phone component
188: * @param bApplyStyle boolean
189: */
190: public void setApplyStyle(boolean bApplyStyle) {
191: _bApplyStyle = bApplyStyle;
192: }
193:
194: /**
195: * Gets the Area code.
196: * @return java.lang.String
197: */
198: public String getAreaCode() {
199: return _sAreaCode != null ? _sAreaCode : "";
200: }
201:
202: /**
203: * Gets the Area code ending char.
204: * @return java.lang.String
205: */
206: public java.lang.String getAreaCodeEnd() {
207: return _sAreaCodeEnd;
208: }
209:
210: /**
211: * Gets the Area code starting char.
212: * @return java.lang.String
213: */
214: public java.lang.String getAreaCodeStart() {
215: return _sAreaCodeStart;
216: }
217:
218: /**
219: * Returns the sub-component to be used for setting focus.
220: * @return com.salmonllc.html.HtmlComponent
221: */
222: public HtmlComponent getFocus() {
223: return _editAreaCode;
224: }
225:
226: /**
227: * This method returns the formatted phone number provided that the component
228: * contains a valid value otherwise it returns an empty string
229: * @return java.lang.String
230: */
231: public String getFormattedValue() {
232: String sFormattedPhone = "";
233:
234: if (isValid()) {
235: if (_sAreaCode.length() == 3)
236: sFormattedPhone = _sAreaCodeStart + _sAreaCode
237: + _sAreaCodeEnd;
238:
239: sFormattedPhone += _sPhoneStart + _sPhoneSeparator
240: + _sPhoneEnd;
241: }
242:
243: return sFormattedPhone;
244: }
245:
246: /**
247: * Gets the Phone Number.
248: * @return java.lang.String
249: */
250: public String getPhone() {
251: return _sPhoneStart + _sPhoneEnd;
252: }
253:
254: /**
255: * Gets the separator char.
256: * @return java.lang.String
257: */
258: public java.lang.String getPhoneSeparator() {
259: return _sPhoneSeparator;
260: }
261:
262: /**
263: * Gets the current value of the control.
264: * @return java.lang.String
265: */
266: public String getValue() {
267: String sValue = "";
268: if (_sAreaCode != null)
269: sValue += _sAreaCode;
270: if (_sPhoneStart != null)
271: sValue += _sPhoneStart;
272: if (_sPhoneEnd != null)
273: sValue += _sPhoneEnd;
274: return sValue;
275: }
276:
277: /**
278: * Returns whether component is visible or not.
279: * Creation date: (7/19/01 8:41:20 AM)
280: * @return boolean Indicates if component is visible or not.
281: */
282: public boolean getVisible() {
283: return _cont.getVisible();
284: }
285:
286: /**
287: * Returns whether the Telephone Number entered is valid or not.
288: * @return boolean Indicates whether Telephone Number is valid or not.
289: */
290: public boolean isValid() {
291: String sAC = _sAreaCode;
292: String sPhoneStart = _sPhoneStart;
293: String sPhoneEnd = _sPhoneEnd;
294:
295: _editAreaCode.setValue(_sAreaCode);
296: _editPhoneStart.setValue(_sPhoneStart);
297: _editPhoneEnd.setValue(_sPhoneEnd);
298:
299: String sPhone = sPhoneStart + sPhoneEnd;
300:
301: int iValidLength = 7;
302:
303: // If the Area Code is not null prepend it to the phone string
304: // and adjust the correct length of the phone string
305: if (sAC != null && !sAC.trim().equals("")) {
306: sPhone = sAC + sPhone;
307: iValidLength = 10;
308: }
309:
310: // Ensure that the length of the phone string is correct
311: if (sPhone.length() != iValidLength)
312: return false;
313:
314: // Corrected the argument of the charAt() method from 0 to i to ensure
315: // that all characters be checked and not just the first one
316: boolean bNumeric = true;
317:
318: for (int i = 0; i < sPhone.length(); i++) {
319: char c = sPhone.charAt(i);
320:
321: if (!Character.isDigit(c)) {
322: bNumeric = false;
323: break;
324: }
325: }
326: return bNumeric;
327: }
328:
329: public boolean processParms(Hashtable parms, int rowNo)
330: throws Exception {
331:
332: if (!getVisible() || !getEnabled())
333: return false;
334:
335: // Determine the old value from both edit fields.
336:
337: String oldValue = "";
338: if (_dsBuff == null) {
339: String sAreaCD = _editAreaCode.getValue();
340: String sExchge = _editPhoneStart.getValue();
341: String sLast4 = _editPhoneEnd.getValue();
342:
343: /*
344: We have to create the value changed events in the same way for both old and new values.
345: if the old values is null for all fields, than oldValue = "nullnullnull". If user changed only one field
346: we have to still create the old and new values by combining 3 fields. In that case old value
347: can be "null123null". Although the phone number is not valid, we must still create a value changed event.
348: TT20010713
349: */
350: if (sAreaCD != null)
351: oldValue += sAreaCD;
352: if (sExchge != null)
353: oldValue += sExchge;
354: if (sLast4 != null)
355: oldValue += sLast4;
356:
357: } else {
358: String s;
359: if (rowNo > -1)
360: s = _dsBuff.getString(rowNo, _dsColNo);
361: else
362: s = _dsBuff.getString(_dsColNo);
363: if (s == null)
364: oldValue = "";
365: else
366: oldValue = s;
367: }
368:
369: // Determine the new value from all three edit fields.
370:
371: String newValue = "", newValue1, newValue2, newValue3;
372:
373: String name1 = _editAreaCode.getFullName();
374: if (rowNo > -1)
375: name1 += "_" + rowNo;
376: String val[] = (String[]) parms.get(name1);
377: if (val != null) {
378: _sAreaCode = newValue1 = val[0].trim();
379: if (newValue1.equals(""))
380: newValue1 = null;
381: } else {
382: newValue1 = null;
383: }
384:
385: String name2 = _editPhoneStart.getFullName();
386: if (rowNo > -1)
387: name2 += "_" + rowNo;
388: val = (String[]) parms.get(name2);
389: if (val != null) {
390: _sPhoneStart = newValue2 = val[0].trim();
391: if (newValue2.equals(""))
392: newValue2 = null;
393: } else {
394: newValue2 = null;
395: }
396:
397: String name3 = _editPhoneEnd.getFullName();
398: if (rowNo > -1)
399: name3 += "_" + rowNo;
400: val = (String[]) parms.get(name3);
401: if (val != null) {
402: _sPhoneEnd = newValue3 = val[0].trim();
403: if (newValue3.equals(""))
404: newValue3 = null;
405: } else {
406: newValue3 = null;
407: }
408:
409: // if (newValue1 != null && newValue2 != null && newValue3 != null) TT20010713
410: if (newValue1 != null)
411: newValue += newValue1;
412: if (newValue2 != null)
413: newValue += newValue2;
414: if (newValue3 != null)
415: newValue += newValue3;
416:
417: // else TT20010713
418: // newValue = null; TT20010713
419:
420: // Compare old and new values and possibly create a ValueChangedEvent.
421: if (!valuesEqual(oldValue, newValue)) {
422: ValueChangedEvent e = new ValueChangedEvent(getPage(),
423: this , getName(), getFullName(), oldValue, newValue,
424: rowNo, _dsColNo, _dsBuff);
425: addEvent(e);
426: }
427: return false;
428: }
429:
430: /**
431: * This method will clear all pending events from the event queue for this component.
432: */
433: public void reset() {
434: super .reset();
435: _cont.reset();
436: }
437:
438: /**
439: * Replaces the area code end component
440: * @param newAreaCodeEnd java.lang.String
441: */
442: public void setAreaCodeEnd(java.lang.String newAreaCodeEnd) {
443: _sAreaCodeEnd = newAreaCodeEnd;
444: // create new text comp
445: HtmlText txtNewAreaCodeEnd = new HtmlText(newAreaCodeEnd,
446: getPage());
447:
448: // replace old area code end comp with new one
449: _cont.replaceComponent(txtNewAreaCodeEnd, _txtAreaCodeEnd);
450:
451: // save ref of new comp
452: _txtAreaCodeEnd = txtNewAreaCodeEnd;
453: }
454:
455: /**
456: * Replaces the area code start component
457: * @param newAreaCodeStart java.lang.String
458: */
459: public void setAreaCodeStart(java.lang.String newAreaCodeStart) {
460: _sAreaCodeStart = newAreaCodeStart;
461: // create new text comp
462: HtmlText txtNewAreaCodeStart = new HtmlText(newAreaCodeStart,
463: getPage());
464:
465: // replace old area code start comp with new one
466: _cont.replaceComponent(txtNewAreaCodeStart, _txtAreaCodeStart);
467:
468: // save ref of new comp
469: _txtAreaCodeStart = txtNewAreaCodeStart;
470: }
471:
472: /**
473: * Specifies the Style Class to be used for the Telephone Component.
474: * Creation date: (7/19/01 8:41:20 AM)
475: * @param sClass java.lang.String A name of a class in Html to be used by this component
476: */
477: public void setClassName(String sClass) {
478: super .setClassName(sClass);
479:
480: if (_bApplyStyle) {
481: if (_txtAreaCodeStart != null)
482: _txtAreaCodeStart.setClassName(sClass);
483: if (_txtAreaCodeEnd != null)
484: _txtAreaCodeEnd.setClassName(sClass);
485: if (_txtSeparator != null)
486: _txtSeparator.setClassName(sClass);
487: }
488:
489: if (_editAreaCode != null)
490: _editAreaCode.setClassName(sClass);
491: if (_editPhoneStart != null)
492: _editPhoneStart.setClassName(sClass);
493: if (_editPhoneEnd != null)
494: _editPhoneEnd.setClassName(sClass);
495: }
496:
497: /**
498: * Sets the font end tag for disabled mode.
499: * @param tag java.lang.String
500: */
501: public void setDisabledFontEndTag(String tag) {
502: _editAreaCode.setDisabledFontEndTag(tag);
503: _editPhoneStart.setDisabledFontEndTag(tag);
504: _editPhoneEnd.setDisabledFontEndTag(tag);
505:
506: _txtAreaCodeStart.setFontEndTag(tag);
507: _txtAreaCodeEnd.setFontEndTag(tag);
508: _txtSeparator.setFontEndTag(tag);
509:
510: }
511:
512: /**
513: * Sets the font tag for disabled mode.
514: * @param tag java.lang.String
515: */
516: public void setDisabledFontStartTag(String tag) {
517:
518: _editAreaCode.setDisabledFontStartTag(tag);
519: _editPhoneStart.setDisabledFontStartTag(tag);
520: _editPhoneEnd.setDisabledFontStartTag(tag);
521:
522: _txtAreaCodeStart.setFontStartTag(tag);
523: _txtAreaCodeEnd.setFontStartTag(tag);
524: _txtSeparator.setFontStartTag(tag);
525: }
526:
527: /**
528: * Enables or disables the ability of this component to respond to user input.
529: */
530: public void setEnabled(boolean enabled) {
531: super .setEnabled(enabled);
532: _cont.setEnabled(enabled);
533: }
534:
535: /**
536: * This method will set the edit focus to this component.
537: */
538: public void setFocus() {
539: _editAreaCode.setFocus();
540: }
541:
542: /**
543: * This method will set the edit focus to this component for a particular row in a datastore.
544: */
545: public void setFocus(int row) {
546: _editAreaCode.setFocus(row);
547: }
548:
549: /**
550: * Specifies the parent component for this Telephone Component.
551: * Creation date: (7/19/01 8:41:20 AM)
552: */
553: public void setParent(HtmlComponent parent) {
554: super .setParent(parent);
555: // This is necessary for the name to be generated correctly, else the leading
556: // sequence of parent names will be lost.
557: _cont.setParent(parent);
558: }
559:
560: /**
561: * Replaces the separator between the phone numbers
562: * @param newPhoneSeparator java.lang.String
563: */
564: public void setPhoneSeparator(java.lang.String newPhoneSeparator) {
565: _sPhoneSeparator = newPhoneSeparator;
566:
567: // create new text comp
568: HtmlText txtNewSeparator = new HtmlText(newPhoneSeparator,
569: getPage());
570:
571: // replace old area code end comp with new one
572: _cont.replaceComponent(txtNewSeparator, _txtSeparator);
573:
574: // save ref of new comp
575: _txtSeparator = txtNewSeparator;
576: }
577:
578: /**
579: * Sets the theme of the Telephone Component.
580: * Creation date: (7/19/01 8:41:20 AM)
581: * @param theme java.lang.String The theme of the component
582: */
583: public void setTheme(String theme) {
584: super .setTheme(theme);
585:
586: if (_txtAreaCodeStart != null)
587: _txtAreaCodeStart.setTheme(theme);
588: if (_txtAreaCodeEnd != null)
589: _txtAreaCodeEnd.setTheme(theme);
590: if (_txtSeparator != null)
591: _txtSeparator.setTheme(theme);
592:
593: if (_editAreaCode != null)
594: _editAreaCode.setTheme(theme);
595: if (_editPhoneStart != null)
596: _editPhoneStart.setTheme(theme);
597: if (_editPhoneEnd != null)
598: _editPhoneEnd.setTheme(theme);
599: }
600:
601: /**
602: * Sets the visibility of the component.
603: * Creation date: (7/19/01 8:41:20 AM)
604: * @param visible boolean Indicates the visibility of the component
605: */
606: public void setVisible(boolean visible) {
607: _cont.setVisible(visible);
608: }
609:
610: /**
611: * Gets the middle three digits.
612: * @return java.lang.String
613: */
614: public String getMiddleThree() {
615: return _sPhoneStart != null ? _sPhoneStart : "";
616: }
617:
618: /**
619: * Gets the last four digits.
620: * @return java.lang.String
621: */
622: public String getLastFour() {
623: return _sPhoneEnd != null ? _sPhoneEnd : "";
624: }
625:
626: /**
627: * @return true if the component is set to automatically tab to next field
628: */
629: public boolean isAutoTab() {
630: return _autoTab;
631: }
632:
633: /**
634: * @return true if the component is set to automatically tab to next field
635: */
636: public void setAutoTab(boolean b) {
637: _autoTab = b;
638: }
639:
640: /**
641: * @returns the access key html attribute
642: */
643: public String getAccessKey() {
644: return _editAreaCode.getAccessKey();
645: }
646:
647: /**
648: * @returns the read only html attribute
649: */
650: public boolean getReadOnly() {
651: return _editAreaCode.getReadOnly();
652: }
653:
654: /**
655: * @returns the tab index html attribute
656: */
657: public int getTabIndex() {
658: return _editAreaCode.getTabIndex();
659: }
660:
661: /**
662: * @param sets the access key html attribute
663: */
664: public void setAccessKey(String val) {
665: _editAreaCode.setAccessKey(val);
666:
667: }
668:
669: /**
670: * @param sets the read only html attribute
671: */
672: public void setReadOnly(boolean val) {
673: _editAreaCode.setReadOnly(val);
674: _editPhoneStart.setReadOnly(val);
675: _editPhoneEnd.setReadOnly(val);
676: }
677:
678: /**
679: * @param 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
680: */
681: public void setTabIndex(int val) {
682: _editAreaCode.setTabIndex(val);
683: _editPhoneStart.setTabIndex(val + 1);
684: _editPhoneEnd.setTabIndex(val + 2);
685: }
686:
687: /**
688: * Returns the name of this component would be referenced by if used in javascript code
689: */
690: public String getJavaScriptName() {
691: return getFormString() + _editAreaCode.getFullName();
692: }
693: }
|