气泡.js
js:
1/**//*----------------------------------------------------------------------------\
2| JSBalloon |
3|-----------------------------------------------------------------------------|
4| Created by Arkady (Alex) Lesniara |
5| (arkady@lesniara.com) |
6|-----------------------------------------------------------------------------|
7| Copyright (c) 2005 Arkady Lesniara |
8|-----------------------------------------------------------------------------|
9| This software is provided "as is", without warranty of any kind, express or |
10| implied, including but not limited to the warranties of merchantability, |
11| fitness for a particular purpose and noninfringement. In no event shall the |
12| authors or copyright holders be liable for any claim, damages or other |
13| liability, whether in an action of contract, tort or otherwise, arising |
14| from, out of or in connection with the software or the use or other |
15| dealings in the software. |
16\----------------------------------------------------------------------------*/
17
18var JSBalloonPath="";
19
20/**//* Class: JSBalloon
21 Provides a flexible, encapsulated way to implement a passive feedback mechanism
22 in a DHTML environment. Define and initialize this object globally, otherwise it will create a new instance
23 each time you call it's constructor. Set up the object with an object array passed to the constructor or, once instantiated,
24 with properties. See <Usage> for more.
25*/
26function JSBalloon()
27{
28 var tmrBalloonPopup;
29
30 var blbWidth=200;;
31 var titleFontStyle='font-family: MS Sans Serif;font-weight: bold; font-size:10pt;';
32 var messageFontStyle='font-family: MS Sans Serif\; font-size:10pt\;';
33 var footerFontStyle='font-family: MS Sans Serif\; font-size:10pt\;';
34 var transShow=true;
35 var transHide=true;
36 var transShowFilter='progid:DXImageTransform.Microsoft.Fade(Overlap=1.00)';
37 var transHideFilter='progid:DXImageTransform.Microsoft.Fade(Overlap=1.00)';
38 var autoHide=true;
39 var autoHideInterval=4000; // 4 sec
40 var autoAway=true;
41 var showCloseBox=false;
42
43 if(JSBalloon.arguments.length>0)
44 {
45 var oArg=JSBalloon.arguments[0];
46
47 if(oArg.width!=null)
48 {
49 blbWidth=oArg.width;
50 }
51
52 if(oArg.titleFontStyle!=null)
53 {
54 titleFontStyle=oArg.titleFontStyle;
55 }
56
57 if(oArg.messageFontStyle!=null)
58 {
59 messageFontStyle=oArg.messageFontStyle;
60 }
61
62 if(oArg.footerFontStyle!=null)
63 {
64 footerFontStyle=oArg.footerFontStyle;
65 }
66
67 if(oArg.transShow!=null)
68 {
69 transShow=oArg.transShow;
70 }
71
72 if(oArg.transHide!=null)
73 {
74 transHide=oArg.transHide;
75 }
76
77 if(oArg.transShowFilter!=null)
78 {
79 transShowFilter=oArg.transShowFilter;
80 }
81
82 if(oArg.transHideFilter!=null)
83 {
84 transHideFilter=oArg.transHideFilter;
85 }
86
87 if(oArg.autoHide!=null)
88 {
89 autoHide=oArg.autoHide;
90 }
91
92 if(oArg.autoHideInterval!=null)
93 {
94 autoHideInterval=oArg.autoHideInterval;
95 }
96
97 if(oArg.autoAway!=null)
98 {
99 autoAway=oArg.autoAway;
100 }
101
102 if(oArg.showCloseBox!=null)
103 {
104 showCloseBox=oArg.showCloseBox;
105 }
106 }
107
108 // Public properties
109
110 /**//* Property: titleFontStyle
111 Sets or retrieves a Cascading Style Sheet formatted value that formats the balloon's title (heading).
112
113 Syntax:
114 object.titleFontStyle [= sCSS ]
115
116 Possible Values:
117 sCSS - *variant* that specifies a properly formed Cascading Style Sheet formatting.
118
119 Examples:
120 balloonObj.titleFontStyle="font-family: MS Sans Serif;font-weight: bold; font-size:12pt;";
121 */
122 this.titleFontStyle=titleFontStyle;
123
124 /**//* Property: messageFontStyle
125 Sets or retrieves a Cascading Style Sheet formatted value that formats the balloon's main message body.
126
127 Syntax:
128 object.messageFontStyle [= sCSS ]
129
130 Possible Values:
131 sCSS - *variant* that specifies a properly formed Cascading Style Sheet formatting.
132
133 Examples:
134 balloonObj.messageFontStyle="font-family: MS Sans Serif;font-weight: bold; font-size:12pt;";
135 */
136 this.messageFontStyle=messageFontStyle;
137
138 /**//* Property: footerFontStyle
139 Sets or retrieves a Cascading Style Sheet formatted value that formats the balloon's footer.
140
141 Syntax:
142 object.footerFontStyle [= sCSS ]
143
144 Possible Values:
145 sCSS - *variant* that specifies a properly formed Cascading Style Sheet formatting.
146
147 Examples:
148 balloonObj.footerFontStyle="font-family: MS Sans Serif;font-weight: bold; font-size:12pt;";
149 */
150 this.footerFontStyle=footerFontStyle;
151
152 /**//* Property: transShowFilter
153 Sets or retrieves a value of a transition (a filter) applied when showing the balloon.
154
155 Syntax:
156 object.transShowFilter [= string ]
157
158 Possible Values:
159 string - *variant* that specifies the transition filter. More information found at http://msdn.microsoft.com/workshop/author/filter/reference/reference.asp
160
161 Examples:
162 balloonObj.transShowFilter="progid:DXImageTransform.Microsoft.Stretch(stretchstyle=SPIN)";
163
164 See also:
165 <transShow>
166 */
167 this.transShowFilter=transShowFilter;
168
169 /**//* Property: transHideFilter
170 Sets or retrieves a value of a transition (a filter) applied when hiding the balloon.
171
172 Syntax:
173 object.transHideFilter [= string ]
174
175 Possible Values:
176 string - *variant* that specifies the transition filter. More information found at http://msdn.microsoft.com/workshop/author/filter/reference/reference.asp
177
178 Examples:
179 balloonObj.transHideFilter="progid:DXImageTransform.Microsoft.Slide(slidestyle=HIDE,Bands=1)";
180
181 See also:
182 <transHide>
183 */
184 this.transHideFilter=transHideFilter;
185
186 /**//* Property: transShow
187 Sets or retrieves a value indicating whether to apply transition filter specified in
188 <transShowFilter> when showing the balloon.
189
190 Syntax:
191 object.transShow [= bValue ]
192
193 Possible Values:
194 bValue - *boolean* true / false
195
196 Examples:
197 balloonObj.transShow=true;
198
199 See also:
200 <transShowFilter>
201 */
202 this.transShow=transShow;
203
204 /**//* Property: transHide
205 Sets or retrieves a value indicating whether to apply transition filter specified in
206 <transHideFilter> when hiding the balloon.
207
208 Syntax:
209 object.transHide [= bValue ]
210
211 Possible Values:
212 bValue - *boolean* true / false
213
214 Examples:
215 balloonObj.transHide=true;
216
217 See also:
218 <transHideFilter>
219 */
220 this.transHide=transHide;
221
222 /**//* Property: autoHide
223 Sets or retrieves a value indicating whether to automatically hide the balloon
224 after s time specified in <autoHideInterval>.
225
226 Syntax:
227 object.autoHide [= bValue ]
228
229 Possible Values:
230 bValue - *boolean* true / false
231
232 Examples:
233 balloonObj.autoHide=true;
234
235 See also:
236 <autoHideInterval>
237 */
238 this.autoHide=autoHide;
239
240 /**//* Property: autoHideInterval
241 Sets or retrieves a value indicating how long to wait before executing <autoHide>.
242
243 Syntax:
244 object.autoHideInterval [= iValue ]
245
246 Possible Values:
247 iValue - *integer* number of milliseconds to wait before activating <autoHide>.
248
249 Examples:
250 balloonObj.autoHideInterval=5000; // 5 Sec
251
252 See also:
253 <autoHide>
254 */
255 this.autoHideInterval=autoHideInterval;
256
257 /**//* Property: autoAway
258 Sets or retrieves a value of this property.
259 When set to true the balloon will immediately run the <Hide> method on mouse over.
260
261 This is particularly useful when the balloon is used only for passive feedback and
262 doesn't have to be dismissed. The user may want to perform some task quickly without having
263 to wait the time specified in the <autoHideInterval> while the balloon is obstructing a page
264 element.
265
266 Syntax:
267 object.autoAway [= bValue ]
268
269 Possible Values:
270 bValue - *boolean* true / false
271
272 Examples:
273 balloonObj.autoAway=true;
274 */
275 this.autoAway=autoAway;
276
277 /**//* Property: width
278 Sets or retrieves a value of balloon's width. The height is dynamic, the width has to be specified.
279
280 Syntax:
281 object.width [= iValue ]
282
283 Possible Values:
284 iValue - *integer* the number of pixels.
285
286 Examples:
287 balloonObj.width=325;
288 */
289 this.width=blbWidth;
290
291 /**//* Property: showCloseBox
292 Sets or retrieves a value of whether the close balloon (right-upper corner) should be displayed.
293 It makes sense to turn <autoHide> off when enabling this feature.
294
295 Syntax:
296 object.showCloseBox [= bValue ]
297
298 Possible Values:
299 bValue - *boolean* true / false
300
301 Examples:
302 balloonObj.showCloseBox=false;
303 */
304 this.showCloseBox=showCloseBox;
305
306 var childID;
307
308 // Constructor
309 var balloonDIV = document.createElement("DIV");
310 balloonDIV.style.width=String(blbWidth);
311 balloonDIV.style.position="absolute";
312 balloonDIV.style.visibility="hidden";
313 balloonDIV.style.filter=transShowFilter+' '+transHideFilter;
314 balloonDIV.style.zIndex=2001;
315
316 /**//* Property: balloon
317 Retrieves the reference to the instantiated balloon object.
318
319 Syntax:
320 [obj =] object.balloon
321
322 Possible Values:
323 obj - *object* balloon reference
324
325 Examples:
326 var obj = balloonObj.balloon;
327 */
328 this.balloon=balloonDIV;
329
330 // Pulic Methods
331 this.Show=Show;
332 this.Hide=Hide;
333
334 /**//* Function: Show
335 Makes the instantiated balloon appear.
336
337 Balloon content note:
338 Because SELECT objects are what's known as windowed controles
339 they need to be hidden when balloons are shown, otherwise they will always be on top
340 (they ignore zIndex attribute). It is normally done automatically by this control.
341 Sometimes, however, you may want to place a drop-down inside the balloon itself.
342 To override this default behaviour add an balloonMember expando attirbute to
343 the SELECT you are placing withing.
344
345 - e.g. <SELECT id=select1 name=select1 balloonMember=true>
346
347 Syntax:
348 (start code)
349 object.Show({[title:vTitle]
350 [,message:vMessage]
351 [,footer:vFooter]
352 [,top:vTop]
353 [,left:vLeft]
354 [,anchor:vAnchor]
355 [,icon:vIcon]
356 });
357 (end)
358
359 Possible Values:
360 vTitle - *string* Optional title text for the balloon.
361 vMessage - *string* Optional. Message body for the balloon.
362 vFooter - *string* Optional. Test displayed at the bottom of the balloon on a separate line.
363 vTop - *integer* Optional. Offset from the top of the screen or top of an anchor.
364 vLeft - *integer* Optional. Offset from the left of the screen or left of an anchor.
365 vAnchor - *object* Optional. Reference to the object that the balloon should use as reference for location.
366 vIcon - *string* Optional. Possible icon values may include one of the values below (case sensitive):
367 - Exclaim - pre-defined, triangle with an exclamation point.
368 - Stop - pre-defined, red circle with a white x inside.
369 - Info - pre-defined, white balloon with a letter "i" inside *Default*
370 - Help - a question mark inside a blue circle.
371 - a relative path to a custom icon.
372
373 Examples:
374
375 - balloonObj.Show({title:'JavaScript Balloon Example',message:'This is an example of a JSBalloon object. It\'s primary application is to provide a modeless feedback to DHTML applications.',anchor:tableCellObj, icon:'Info'});
376 - balloonObj1.Show({title:'JavaScript Balloon Example',message:'This is an example of a JSBalloon object. It\'s primary application is to provide a modeless feedback to DHTML applications.',anchor:tableCellObj});
377 - balloonObj2.Show({message:'This is an example of a JSBalloon object. It\'s primary application is to provide a modeless feedback to DHTML applications. ',anchor:tableCellObj});
378
379 */
380 function Show()
381 {
382 var title;
383 var message='';
384 var icon='';
385 var footer='';
386 var btop=0, bleft=0;
387 var atop=0, aleft=0;
388 var anchor;
389 var direction='SE';
390
391 // Updates
392 blbWidth=String(this.width);
393 titleFontStyle=this.titleFontStyle;
394 messageFontStyle=this.messageFontStyle;
395 footerFontStyle=this.footerFontStyle;
396 transShowFilter=this.transShowFilter;
397 transHideFilter=this.transHideFilter;
398 transShow=this.transShow;
399 transHide=this.transHide;
400 autoHide=this.autoHide;
401 autoHideInterval=this.autoHideInterval;
402 autoAway=this.autoAway;
403
404 if(document.readyState!='complete')
405 {
406 alert('Document needs to fully load before you may show JSBalloons.');
407 return;
408 }
409
410 if(Show.arguments.length>0)
411 {
412 var oArg=Show.arguments[0];
413
414 if(oArg.title!=null)
415 {
416 title=oArg.title;
417 }
418
419 if(oArg.message!=null)
420 {
421 message=oArg.message;
422 }
423
424 if(oArg.icon!=null)
425 {
426 icon=oArg.icon;
427
428 switch(icon)
429 {
430 case 'Exclaim':
431 icon = JSBalloonPath+'images/exclaim.ico';
432 SoundFx = 'Exclaim';
433 break;
434
435 case 'Stop':
436 icon = JSBalloonPath+'images/stop.ico';
437 SoundFx = 'Stop';
438 break;
439
440 case 'Info':
441 icon = JSBalloonPath+'images/info.ico';
442 SoundFx = 'Info';
443 break;
444
445 case 'Help':
446 icon = JSBalloonPath+'images/help.ico';
447 SoundFx = 'Info';
448 break;
449
450 default:
451 SoundFx = 'Info';
452 }
453 }
454
455 if(oArg.footer!=null)
456 {
457 footer=oArg.footer;
458 }
459
460 if(oArg.top!=null)
461 {
462 btop=oArg.top;
463 }
464
465 if(oArg.left!=null)
466 {
467 bleft=oArg.left;
468 }
469
470 if(oArg.anchor!=null)
471 {
472 anchor=oArg.anchor;
473 atop=getTop(anchor);
474 aleft=getLeft(anchor);
475 }
476 }
477
478 // Figure out the best direction for the pointer
479
480 // Assume SE
481 var ret=balloonInfrastructure(balloonBody( title,
482 icon,
483 message,
484 footer,
485 this.titleFontStyle,
486 this.messageFontStyle,
487 this.footerFontStyle,
488 this.showCloseBox), direction);
489
490 // Populate the contents
491 balloonDIV.innerHTML=ret;
492
493 var btnClose=balloonDIV.children[0].children[0].children[1].children[0].children[0].children[0].children[0].children[2].children[0];
494 btnClose.onclick=this.Hide;
495
496 // check if the object is already initialized
497 if(typeof(childID)!='object')
498 {
499 childID=document.body.appendChild(balloonDIV);
500 }
501
502 if(anchor!=null)
503 {
504
505 balloonDIV.style.left = aleft+bleft;
506 balloonDIV.style.top = (atop-balloonDIV.offsetHeight)+btop;
507 }
508 else
509 {
510 balloonDIV.style.left = bleft;
511 balloonDIV.style.top = btop;
512 }
513
514
515 var bAdjustedLeft=parseInt(balloonDIV.style.left, 10);
516 var showSE;
517
518
519 if(document.body.offsetWidth < (bAdjustedLeft+balloonDIV.offsetWidth+20))
520 {
521 direction='SW';
522
523 ret=balloonInfrastructure(balloonBody( title,
524 icon,
525 message,
526 footer,
527 this.titleFontStyle,
528 this.messageFontStyle,
529 this.footerFontStyle,
530 this.showCloseBox), direction);
531 balloonDIV.innerHTML=ret;
532
533 balloonDIV.style.left = bAdjustedLeft-balloonDIV.offsetWidth+20;
534 showSE=false;
535 }
536 else
537 {
538 direction='SE';
539 showSE=true;
540 }
541
542 if(parseInt(balloonDIV.style.top, 10)<0)
543 {
544 if(showSE)
545 {
546 direction='NE';
547 ret=balloonInfrastructure(balloonBody( title,
548 icon,
549 message,
550 footer,
551 this.titleFontStyle,
552 this.messageFontStyle,
553 this.footerFontStyle,
554 this.showCloseBox), direction);
555 balloonDIV.innerHTML=ret;
556 }
557 else
558 {
559 direction='NW';
560 ret=balloonInfrastructure(balloonBody( title,
561 icon,
562 message,
563 footer,
564 this.titleFontStyle,
565 this.messageFontStyle,
566 this.footerFontStyle,
567 this.showCloseBox), direction);
568 balloonDIV.innerHTML=ret;
569 }
570 balloonDIV.style.top = parseInt(balloonDIV.style.top, 10)+balloonDIV.offsetHeight;
571 if(anchor!=null)
572 {
573 balloonDIV.style.top = parseInt(balloonDIV.style.top, 10)+anchor.offsetHeight
574 }
575 }
576
577 if(this.showCloseBox)
578 {
579 if(direction=='SE' || direction=='SW')
580 {
581 btnClose=balloonDIV.children[0].children[0].children[1].children[0].children[0].children[0].children[0].children[2].children[0];
582 }
583 else
584 {
585 btnClose=balloonDIV.children[0].children[0].children[2].children[0].children[0].children[0].children[0].children[2].children[0];
586 }
587 btnClose.onclick=this.Hide;
588 }
589
590 // Adjust all srollers
591 var scrollOffsets=ScrollOffsets(anchor);
592 balloonDIV.style.top=parseInt(balloonDIV.style.top, 10)-scrollOffsets[0];
593 balloonDIV.style.left=parseInt(balloonDIV.style.left, 10)-scrollOffsets[1];
594
595 // Hide any overlapping selects
596 SuppressSelects();
597
598 // Show balloon
599 if(this.transShow)
600 {
601 balloonDIV.style.filter=this.transShowFilter+' '+this.transHideFilter;
602 if(balloonDIV.filters(0).status==2 || balloonDIV.filters(0).status==1)
603 {
604 balloonDIV.filters(0).Stop();
605 }
606 balloonDIV.filters(0).Apply();
607 balloonDIV.style.visibility='visible';
608 balloonDIV.filters(0).Play();
609 }
610 else
611 {
612 balloonDIV.style.visibility='visible';
613 }
614
615 // Init autohide if true
616 if(this.autoHide)
617 {
618 clearTimeout(this.tmrBalloonPopup);
619 transHide=this.transHide;
620 this.tmrBalloonPopup=setTimeout(this.Hide, this.autoHideInterval);
621 }
622
623 if(this.autoAway)
624 {
625 balloonDIV.onmouseover=Hide;
626 }
627 else
628 {
629 balloonDIV.onmouseover='';
630 }
631 }
632
633 /**//* Function: Hide
634 Hide a visible balloon.
635 Call this function to immediately initiate the hiding of the instantiated balloon
636 with the predefined transition in <transHideFilter> depending on the setting of <transHide>.
637 */
638 function Hide()
639 {
640 if(balloonDIV.style.visibility=='hidden')
641 {
642 return;
643 }
644
645 if(transHide)
646 {
647 if(balloonDIV.filters(1).status==2 || balloonDIV.filters(1).status==1)
648 {
649 balloonDIV.filters(1).Stop();
650 }
651 balloonDIV.filters(1).Apply();
652 balloonDIV.style.visibility='hidden';
653 balloonDIV.filters(1).Play();
654 }
655 else
656 {
657 balloonDIV.style.visibility='hidden';
658 }
659
660 RestoreSelects();
661 }
662
663 // Private
664
665 function SuppressSelects()
666 {
667 var selObjects=document.getElementsByTagName("SELECT");
668
669 for(var i=0;i<selObjects.length;i++)
670 {
671 if(selObjects[i].balloonMember!='true')
672 {
673 if(selObjects[i].style.visibility=='visible' || selObjects[i].style.visibility=='')
674 {
675 if(ObjectOverlap(balloonDIV, selObjects[i]))
676 {
677 selObjects[i].style.visibility='hidden';
678 // Mark as ballonhidden
679 selObjects[i].baloonHidden=true;
680 }
681 }
682 }
683 }
684 }
685
686 function RestoreSelects()
687 {
688 var selObjects=document.getElementsByTagName("SELECT");
689
690 for(var i=0;i<selObjects.length;i++)
691 {
692 if(selObjects[i].baloonHidden)
693 {
694 selObjects[i].style.visibility='visible';
695 // Mark as ballonhidden
696 selObjects[i].baloonHidden=false;
697 }
698 }
699 }
700
701 function ObjectOverlap(obj1, obj2)
702 {
703 var obj1TopX = getLeft(obj1);
704 var obj1TopY = getTop(obj1);
705 var obj1BottomX = getLeft(obj1)+obj1.offsetWidth;
706 var obj1BottomY = getTop(obj1)+obj1.offsetHeight;
707
708 var obj2TopX = getLeft(obj2);
709 var obj2TopY = getTop(obj2);
710 var obj2BottomX = getLeft(obj2)+obj2.offsetWidth;
711 var obj2BottomY = getTop(obj2)+obj2.offsetHeight;
712
713 var overlapOnX = (obj1TopX < obj2BottomX && obj2TopX < obj1BottomX);
714 var overlapOnY = (obj1TopY < obj2BottomY && obj2TopY < obj1BottomY);
715
716 return (overlapOnX && overlapOnY);
717 }
718
719 //Positioning functions
720 function getObjLeft(anObject)
721 {
722 return(anObject.offsetParent ? (getObjLeft(anObject.offsetParent) + anObject.offsetLeft) : anObject.offsetLeft);
723 }
724
725 function getObjTop(anObject)
726 {
727 return(anObject.offsetParent ? (getObjTop(anObject.offsetParent) + anObject.offsetTop) : anObject.offsetTop);
728 }
729
730
731 function getLeft(anObject)
732 {
733 return(getObjLeft(anObject));
734 }
735
736 function getTop(anObject)
737 {
738 return(getObjTop(anObject));
739 }
740
741 function ScrollOffsets(anchor)
742 {
743 var aryScrolls = new Array(0,0);
744
745 try
746 {
747 var parentElem=anchor.parentElement;
748
749 while(parentElem!=null)
750 {
751 if(parentElem.scrollTop!=null)
752 {
753 aryScrolls[0]+=parseInt(parentElem.scrollTop, 10);
754 aryScrolls[1]+=parseInt(parentElem.scrollLeft, 10);
755 }
756
757 parentElem=parentElem.parentElement;
758 }
759 }
760 catch(ex)
761 {
762 // continue
763 }
764 return aryScrolls;
765 }
766
767 // Rendering functions
768 function balloonInfrastructure(body, direction)
769 {
770 var ret;
771
772 switch(direction)
773 {
774 case 'SE':
775 // South East
776 ret ='<table class="JSBalloon" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" >'+
777 ' <tr>'+
778 ' <td height="1" width="10">'+
779 ' <img border="0" src="'+JSBalloonPath+'images/cLeftTop.gif" width="10" height="10"></td>'+
780 ' <td height="7" width=100% style="border-top:1px solid #999999; border-left-width:1; border-right-width:1; border-bottom-width:1; background-color:#FFFFEA" colspan="4"></td>'+
781 ' <td height="7" width="10">'+
782 ' <img border="0" src="'+JSBalloonPath+'images/cRightTop.gif" width="10" height="10"></td>'+
783 ' </tr>'+
784 ' <tr>'+
785 ' <td valign=top colspan="6" style="border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #FFFFEA">'+
786 body +
787 ' </td>'+
788 ' </tr>'+
789 ' <tr>'+
790 ' <td width="10" height="7">'+
791 ' <img border="0" src="'+JSBalloonPath+'images/cLeftBottom.gif" width="10" height="10"></td>'+
792 ' <td height="7" style="background-color: #FFFFEA" colspan="4" width="280"></td>'+
793 ' <td width="10" height="7">'+
794 ' <img border="0" src="'+JSBalloonPath+'images/cRightBottom.gif" width="10" height="10"></td>'+
795 ' </tr>'+
796 ' <tr>'+
797 ' <td width="10" height="10"></td>'+
798 ' <td width="1" style="border-top: 1px solid #999999; padding-left: 4; padding-right: 4; padding-top: 1; padding-bottom: 1" height="10"></td>'+
799 ' <td height="10">'+
800 ' <img border="0" src="'+JSBalloonPath+'images/aSouthEast.gif" width="67" height="18"></td>'+
801 ' <td width=100% height="10" style="border-top: 1px solid #999999; padding-left: 4; padding-right: 4; padding-top: 1; padding-bottom: 1"></td>'+
802 ' <td width="70" height="10" style="border-top: 1px solid #999999; padding-left: 4; padding-right: 4; padding-top: 1; padding-bottom: 1"></td>'+
803 ' <td width="10" height="10"></td>'+
804 ' </tr>'+
805 '</table>'
806 break;
807
808 case 'SW':
809 // South West
810 ret ='<table class="JSBalloon" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1" >'+
811 ' <tr>'+
812 ' <td height="1" width="10">'+
813 ' <img border="0" src="'+JSBalloonPath+'images/cLeftTop.gif" width="10" height="10"></td>'+
814 ' <td height="7" width=179 style="border-top:1px solid #999999; border-left-width:1; border-right-width:1; border-bottom-width:1; background-color:#FFFFEA" colspan="4"></td>'+
815 ' <td height="7" width="11">'+
816 ' <img border="0" src="'+JSBalloonPath+'images/cRightTop.gif" width="10" height="10"></td>'+
817 ' </tr>'+
818 ' <tr>'+
819 ' <td valign=top colspan="6" style="border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #FFFFEA"">'+
820 body +
821 ' </td>'+
822 ' </tr>'+
823 ' <tr>'+
824 ' <td width="10" height="7">'+
825 ' <img border="0" src="'+JSBalloonPath+'images/cLeftBottom.gif" width="10" height="10"></td>'+
826 ' <td height="7" style="background-color: #FFFFEA" colspan="4" width="179"></td>'+
827 ' <td width="11" height="7">'+
828 ' <img border="0" src="'+JSBalloonPath+'images/cRightBottom.gif" width="10" height="10"></td>'+
829 ' </tr>'+
830 ' <tr>'+
831 ' <td width="10" height="10"></td>'+
832 ' <td width="70" style="border-top: 1px solid #999999; border-left-width:1; border-right-width:1; border-bottom-width:1" height="10"></td>'+
833 ' <td height="10" style="border-left-width: 1; border-right-width: 1; border-top: 1px solid #999999; border-bottom-width: 1" width="100%">'+
834 ' </td>'+
835 ' <td align="right">'+
836 ' <img border="0" src="'+JSBalloonPath+'images/aSouthWest.gif" width="67" height="18"></td>'+
837 ' <td width="1" height="10" style="border-top: 1px solid #999999;"></td>'+
838 ' <td width="10" height="10"></td>'+
839 ' </tr>'+
840 '</table>'
841 break;
842
843 case 'NE':
844 // North East
845 ret ='<table class="JSBalloon" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1" >'+
846 ' <tr>'+
847 ' <td width="10" height="9"></td>'+
848 ' <td width="1" style="border-bottom:1px solid #999999; " height="9"></td>'+
849 ' <td height="9" valign="bottom">'+
850 ' <img border="0" src="'+JSBalloonPath+'images/aNorthEast.gif" width="67" height="18"></td>'+
851 ' <td width=100% height="9" style="border-bottom:1px solid #999999; "></td>'+
852 ' <td width="70" height="9" style="border-bottom:1px solid #999999;"></td>'+
853 ' <td width="10" height="9"></td>'+
854 ' </tr>'+
855 ' <tr>'+
856 ' <td height="1" width="10">'+
857 ' <img border="0" src="'+JSBalloonPath+'images/cLeftTop.gif" width="10" height="10"></td>'+
858 ' <td height="7" width=100% colspan="4" bgcolor="#FFFFEA"></td>'+
859 ' <td height="7" width="10">'+
860 ' <img border="0" src="'+JSBalloonPath+'images/cRightTop.gif" width="10" height="10"></td>'+
861 ' </tr>'+
862 ' <tr>'+
863 ' <td valign=top colspan="6" style="border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #FFFFEA">'+
864 body +
865 ' </td>'+
866 ' </tr>'+
867 ' <tr>'+
868 ' <td width="10" height="7">'+
869 ' <img border="0" src="'+JSBalloonPath+'images/cLeftBottom.gif" width="10" height="10"></td>'+
870 ' <td height="7" style="border-bottom:1px solid #999999; border-left-width:1; border-right-width:1; border-top-width:1" colspan="4" width="280" bgcolor="#FFFFEA"></td>'+
871 ' <td width="10" height="7">'+
872 ' <img border="0" src="'+JSBalloonPath+'images/cRightBottom.gif" width="10" height="10"></td>'+
873 ' </tr>'+
874 '</table>'
875 break;
876
877 case 'NW':
878 // North West
879 ret ='<table class="JSBalloon" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1" >'+
880 ' <tr>'+
881 ' <td width="10" height="10"></td>'+
882 ' <td width="70" style="border-bottom:1px solid #999999; border-left-width:1; border-right-width:1; " height="10"></td>'+
883 ' <td height="10" style="border-bottom:1px solid #999999; border-left-width: 1; border-right-width: 1; " width="100%">'+
884 ' </td>'+
885 ' <td align="right" valign="bottom">'+
886 ' <img border="0" src="'+JSBalloonPath+'images/aNorthWest.gif" width="67" height="18"></td>'+
887 ' <td width="1" height="10" style="border-bottom:1px solid #999999;"></td>'+
888 ' <td width="10" height="10"></td>'+
889 ' </tr>'+
890 ' <tr>'+
891 ' <td height="1" width="10">'+
892 ' <img border="0" src="'+JSBalloonPath+'images/cLeftTop.gif" width="10" height="10"></td>'+
893 ' <td height="7" width=179 colspan="4" bgcolor="#FFFFEA"></td>'+
894 ' <td height="7" width="11">'+
895 ' <img border="0" src="'+JSBalloonPath+'images/cRightTop.gif" width="10" height="10"></td>'+
896 ' </tr>'+
897 ' <tr>'+
898 ' <td valign=top colspan="6" style="border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #FFFFEA">'+
899 body +
900 ' </td>'+
901 ' </tr>'+
902 ' <tr>'+
903 ' <td width="10" height="7">'+
904 ' <img border="0" src="'+JSBalloonPath+'images/cLeftBottom.gif" width="10" height="10"></td>'+
905 ' <td height="7" style="border-bottom:1px solid #999999; border-left-width:1; border-right-width:1; border-top-width:1" colspan="4" width="179" bgcolor="#FFFFEA"></td>'+
906 ' <td width="11" height="7">'+
907 ' <img border="0" src="'+JSBalloonPath+'images/cRightBottom.gif" width="10" height="10"></td>'+
908 ' </tr>'+
909 '</table>'
910 break;
911 }
912
913
914 return ret;
915 }
916
917 function balloonBody(title, icon, body, footer, titleFontStyle,
918 messageFontStyle, footerFontStyle,
919 showCloseBox)
920 {
921 var imgShow='none';
922 var iconTitle='';
923 var ballonBody=body;
924 var imgClose='none';
925 var headerVisible='block';
926 var offsetParent="-7";
927
928 if(title!=undefined)
929 {
930 iconTitle=title;
931 }
932
933 if(showCloseBox)
934 {
935 imgClose='block';
936 }
937 else
938 {
939 imgClose='none';
940 }
941
942 if(icon != '')
943 {
944 imgShow='block';
945 }
946 else
947 {
948 imgShow='none';
949 }
950
951 if(imgShow=='none' && imgClose=='none' && iconTitle=='')
952 {
953 headerVisible='none';
954 offsetParent="0";
955 }
956 else
957 {
958 headerVisible='block';
959 offsetParent="-7";
960 }
961
962 return ' <table border="0" cellpadding="3" cellspacing="0" style="cursor:default;border-collapse: collapse; position:relative; top: '+offsetParent+';left:3" width="100%">' +
963 ' <tr style="display:'+headerVisible+'">' +
964 ' <td id="BIcon" width="3%" align=left><img id=BIcon src="'+icon+'" style="display:'+imgShow+'"></td>' +
965 ' <td id="BTitle" UNSELECTABLE="on" width="90%" style="'+titleFontStyle+'" align=left>'+iconTitle+'</td>' +
966 ' <td id="BClose" width="3%" valign=top align=right><img src="'+JSBalloonPath+'images/close.jpg" style="position:relative; top: 4;left:-5;display:'+imgClose+'" onmouseover="this.src=\''+JSBalloonPath+'images/closeActive.jpg\'" onmouseout="this.src=\''+JSBalloonPath+'images/close.jpg\'" onmouseup="this.src=\''+JSBalloonPath+'images/closeActive.jpg\'" onmousedown="this.src=\''+JSBalloonPath+'images/closeDown.jpg\'" title="Close"> </td>' +
967 ' </tr>' +
968 ' <tr>' +
969 ' <td id="BBody" UNSELECTABLE="on" style="'+messageFontStyle+'" width="100%" colspan="3">' + ballonBody +'</td>' +
970 ' </tr>' +
971 ' <tr>' +
972 ' <td id="BFooter" UNSELECTABLE="on" style="'+footerFontStyle+'" width="100%" colspan="3">' + footer +'</td>' +
973 ' </tr>' +
974 ' </table>'
975 }
976}
977
978/**//*
979 Section: Usage
980 Examples of the object instantiation.
981
982 Examples:
983
984 (start code)
985 var bl=new JSBalloon({ width:300});
986 var b2=new JSBalloon();
987 var b3=new JSBalloon({ width:150,
988 autoAway:false,
989 autoHide:false,
990 showCloseBox:true});
991
992 (end)
993
994 Section: Include Setup Notes
995 Please read before installing.
996
997 Set the global variable JSBalloonPath to the full application path (or URL) where
998 it is located.
999
1000 Make sure you included the trailing forward slash.
1001
1002 Examples:
1003 - var JSBalloonPath="/appname/includes/js/JSBalloon/";
1004 - var JSBalloonPath="http://prodserver/appname/includes/js/JSBalloon/";
1005*/
1006
1/**//*----------------------------------------------------------------------------\
2| JSBalloon |
3|-----------------------------------------------------------------------------|
4| Created by Arkady (Alex) Lesniara |
5| (arkady@lesniara.com) |
6|-----------------------------------------------------------------------------|
7| Copyright (c) 2005 Arkady Lesniara |
8|-----------------------------------------------------------------------------|
9| This software is provided "as is", without warranty of any kind, express or |
10| implied, including but not limited to the warranties of merchantability, |
11| fitness for a particular purpose and noninfringement. In no event shall the |
12| authors or copyright holders be liable for any claim, damages or other |
13| liability, whether in an action of contract, tort or otherwise, arising |
14| from, out of or in connection with the software or the use or other |
15| dealings in the software. |
16\----------------------------------------------------------------------------*/
17
18var JSBalloonPath="";
19
20/**//* Class: JSBalloon
21 Provides a flexible, encapsulated way to implement a passive feedback mechanism
22 in a DHTML environment. Define and initialize this object globally, otherwise it will create a new instance
23 each time you call it's constructor. Set up the object with an object array passed to the constructor or, once instantiated,
24 with properties. See <Usage> for more.
25*/
26function JSBalloon()
27{
28 var tmrBalloonPopup;
29
30 var blbWidth=200;;
31 var titleFontStyle='font-family: MS Sans Serif;font-weight: bold; font-size:10pt;';
32 var messageFontStyle='font-family: MS Sans Serif\; font-size:10pt\;';
33 var footerFontStyle='font-family: MS Sans Serif\; font-size:10pt\;';
34 var transShow=true;
35 var transHide=true;
36 var transShowFilter='progid:DXImageTransform.Microsoft.Fade(Overlap=1.00)';
37 var transHideFilter='progid:DXImageTransform.Microsoft.Fade(Overlap=1.00)';
38 var autoHide=true;
39 var autoHideInterval=4000; // 4 sec
40 var autoAway=true;
41 var showCloseBox=false;
42
43 if(JSBalloon.arguments.length>0)
44 {
45 var oArg=JSBalloon.arguments[0];
46
47 if(oArg.width!=null)
48 {
49 blbWidth=oArg.width;
50 }
51
52 if(oArg.titleFontStyle!=null)
53 {
54 titleFontStyle=oArg.titleFontStyle;
55 }
56
57 if(oArg.messageFontStyle!=null)
58 {
59 messageFontStyle=oArg.messageFontStyle;
60 }
61
62 if(oArg.footerFontStyle!=null)
63 {
64 footerFontStyle=oArg.footerFontStyle;
65 }
66
67 if(oArg.transShow!=null)
68 {
69 transShow=oArg.transShow;
70 }
71
72 if(oArg.transHide!=null)
73 {
74 transHide=oArg.transHide;
75 }
76
77 if(oArg.transShowFilter!=null)
78 {
79 transShowFilter=oArg.transShowFilter;
80 }
81
82 if(oArg.transHideFilter!=null)
83 {
84 transHideFilter=oArg.transHideFilter;
85 }
86
87 if(oArg.autoHide!=null)
88 {
89 autoHide=oArg.autoHide;
90 }
91
92 if(oArg.autoHideInterval!=null)
93 {
94 autoHideInterval=oArg.autoHideInterval;
95 }
96
97 if(oArg.autoAway!=null)
98 {
99 autoAway=oArg.autoAway;
100 }
101
102 if(oArg.showCloseBox!=null)
103 {
104 showCloseBox=oArg.showCloseBox;
105 }
106 }
107
108 // Public properties
109
110 /**//* Property: titleFontStyle
111 Sets or retrieves a Cascading Style Sheet formatted value that formats the balloon's title (heading).
112
113 Syntax:
114 object.titleFontStyle [= sCSS ]
115
116 Possible Values:
117 sCSS - *variant* that specifies a properly formed Cascading Style Sheet formatting.
118
119 Examples:
120 balloonObj.titleFontStyle="font-family: MS Sans Serif;font-weight: bold; font-size:12pt;";
121 */
122 this.titleFontStyle=titleFontStyle;
123
124 /**//* Property: messageFontStyle
125 Sets or retrieves a Cascading Style Sheet formatted value that formats the balloon's main message body.
126
127 Syntax:
128 object.messageFontStyle [= sCSS ]
129
130 Possible Values:
131 sCSS - *variant* that specifies a properly formed Cascading Style Sheet formatting.
132
133 Examples:
134 balloonObj.messageFontStyle="font-family: MS Sans Serif;font-weight: bold; font-size:12pt;";
135 */
136 this.messageFontStyle=messageFontStyle;
137
138 /**//* Property: footerFontStyle
139 Sets or retrieves a Cascading Style Sheet formatted value that formats the balloon's footer.
140
141 Syntax:
142 object.footerFontStyle [= sCSS ]
143
144 Possible Values:
145 sCSS - *variant* that specifies a properly formed Cascading Style Sheet formatting.
146
147 Examples:
148 balloonObj.footerFontStyle="font-family: MS Sans Serif;font-weight: bold; font-size:12pt;";
149 */
150 this.footerFontStyle=footerFontStyle;
151
152 /**//* Property: transShowFilter
153 Sets or retrieves a value of a transition (a filter) applied when showing the balloon.
154
155 Syntax:
156 object.transShowFilter [= string ]
157
158 Possible Values:
159 string - *variant* that specifies the transition filter. More information found at http://msdn.microsoft.com/workshop/author/filter/reference/reference.asp
160
161 Examples:
162 balloonObj.transShowFilter="progid:DXImageTransform.Microsoft.Stretch(stretchstyle=SPIN)";
163
164 See also:
165 <transShow>
166 */
167 this.transShowFilter=transShowFilter;
168
169 /**//* Property: transHideFilter
170 Sets or retrieves a value of a transition (a filter) applied when hiding the balloon.
171
172 Syntax:
173 object.transHideFilter [= string ]
174
175 Possible Values:
176 string - *variant* that specifies the transition filter. More information found at http://msdn.microsoft.com/workshop/author/filter/reference/reference.asp
177
178 Examples:
179 balloonObj.transHideFilter="progid:DXImageTransform.Microsoft.Slide(slidestyle=HIDE,Bands=1)";
180
181 See also:
182 <transHide>
183 */
184 this.transHideFilter=transHideFilter;
185
186 /**//* Property: transShow
187 Sets or retrieves a value indicating whether to apply transition filter specified in
188 <transShowFilter> when showing the balloon.
189
190 Syntax:
191 object.transShow [= bValue ]
192
193 Possible Values:
194 bValue - *boolean* true / false
195
196 Examples:
197 balloonObj.transShow=true;
198
199 See also:
200 <transShowFilter>
201 */
202 this.transShow=transShow;
203
204 /**//* Property: transHide
205 Sets or retrieves a value indicating whether to apply transition filter specified in
206 <transHideFilter> when hiding the balloon.
207
208 Syntax:
209 object.transHide [= bValue ]
210
211 Possible Values:
212 bValue - *boolean* true / false
213
214 Examples:
215 balloonObj.transHide=true;
216
217 See also:
218 <transHideFilter>
219 */
220 this.transHide=transHide;
221
222 /**//* Property: autoHide
223 Sets or retrieves a value indicating whether to automatically hide the balloon
224 after s time specified in <autoHideInterval>.
225
226 Syntax:
227 object.autoHide [= bValue ]
228
229 Possible Values:
230 bValue - *boolean* true / false
231
232 Examples:
233 balloonObj.autoHide=true;
234
235 See also:
236 <autoHideInterval>
237 */
238 this.autoHide=autoHide;
239
240 /**//* Property: autoHideInterval
241 Sets or retrieves a value indicating how long to wait before executing <autoHide>.
242
243 Syntax:
244 object.autoHideInterval [= iValue ]
245
246 Possible Values:
247 iValue - *integer* number of milliseconds to wait before activating <autoHide>.
248
249 Examples:
250 balloonObj.autoHideInterval=5000; // 5 Sec
251
252 See also:
253 <autoHide>
254 */
255 this.autoHideInterval=autoHideInterval;
256
257 /**//* Property: autoAway
258 Sets or retrieves a value of this property.
259 When set to true the balloon will immediately run the <Hide> method on mouse over.
260
261 This is particularly useful when the balloon is used only for passive feedback and
262 doesn't have to be dismissed. The user may want to perform some task quickly without having
263 to wait the time specified in the <autoHideInterval> while the balloon is obstructing a page
264 element.
265
266 Syntax:
267 object.autoAway [= bValue ]
268
269 Possible Values:
270 bValue - *boolean* true / false
271
272 Examples:
273 balloonObj.autoAway=true;
274 */
275 this.autoAway=autoAway;
276
277 /**//* Property: width
278 Sets or retrieves a value of balloon's width. The height is dynamic, the width has to be specified.
279
280 Syntax:
281 object.width [= iValue ]
282
283 Possible Values:
284 iValue - *integer* the number of pixels.
285
286 Examples:
287 balloonObj.width=325;
288 */
289 this.width=blbWidth;
290
291 /**//* Property: showCloseBox
292 Sets or retrieves a value of whether the close balloon (right-upper corner) should be displayed.
293 It makes sense to turn <autoHide> off when enabling this feature.
294
295 Syntax:
296 object.showCloseBox [= bValue ]
297
298 Possible Values:
299 bValue - *boolean* true / false
300
301 Examples:
302 balloonObj.showCloseBox=false;
303 */
304 this.showCloseBox=showCloseBox;
305
306 var childID;
307
308 // Constructor
309 var balloonDIV = document.createElement("DIV");
310 balloonDIV.style.width=String(blbWidth);
311 balloonDIV.style.position="absolute";
312 balloonDIV.style.visibility="hidden";
313 balloonDIV.style.filter=transShowFilter+' '+transHideFilter;
314 balloonDIV.style.zIndex=2001;
315
316 /**//* Property: balloon
317 Retrieves the reference to the instantiated balloon object.
318
319 Syntax:
320 [obj =] object.balloon
321
322 Possible Values:
323 obj - *object* balloon reference
324
325 Examples:
326 var obj = balloonObj.balloon;
327 */
328 this.balloon=balloonDIV;
329
330 // Pulic Methods
331 this.Show=Show;
332 this.Hide=Hide;
333
334 /**//* Function: Show
335 Makes the instantiated balloon appear.
336
337 Balloon content note:
338 Because SELECT objects are what's known as windowed controles
339 they need to be hidden when balloons are shown, otherwise they will always be on top
340 (they ignore zIndex attribute). It is normally done automatically by this control.
341 Sometimes, however, you may want to place a drop-down inside the balloon itself.
342 To override this default behaviour add an balloonMember expando attirbute to
343 the SELECT you are placing withing.
344
345 - e.g. <SELECT id=select1 name=select1 balloonMember=true>
346
347 Syntax:
348 (start code)
349 object.Show({[title:vTitle]
350 [,message:vMessage]
351 [,footer:vFooter]
352 [,top:vTop]
353 [,left:vLeft]
354 [,anchor:vAnchor]
355 [,icon:vIcon]
356 });
357 (end)
358
359 Possible Values:
360 vTitle - *string* Optional title text for the balloon.
361 vMessage - *string* Optional. Message body for the balloon.
362 vFooter - *string* Optional. Test displayed at the bottom of the balloon on a separate line.
363 vTop - *integer* Optional. Offset from the top of the screen or top of an anchor.
364 vLeft - *integer* Optional. Offset from the left of the screen or left of an anchor.
365 vAnchor - *object* Optional. Reference to the object that the balloon should use as reference for location.
366 vIcon - *string* Optional. Possible icon values may include one of the values below (case sensitive):
367 - Exclaim - pre-defined, triangle with an exclamation point.
368 - Stop - pre-defined, red circle with a white x inside.
369 - Info - pre-defined, white balloon with a letter "i" inside *Default*
370 - Help - a question mark inside a blue circle.
371 - a relative path to a custom icon.
372
373 Examples:
374
375 - balloonObj.Show({title:'JavaScript Balloon Example',message:'This is an example of a JSBalloon object. It\'s primary application is to provide a modeless feedback to DHTML applications.',anchor:tableCellObj, icon:'Info'});
376 - balloonObj1.Show({title:'JavaScript Balloon Example',message:'This is an example of a JSBalloon object. It\'s primary application is to provide a modeless feedback to DHTML applications.',anchor:tableCellObj});
377 - balloonObj2.Show({message:'This is an example of a JSBalloon object. It\'s primary application is to provide a modeless feedback to DHTML applications. ',anchor:tableCellObj});
378
379 */
380 function Show()
381 {
382 var title;
383 var message='';
384 var icon='';
385 var footer='';
386 var btop=0, bleft=0;
387 var atop=0, aleft=0;
388 var anchor;
389 var direction='SE';
390
391 // Updates
392 blbWidth=String(this.width);
393 titleFontStyle=this.titleFontStyle;
394 messageFontStyle=this.messageFontStyle;
395 footerFontStyle=this.footerFontStyle;
396 transShowFilter=this.transShowFilter;
397 transHideFilter=this.transHideFilter;
398 transShow=this.transShow;
399 transHide=this.transHide;
400 autoHide=this.autoHide;
401 autoHideInterval=this.autoHideInterval;
402 autoAway=this.autoAway;
403
404 if(document.readyState!='complete')
405 {
406 alert('Document needs to fully load before you may show JSBalloons.');
407 return;
408 }
409
410 if(Show.arguments.length>0)
411 {
412 var oArg=Show.arguments[0];
413
414 if(oArg.title!=null)
415 {
416 title=oArg.title;
417 }
418
419 if(oArg.message!=null)
420 {
421 message=oArg.message;
422 }
423
424 if(oArg.icon!=null)
425 {
426 icon=oArg.icon;
427
428 switch(icon)
429 {
430 case 'Exclaim':
431 icon = JSBalloonPath+'images/exclaim.ico';
432 SoundFx = 'Exclaim';
433 break;
434
435 case 'Stop':
436 icon = JSBalloonPath+'images/stop.ico';
437 SoundFx = 'Stop';
438 break;
439
440 case 'Info':
441 icon = JSBalloonPath+'images/info.ico';
442 SoundFx = 'Info';
443 break;
444
445 case 'Help':
446 icon = JSBalloonPath+'images/help.ico';
447 SoundFx = 'Info';
448 break;
449
450 default:
451 SoundFx = 'Info';
452 }
453 }
454
455 if(oArg.footer!=null)
456 {
457 footer=oArg.footer;
458 }
459
460 if(oArg.top!=null)
461 {
462 btop=oArg.top;
463 }
464
465 if(oArg.left!=null)
466 {
467 bleft=oArg.left;
468 }
469
470 if(oArg.anchor!=null)
471 {
472 anchor=oArg.anchor;
473 atop=getTop(anchor);
474 aleft=getLeft(anchor);
475 }
476 }
477
478 // Figure out the best direction for the pointer
479
480 // Assume SE
481 var ret=balloonInfrastructure(balloonBody( title,
482 icon,
483 message,
484 footer,
485 this.titleFontStyle,
486 this.messageFontStyle,
487 this.footerFontStyle,
488 this.showCloseBox), direction);
489
490 // Populate the contents
491 balloonDIV.innerHTML=ret;
492
493 var btnClose=balloonDIV.children[0].children[0].children[1].children[0].children[0].children[0].children[0].children[2].children[0];
494 btnClose.onclick=this.Hide;
495
496 // check if the object is already initialized
497 if(typeof(childID)!='object')
498 {
499 childID=document.body.appendChild(balloonDIV);
500 }
501
502 if(anchor!=null)
503 {
504
505 balloonDIV.style.left = aleft+bleft;
506 balloonDIV.style.top = (atop-balloonDIV.offsetHeight)+btop;
507 }
508 else
509 {
510 balloonDIV.style.left = bleft;
511 balloonDIV.style.top = btop;
512 }
513
514
515 var bAdjustedLeft=parseInt(balloonDIV.style.left, 10);
516 var showSE;
517
518
519 if(document.body.offsetWidth < (bAdjustedLeft+balloonDIV.offsetWidth+20))
520 {
521 direction='SW';
522
523 ret=balloonInfrastructure(balloonBody( title,
524 icon,
525 message,
526 footer,
527 this.titleFontStyle,
528 this.messageFontStyle,
529 this.footerFontStyle,
530 this.showCloseBox), direction);
531 balloonDIV.innerHTML=ret;
532
533 balloonDIV.style.left = bAdjustedLeft-balloonDIV.offsetWidth+20;
534 showSE=false;
535 }
536 else
537 {
538 direction='SE';
539 showSE=true;
540 }
541
542 if(parseInt(balloonDIV.style.top, 10)<0)
543 {
544 if(showSE)
545 {
546 direction='NE';
547 ret=balloonInfrastructure(balloonBody( title,
548 icon,
549 message,
550 footer,
551 this.titleFontStyle,
552 this.messageFontStyle,
553 this.footerFontStyle,
554 this.showCloseBox), direction);
555 balloonDIV.innerHTML=ret;
556 }
557 else
558 {
559 direction='NW';
560 ret=balloonInfrastructure(balloonBody( title,
561 icon,
562 message,
563 footer,
564 this.titleFontStyle,
565 this.messageFontStyle,
566 this.footerFontStyle,
567 this.showCloseBox), direction);
568 balloonDIV.innerHTML=ret;
569 }
570 balloonDIV.style.top = parseInt(balloonDIV.style.top, 10)+balloonDIV.offsetHeight;
571 if(anchor!=null)
572 {
573 balloonDIV.style.top = parseInt(balloonDIV.style.top, 10)+anchor.offsetHeight
574 }
575 }
576
577 if(this.showCloseBox)
578 {
579 if(direction=='SE' || direction=='SW')
580 {
581 btnClose=balloonDIV.children[0].children[0].children[1].children[0].children[0].children[0].children[0].children[2].children[0];
582 }
583 else
584 {
585 btnClose=balloonDIV.children[0].children[0].children[2].children[0].children[0].children[0].children[0].children[2].children[0];
586 }
587 btnClose.onclick=this.Hide;
588 }
589
590 // Adjust all srollers
591 var scrollOffsets=ScrollOffsets(anchor);
592 balloonDIV.style.top=parseInt(balloonDIV.style.top, 10)-scrollOffsets[0];
593 balloonDIV.style.left=parseInt(balloonDIV.style.left, 10)-scrollOffsets[1];
594
595 // Hide any overlapping selects
596 SuppressSelects();
597
598 // Show balloon
599 if(this.transShow)
600 {
601 balloonDIV.style.filter=this.transShowFilter+' '+this.transHideFilter;
602 if(balloonDIV.filters(0).status==2 || balloonDIV.filters(0).status==1)
603 {
604 balloonDIV.filters(0).Stop();
605 }
606 balloonDIV.filters(0).Apply();
607 balloonDIV.style.visibility='visible';
608 balloonDIV.filters(0).Play();
609 }
610 else
611 {
612 balloonDIV.style.visibility='visible';
613 }
614
615 // Init autohide if true
616 if(this.autoHide)
617 {
618 clearTimeout(this.tmrBalloonPopup);
619 transHide=this.transHide;
620 this.tmrBalloonPopup=setTimeout(this.Hide, this.autoHideInterval);
621 }
622
623 if(this.autoAway)
624 {
625 balloonDIV.onmouseover=Hide;
626 }
627 else
628 {
629 balloonDIV.onmouseover='';
630 }
631 }
632
633 /**//* Function: Hide
634 Hide a visible balloon.
635 Call this function to immediately initiate the hiding of the instantiated balloon
636 with the predefined transition in <transHideFilter> depending on the setting of <transHide>.
637 */
638 function Hide()
639 {
640 if(balloonDIV.style.visibility=='hidden')
641 {
642 return;
643 }
644
645 if(transHide)
646 {
647 if(balloonDIV.filters(1).status==2 || balloonDIV.filters(1).status==1)
648 {
649 balloonDIV.filters(1).Stop();
650 }
651 balloonDIV.filters(1).Apply();
652 balloonDIV.style.visibility='hidden';
653 balloonDIV.filters(1).Play();
654 }
655 else
656 {
657 balloonDIV.style.visibility='hidden';
658 }
659
660 RestoreSelects();
661 }
662
663 // Private
664
665 function SuppressSelects()
666 {
667 var selObjects=document.getElementsByTagName("SELECT");
668
669 for(var i=0;i<selObjects.length;i++)
670 {
671 if(selObjects[i].balloonMember!='true')
672 {
673 if(selObjects[i].style.visibility=='visible' || selObjects[i].style.visibility=='')
674 {
675 if(ObjectOverlap(balloonDIV, selObjects[i]))
676 {
677 selObjects[i].style.visibility='hidden';
678 // Mark as ballonhidden
679 selObjects[i].baloonHidden=true;
680 }
681 }
682 }
683 }
684 }
685
686 function RestoreSelects()
687 {
688 var selObjects=document.getElementsByTagName("SELECT");
689
690 for(var i=0;i<selObjects.length;i++)
691 {
692 if(selObjects[i].baloonHidden)
693 {
694 selObjects[i].style.visibility='visible';
695 // Mark as ballonhidden
696 selObjects[i].baloonHidden=false;
697 }
698 }
699 }
700
701 function ObjectOverlap(obj1, obj2)
702 {
703 var obj1TopX = getLeft(obj1);
704 var obj1TopY = getTop(obj1);
705 var obj1BottomX = getLeft(obj1)+obj1.offsetWidth;
706 var obj1BottomY = getTop(obj1)+obj1.offsetHeight;
707
708 var obj2TopX = getLeft(obj2);
709 var obj2TopY = getTop(obj2);
710 var obj2BottomX = getLeft(obj2)+obj2.offsetWidth;
711 var obj2BottomY = getTop(obj2)+obj2.offsetHeight;
712
713 var overlapOnX = (obj1TopX < obj2BottomX && obj2TopX < obj1BottomX);
714 var overlapOnY = (obj1TopY < obj2BottomY && obj2TopY < obj1BottomY);
715
716 return (overlapOnX && overlapOnY);
717 }
718
719 //Positioning functions
720 function getObjLeft(anObject)
721 {
722 return(anObject.offsetParent ? (getObjLeft(anObject.offsetParent) + anObject.offsetLeft) : anObject.offsetLeft);
723 }
724
725 function getObjTop(anObject)
726 {
727 return(anObject.offsetParent ? (getObjTop(anObject.offsetParent) + anObject.offsetTop) : anObject.offsetTop);
728 }
729
730
731 function getLeft(anObject)
732 {
733 return(getObjLeft(anObject));
734 }
735
736 function getTop(anObject)
737 {
738 return(getObjTop(anObject));
739 }
740
741 function ScrollOffsets(anchor)
742 {
743 var aryScrolls = new Array(0,0);
744
745 try
746 {
747 var parentElem=anchor.parentElement;
748
749 while(parentElem!=null)
750 {
751 if(parentElem.scrollTop!=null)
752 {
753 aryScrolls[0]+=parseInt(parentElem.scrollTop, 10);
754 aryScrolls[1]+=parseInt(parentElem.scrollLeft, 10);
755 }
756
757 parentElem=parentElem.parentElement;
758 }
759 }
760 catch(ex)
761 {
762 // continue
763 }
764 return aryScrolls;
765 }
766
767 // Rendering functions
768 function balloonInfrastructure(body, direction)
769 {
770 var ret;
771
772 switch(direction)
773 {
774 case 'SE':
775 // South East
776 ret ='<table class="JSBalloon" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" >'+
777 ' <tr>'+
778 ' <td height="1" width="10">'+
779 ' <img border="0" src="'+JSBalloonPath+'images/cLeftTop.gif" width="10" height="10"></td>'+
780 ' <td height="7" width=100% style="border-top:1px solid #999999; border-left-width:1; border-right-width:1; border-bottom-width:1; background-color:#FFFFEA" colspan="4"></td>'+
781 ' <td height="7" width="10">'+
782 ' <img border="0" src="'+JSBalloonPath+'images/cRightTop.gif" width="10" height="10"></td>'+
783 ' </tr>'+
784 ' <tr>'+
785 ' <td valign=top colspan="6" style="border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #FFFFEA">'+
786 body +
787 ' </td>'+
788 ' </tr>'+
789 ' <tr>'+
790 ' <td width="10" height="7">'+
791 ' <img border="0" src="'+JSBalloonPath+'images/cLeftBottom.gif" width="10" height="10"></td>'+
792 ' <td height="7" style="background-color: #FFFFEA" colspan="4" width="280"></td>'+
793 ' <td width="10" height="7">'+
794 ' <img border="0" src="'+JSBalloonPath+'images/cRightBottom.gif" width="10" height="10"></td>'+
795 ' </tr>'+
796 ' <tr>'+
797 ' <td width="10" height="10"></td>'+
798 ' <td width="1" style="border-top: 1px solid #999999; padding-left: 4; padding-right: 4; padding-top: 1; padding-bottom: 1" height="10"></td>'+
799 ' <td height="10">'+
800 ' <img border="0" src="'+JSBalloonPath+'images/aSouthEast.gif" width="67" height="18"></td>'+
801 ' <td width=100% height="10" style="border-top: 1px solid #999999; padding-left: 4; padding-right: 4; padding-top: 1; padding-bottom: 1"></td>'+
802 ' <td width="70" height="10" style="border-top: 1px solid #999999; padding-left: 4; padding-right: 4; padding-top: 1; padding-bottom: 1"></td>'+
803 ' <td width="10" height="10"></td>'+
804 ' </tr>'+
805 '</table>'
806 break;
807
808 case 'SW':
809 // South West
810 ret ='<table class="JSBalloon" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1" >'+
811 ' <tr>'+
812 ' <td height="1" width="10">'+
813 ' <img border="0" src="'+JSBalloonPath+'images/cLeftTop.gif" width="10" height="10"></td>'+
814 ' <td height="7" width=179 style="border-top:1px solid #999999; border-left-width:1; border-right-width:1; border-bottom-width:1; background-color:#FFFFEA" colspan="4"></td>'+
815 ' <td height="7" width="11">'+
816 ' <img border="0" src="'+JSBalloonPath+'images/cRightTop.gif" width="10" height="10"></td>'+
817 ' </tr>'+
818 ' <tr>'+
819 ' <td valign=top colspan="6" style="border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #FFFFEA"">'+
820 body +
821 ' </td>'+
822 ' </tr>'+
823 ' <tr>'+
824 ' <td width="10" height="7">'+
825 ' <img border="0" src="'+JSBalloonPath+'images/cLeftBottom.gif" width="10" height="10"></td>'+
826 ' <td height="7" style="background-color: #FFFFEA" colspan="4" width="179"></td>'+
827 ' <td width="11" height="7">'+
828 ' <img border="0" src="'+JSBalloonPath+'images/cRightBottom.gif" width="10" height="10"></td>'+
829 ' </tr>'+
830 ' <tr>'+
831 ' <td width="10" height="10"></td>'+
832 ' <td width="70" style="border-top: 1px solid #999999; border-left-width:1; border-right-width:1; border-bottom-width:1" height="10"></td>'+
833 ' <td height="10" style="border-left-width: 1; border-right-width: 1; border-top: 1px solid #999999; border-bottom-width: 1" width="100%">'+
834 ' </td>'+
835 ' <td align="right">'+
836 ' <img border="0" src="'+JSBalloonPath+'images/aSouthWest.gif" width="67" height="18"></td>'+
837 ' <td width="1" height="10" style="border-top: 1px solid #999999;"></td>'+
838 ' <td width="10" height="10"></td>'+
839 ' </tr>'+
840 '</table>'
841 break;
842
843 case 'NE':
844 // North East
845 ret ='<table class="JSBalloon" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1" >'+
846 ' <tr>'+
847 ' <td width="10" height="9"></td>'+
848 ' <td width="1" style="border-bottom:1px solid #999999; " height="9"></td>'+
849 ' <td height="9" valign="bottom">'+
850 ' <img border="0" src="'+JSBalloonPath+'images/aNorthEast.gif" width="67" height="18"></td>'+
851 ' <td width=100% height="9" style="border-bottom:1px solid #999999; "></td>'+
852 ' <td width="70" height="9" style="border-bottom:1px solid #999999;"></td>'+
853 ' <td width="10" height="9"></td>'+
854 ' </tr>'+
855 ' <tr>'+
856 ' <td height="1" width="10">'+
857 ' <img border="0" src="'+JSBalloonPath+'images/cLeftTop.gif" width="10" height="10"></td>'+
858 ' <td height="7" width=100% colspan="4" bgcolor="#FFFFEA"></td>'+
859 ' <td height="7" width="10">'+
860 ' <img border="0" src="'+JSBalloonPath+'images/cRightTop.gif" width="10" height="10"></td>'+
861 ' </tr>'+
862 ' <tr>'+
863 ' <td valign=top colspan="6" style="border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #FFFFEA">'+
864 body +
865 ' </td>'+
866 ' </tr>'+
867 ' <tr>'+
868 ' <td width="10" height="7">'+
869 ' <img border="0" src="'+JSBalloonPath+'images/cLeftBottom.gif" width="10" height="10"></td>'+
870 ' <td height="7" style="border-bottom:1px solid #999999; border-left-width:1; border-right-width:1; border-top-width:1" colspan="4" width="280" bgcolor="#FFFFEA"></td>'+
871 ' <td width="10" height="7">'+
872 ' <img border="0" src="'+JSBalloonPath+'images/cRightBottom.gif" width="10" height="10"></td>'+
873 ' </tr>'+
874 '</table>'
875 break;
876
877 case 'NW':
878 // North West
879 ret ='<table class="JSBalloon" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1" >'+
880 ' <tr>'+
881 ' <td width="10" height="10"></td>'+
882 ' <td width="70" style="border-bottom:1px solid #999999; border-left-width:1; border-right-width:1; " height="10"></td>'+
883 ' <td height="10" style="border-bottom:1px solid #999999; border-left-width: 1; border-right-width: 1; " width="100%">'+
884 ' </td>'+
885 ' <td align="right" valign="bottom">'+
886 ' <img border="0" src="'+JSBalloonPath+'images/aNorthWest.gif" width="67" height="18"></td>'+
887 ' <td width="1" height="10" style="border-bottom:1px solid #999999;"></td>'+
888 ' <td width="10" height="10"></td>'+
889 ' </tr>'+
890 ' <tr>'+
891 ' <td height="1" width="10">'+
892 ' <img border="0" src="'+JSBalloonPath+'images/cLeftTop.gif" width="10" height="10"></td>'+
893 ' <td height="7" width=179 colspan="4" bgcolor="#FFFFEA"></td>'+
894 ' <td height="7" width="11">'+
895 ' <img border="0" src="'+JSBalloonPath+'images/cRightTop.gif" width="10" height="10"></td>'+
896 ' </tr>'+
897 ' <tr>'+
898 ' <td valign=top colspan="6" style="border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #FFFFEA">'+
899 body +
900 ' </td>'+
901 ' </tr>'+
902 ' <tr>'+
903 ' <td width="10" height="7">'+
904 ' <img border="0" src="'+JSBalloonPath+'images/cLeftBottom.gif" width="10" height="10"></td>'+
905 ' <td height="7" style="border-bottom:1px solid #999999; border-left-width:1; border-right-width:1; border-top-width:1" colspan="4" width="179" bgcolor="#FFFFEA"></td>'+
906 ' <td width="11" height="7">'+
907 ' <img border="0" src="'+JSBalloonPath+'images/cRightBottom.gif" width="10" height="10"></td>'+
908 ' </tr>'+
909 '</table>'
910 break;
911 }
912
913
914 return ret;
915 }
916
917 function balloonBody(title, icon, body, footer, titleFontStyle,
918 messageFontStyle, footerFontStyle,
919 showCloseBox)
920 {
921 var imgShow='none';
922 var iconTitle='';
923 var ballonBody=body;
924 var imgClose='none';
925 var headerVisible='block';
926 var offsetParent="-7";
927
928 if(title!=undefined)
929 {
930 iconTitle=title;
931 }
932
933 if(showCloseBox)
934 {
935 imgClose='block';
936 }
937 else
938 {
939 imgClose='none';
940 }
941
942 if(icon != '')
943 {
944 imgShow='block';
945 }
946 else
947 {
948 imgShow='none';
949 }
950
951 if(imgShow=='none' && imgClose=='none' && iconTitle=='')
952 {
953 headerVisible='none';
954 offsetParent="0";
955 }
956 else
957 {
958 headerVisible='block';
959 offsetParent="-7";
960 }
961
962 return ' <table border="0" cellpadding="3" cellspacing="0" style="cursor:default;border-collapse: collapse; position:relative; top: '+offsetParent+';left:3" width="100%">' +
963 ' <tr style="display:'+headerVisible+'">' +
964 ' <td id="BIcon" width="3%" align=left><img id=BIcon src="'+icon+'" style="display:'+imgShow+'"></td>' +
965 ' <td id="BTitle" UNSELECTABLE="on" width="90%" style="'+titleFontStyle+'" align=left>'+iconTitle+'</td>' +
966 ' <td id="BClose" width="3%" valign=top align=right><img src="'+JSBalloonPath+'images/close.jpg" style="position:relative; top: 4;left:-5;display:'+imgClose+'" onmouseover="this.src=\''+JSBalloonPath+'images/closeActive.jpg\'" onmouseout="this.src=\''+JSBalloonPath+'images/close.jpg\'" onmouseup="this.src=\''+JSBalloonPath+'images/closeActive.jpg\'" onmousedown="this.src=\''+JSBalloonPath+'images/closeDown.jpg\'" title="Close"> </td>' +
967 ' </tr>' +
968 ' <tr>' +
969 ' <td id="BBody" UNSELECTABLE="on" style="'+messageFontStyle+'" width="100%" colspan="3">' + ballonBody +'</td>' +
970 ' </tr>' +
971 ' <tr>' +
972 ' <td id="BFooter" UNSELECTABLE="on" style="'+footerFontStyle+'" width="100%" colspan="3">' + footer +'</td>' +
973 ' </tr>' +
974 ' </table>'
975 }
976}
977
978/**//*
979 Section: Usage
980 Examples of the object instantiation.
981
982 Examples:
983
984 (start code)
985 var bl=new JSBalloon({ width:300});
986 var b2=new JSBalloon();
987 var b3=new JSBalloon({ width:150,
988 autoAway:false,
989 autoHide:false,
990 showCloseBox:true});
991
992 (end)
993
994 Section: Include Setup Notes
995 Please read before installing.
996
997 Set the global variable JSBalloonPath to the full application path (or URL) where
998 it is located.
999
1000 Make sure you included the trailing forward slash.
1001
1002 Examples:
1003 - var JSBalloonPath="/appname/includes/js/JSBalloon/";
1004 - var JSBalloonPath="http://prodserver/appname/includes/js/JSBalloon/";
1005*/
1006
posted on 2006-05-10 11:38 komazhang 阅读(1362) 评论(2) 编辑 收藏 举报