1 | (function ($) {
|
2 | $.fn.tooltip = function (options) {
|
3 | var timeout = null,
|
4 | margin = 5;
|
5 |
|
6 |
|
7 | var defaults = {
|
8 | delay: 350,
|
9 | tooltip: '',
|
10 | position: 'bottom',
|
11 | html: false
|
12 | };
|
13 |
|
14 |
|
15 | if (options === "remove") {
|
16 | this.each(function() {
|
17 | $('#' + $(this).attr('data-tooltip-id')).remove();
|
18 | $(this).off('mouseenter.tooltip mouseleave.tooltip');
|
19 | });
|
20 | return false;
|
21 | }
|
22 |
|
23 | options = $.extend(defaults, options);
|
24 |
|
25 | return this.each(function() {
|
26 | var tooltipId = Materialize.guid();
|
27 | var origin = $(this);
|
28 |
|
29 |
|
30 | if (origin.attr('data-tooltip-id')) {
|
31 | $('#' + origin.attr('data-tooltip-id')).remove();
|
32 | }
|
33 |
|
34 | origin.attr('data-tooltip-id', tooltipId);
|
35 |
|
36 |
|
37 | var allowHtml,
|
38 | tooltipDelay,
|
39 | tooltipPosition,
|
40 | tooltipText,
|
41 | tooltipEl,
|
42 | backdrop;
|
43 | var setAttributes = function() {
|
44 | allowHtml = origin.attr('data-html') ? origin.attr('data-html') === 'true' : options.html;
|
45 | tooltipDelay = origin.attr('data-delay');
|
46 | tooltipDelay = (tooltipDelay === undefined || tooltipDelay === '') ?
|
47 | options.delay : tooltipDelay;
|
48 | tooltipPosition = origin.attr('data-position');
|
49 | tooltipPosition = (tooltipPosition === undefined || tooltipPosition === '') ?
|
50 | options.position : tooltipPosition;
|
51 | tooltipText = origin.attr('data-tooltip');
|
52 | tooltipText = (tooltipText === undefined || tooltipText === '') ?
|
53 | options.tooltip : tooltipText;
|
54 | };
|
55 | setAttributes();
|
56 |
|
57 | var renderTooltipEl = function() {
|
58 | var tooltip = $('<div class="material-tooltip"></div>');
|
59 |
|
60 |
|
61 | if (allowHtml) {
|
62 | tooltipText = $('<span></span>').html(tooltipText);
|
63 | } else{
|
64 | tooltipText = $('<span></span>').text(tooltipText);
|
65 | }
|
66 |
|
67 |
|
68 | tooltip.append(tooltipText)
|
69 | .appendTo($('body'))
|
70 | .attr('id', tooltipId);
|
71 |
|
72 |
|
73 | backdrop = $('<div class="backdrop"></div>');
|
74 | backdrop.appendTo(tooltip);
|
75 | return tooltip;
|
76 | };
|
77 | tooltipEl = renderTooltipEl();
|
78 |
|
79 |
|
80 | origin.off('mouseenter.tooltip mouseleave.tooltip');
|
81 |
|
82 | var started = false, timeoutRef;
|
83 | origin.on({'mouseenter.tooltip': function(e) {
|
84 | var showTooltip = function() {
|
85 | setAttributes();
|
86 | started = true;
|
87 | tooltipEl.velocity('stop');
|
88 | backdrop.velocity('stop');
|
89 | tooltipEl.css({ visibility: 'visible', left: '0px', top: '0px' });
|
90 |
|
91 |
|
92 | var originWidth = origin.outerWidth();
|
93 | var originHeight = origin.outerHeight();
|
94 | var tooltipHeight = tooltipEl.outerHeight();
|
95 | var tooltipWidth = tooltipEl.outerWidth();
|
96 | var tooltipVerticalMovement = '0px';
|
97 | var tooltipHorizontalMovement = '0px';
|
98 | var backdropOffsetWidth = backdrop[0].offsetWidth;
|
99 | var backdropOffsetHeight = backdrop[0].offsetHeight;
|
100 | var scaleXFactor = 8;
|
101 | var scaleYFactor = 8;
|
102 | var scaleFactor = 0;
|
103 | var targetTop, targetLeft, newCoordinates;
|
104 |
|
105 | if (tooltipPosition === "top") {
|
106 |
|
107 | targetTop = origin.offset().top - tooltipHeight - margin;
|
108 | targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2;
|
109 | newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
|
110 | tooltipVerticalMovement = '-10px';
|
111 | backdrop.css({
|
112 | bottom: 0,
|
113 | left: 0,
|
114 | borderRadius: '14px 14px 0 0',
|
115 | transformOrigin: '50% 100%',
|
116 | marginTop: tooltipHeight,
|
117 | marginLeft: (tooltipWidth/2) - (backdropOffsetWidth/2)
|
118 | });
|
119 | }
|
120 |
|
121 | else if (tooltipPosition === "left") {
|
122 | targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2;
|
123 | targetLeft = origin.offset().left - tooltipWidth - margin;
|
124 | newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
|
125 |
|
126 | tooltipHorizontalMovement = '-10px';
|
127 | backdrop.css({
|
128 | top: '-7px',
|
129 | right: 0,
|
130 | width: '14px',
|
131 | height: '14px',
|
132 | borderRadius: '14px 0 0 14px',
|
133 | transformOrigin: '95% 50%',
|
134 | marginTop: tooltipHeight/2,
|
135 | marginLeft: tooltipWidth
|
136 | });
|
137 | }
|
138 |
|
139 | else if (tooltipPosition === "right") {
|
140 | targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2;
|
141 | targetLeft = origin.offset().left + originWidth + margin;
|
142 | newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
|
143 |
|
144 | tooltipHorizontalMovement = '+10px';
|
145 | backdrop.css({
|
146 | top: '-7px',
|
147 | left: 0,
|
148 | width: '14px',
|
149 | height: '14px',
|
150 | borderRadius: '0 14px 14px 0',
|
151 | transformOrigin: '5% 50%',
|
152 | marginTop: tooltipHeight/2,
|
153 | marginLeft: '0px'
|
154 | });
|
155 | }
|
156 | else {
|
157 |
|
158 | targetTop = origin.offset().top + origin.outerHeight() + margin;
|
159 | targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2;
|
160 | newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
|
161 | tooltipVerticalMovement = '+10px';
|
162 | backdrop.css({
|
163 | top: 0,
|
164 | left: 0,
|
165 | marginLeft: (tooltipWidth/2) - (backdropOffsetWidth/2)
|
166 | });
|
167 | }
|
168 |
|
169 |
|
170 | tooltipEl.css({
|
171 | top: newCoordinates.y,
|
172 | left: newCoordinates.x
|
173 | });
|
174 |
|
175 |
|
176 | scaleXFactor = Math.SQRT2 * tooltipWidth / parseInt(backdropOffsetWidth);
|
177 | scaleYFactor = Math.SQRT2 * tooltipHeight / parseInt(backdropOffsetHeight);
|
178 | scaleFactor = Math.max(scaleXFactor, scaleYFactor);
|
179 |
|
180 | tooltipEl.velocity({ translateY: tooltipVerticalMovement, translateX: tooltipHorizontalMovement}, { duration: 350, queue: false })
|
181 | .velocity({opacity: 1}, {duration: 300, delay: 50, queue: false});
|
182 | backdrop.css({ visibility: 'visible' })
|
183 | .velocity({opacity:1},{duration: 55, delay: 0, queue: false})
|
184 | .velocity({scaleX: scaleFactor, scaleY: scaleFactor}, {duration: 300, delay: 0, queue: false, easing: 'easeInOutQuad'});
|
185 | };
|
186 |
|
187 | timeoutRef = setTimeout(showTooltip, tooltipDelay);
|
188 |
|
189 |
|
190 | },
|
191 | 'mouseleave.tooltip': function(){
|
192 |
|
193 | started = false;
|
194 | clearTimeout(timeoutRef);
|
195 |
|
196 |
|
197 | setTimeout(function() {
|
198 | if (started !== true) {
|
199 | tooltipEl.velocity({
|
200 | opacity: 0, translateY: 0, translateX: 0}, { duration: 225, queue: false});
|
201 | backdrop.velocity({opacity: 0, scaleX: 1, scaleY: 1}, {
|
202 | duration:225,
|
203 | queue: false,
|
204 | complete: function(){
|
205 | backdrop.css({ visibility: 'hidden' });
|
206 | tooltipEl.css({ visibility: 'hidden' });
|
207 | started = false;}
|
208 | });
|
209 | }
|
210 | },225);
|
211 | }
|
212 | });
|
213 | });
|
214 | };
|
215 |
|
216 | var repositionWithinScreen = function(x, y, width, height) {
|
217 | var newX = x;
|
218 | var newY = y;
|
219 |
|
220 | if (newX < 0) {
|
221 | newX = 4;
|
222 | } else if (newX + width > window.innerWidth) {
|
223 | newX -= newX + width - window.innerWidth;
|
224 | }
|
225 |
|
226 | if (newY < 0) {
|
227 | newY = 4;
|
228 | } else if (newY + height > window.innerHeight + $(window).scrollTop) {
|
229 | newY -= newY + height - window.innerHeight;
|
230 | }
|
231 |
|
232 | return {x: newX, y: newY};
|
233 | };
|
234 |
|
235 | $(document).ready(function(){
|
236 | $('.tooltipped').tooltip();
|
237 | });
|
238 | }( jQuery ));
|