1 /*
2 * Copyright (c) 2006 Jonathan Weiss <jw@innerewut.de>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
18 /* tooltip-0.2.js - Small tooltip library on top of Prototype
19 * by Jonathan Weiss <jw@innerewut.de> distributed under the BSD license.
20 *
21 * This tooltip library works in two modes. If it gets a valid DOM element
22 * or DOM id as an argument it uses this element as the tooltip. This
23 * element will be placed (and shown) near the mouse pointer when a trigger-
24 * element is moused-over.
25 * If it gets only a text as an argument instead of a DOM id or DOM element
26 * it will create a div with the classname 'tooltip' that holds the given text.
27 * This newly created div will be used as the tooltip. This is usefull if you
28 * want to use tooltip.js to create popups out of title attributes.
29 *
30 *
31 * Usage:
32 * <script src="/javascripts/prototype.js" type="text/javascript"></script>
33 * <script src="/javascripts/tooltip.js" type="text/javascript"></script>
34 * <script type="text/javascript">
35 * // with valid DOM id
36 * var my_tooltip = new Tooltip('id_of_trigger_element', 'id_of_tooltip_to_show_element')
37 *
38 * // with text
39 * var my_other_tooltip = new Tooltip('id_of_trigger_element', 'a nice description')
40 *
41 * // create popups for each element with a title attribute
42 * Event.observe(window,"load",function() {
43 * $$("*").findAll(function(node){
44 * return node.getAttribute('title');
45 * }).each(function(node){
46 * new Tooltip(node,node.title);
47 * node.removeAttribute("title");
48 * });
49 * });
50 *
51 * </script>
52 *
53 * Now whenever you trigger a mouseOver on the `trigger` element, the tooltip element will
54 * be shown. On o mouseOut the tooltip disappears.
55 *
56 * Example:
57 *
58 * <script src="/javascripts/prototype.js" type="text/javascript"></script>
59 * <script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
60 * <script src="/javascripts/tooltip.js" type="text/javascript"></script>
61 *
62 * <div id='tooltip' style="display:none; margin: 5px; background-color: red;">
63 * Detail infos on product 1....<br />
64 * </div>
65 *
66 * <div id='product_1'>
67 * This is product 1
68 * </div>
69 *
70 * <script type="text/javascript">
71 * var my_tooltip = new Tooltip('product_1', 'tooltip')
72 * </script>
73 *
74 * You can use my_tooltip.destroy() to remove the event observers and thereby the tooltip.
75 */
77 var Tooltip = Class.create();
78 Tooltip.prototype = {
79 initialize: function(element, tool_tip) {
80 var options = Object.extend({
81 default_css: false,
82 margin: "0px",
83 padding: "5px",
84 backgroundColor: "#d6d6fc",
85 min_distance_x: 5,
86 min_distance_y: 5,
87 delta_x: 0,
88 delta_y: 0,
89 zindex: 1000
90 }, arguments[2] || {});
92 this.element = $(element);
94 this.options = options;
96 // use the supplied tooltip element or create our own div
97 if($(tool_tip)) {
98 this.tool_tip = $(tool_tip);
99 } else {
100 this.tool_tip = $(document.createElement("div"));
101 document.body.appendChild(this.tool_tip);
102 this.tool_tip.addClassName("tooltip");
103 this.tool_tip.appendChild(document.createTextNode(tool_tip));
104 }
106 // hide the tool-tip by default
107 this.tool_tip.hide();
109 this.eventMouseOver = this.showTooltip.bindAsEventListener(this);
110 this.eventMouseOut = this.hideTooltip.bindAsEventListener(this);
111 this.eventMouseMove = this.moveTooltip.bindAsEventListener(this);
113 this.registerEvents();
114 },
116 destroy: function() {
117 Event.stopObserving(this.element, "mouseover", this.eventMouseOver);
118 Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
119 Event.stopObserving(this.element, "mousemove", this.eventMouseMove);
120 },
122 registerEvents: function() {
123 Event.observe(this.element, "mouseover", this.eventMouseOver);
124 Event.observe(this.element, "mouseout", this.eventMouseOut);
125 Event.observe(this.element, "mousemove", this.eventMouseMove);
126 },
128 moveTooltip: function(event){
129 Event.stop(event);
130 // get Mouse position
131 var mouse_x = Event.pointerX(event);
132 var mouse_y = Event.pointerY(event);
134 // decide if wee need to switch sides for the tooltip
135 var dimensions = Element.getDimensions( this.tool_tip );
136 var element_width = dimensions.width;
137 var element_height = dimensions.height;
139 if ( (element_width + mouse_x) >= ( this.getWindowWidth() - this.options.min_distance_x) ){ // too big for X
140 mouse_x = mouse_x - element_width;
141 // apply min_distance to make sure that the mouse is not on the tool-tip
142 mouse_x = mouse_x - this.options.min_distance_x;
143 } else {
144 mouse_x = mouse_x + this.options.min_distance_x;
145 }
147 if ( (element_height + mouse_y) >= ( this.getWindowHeight() - this.options.min_distance_y) ){ // too big for Y
148 mouse_y = mouse_y - element_height;
149 // apply min_distance to make sure that the mouse is not on the tool-tip
150 mouse_y = mouse_y - this.options.min_distance_y;
151 } else {
152 mouse_y = mouse_y + this.options.min_distance_y;
153 }
155 // now set the right styles
156 this.setStyles(mouse_x, mouse_y);
157 },
160 showTooltip: function(event) {
161 Event.stop(event);
162 this.moveTooltip(event);
163 new Element.show(this.tool_tip);
164 },
166 setStyles: function(x, y){
167 // set the right styles to position the tool tip
168 Element.setStyle(this.tool_tip, { position:'absolute',
169 top:y + this.options.delta_y + "px",
170 left:x + this.options.delta_x + "px",
171 zindex:this.options.zindex
172 });
174 // apply default theme if wanted
175 if (this.options.default_css){
176 Element.setStyle(this.tool_tip, { margin:this.options.margin,
177 padding:this.options.padding,
178 backgroundColor:this.options.backgroundColor,
179 zindex:this.options.zindex
180 });
181 }
182 },
184 hideTooltip: function(event){
185 new Element.hide(this.tool_tip);
186 },
188 getWindowHeight: function(){
189 var innerHeight;
190 if (navigator.appVersion.indexOf('MSIE')>0) {
191 innerHeight = document.body.clientHeight;
192 } else {
193 innerHeight = window.innerHeight;
194 }
195 return innerHeight;
196 },
198 getWindowWidth: function(){
199 var innerWidth;
200 if (navigator.appVersion.indexOf('MSIE')>0) {
201 innerWidth = document.body.clientWidth;
202 } else {
203 innerWidth = window.innerWidth;
204 }
205 return innerWidth;
206 }
208 }