(function ($) { $.fn.tooltip = function (options) { var timeout = null, margin = 5; // Defaults var defaults = { delay: 350, tooltip: '', position: 'bottom', html: false }; // Remove tooltip from the activator if (options === "remove") { this.each(function() { $('#' + $(this).attr('data-tooltip-id')).remove(); $(this).off('mouseenter.tooltip mouseleave.tooltip'); }); return false; } options = $.extend(defaults, options); return this.each(function() { var tooltipId = Materialize.guid(); var origin = $(this); // Destroy old tooltip if (origin.attr('data-tooltip-id')) { $('#' + origin.attr('data-tooltip-id')).remove(); } origin.attr('data-tooltip-id', tooltipId); // Get attributes. var allowHtml, tooltipDelay, tooltipPosition, tooltipText, tooltipEl, backdrop; var setAttributes = function() { allowHtml = origin.attr('data-html') ? origin.attr('data-html') === 'true' : options.html; tooltipDelay = origin.attr('data-delay'); tooltipDelay = (tooltipDelay === undefined || tooltipDelay === '') ? options.delay : tooltipDelay; tooltipPosition = origin.attr('data-position'); tooltipPosition = (tooltipPosition === undefined || tooltipPosition === '') ? options.position : tooltipPosition; tooltipText = origin.attr('data-tooltip'); tooltipText = (tooltipText === undefined || tooltipText === '') ? options.tooltip : tooltipText; }; setAttributes(); var renderTooltipEl = function() { var tooltip = $('
'); // Create Text span if (allowHtml) { tooltipText = $('').html(tooltipText); } else{ tooltipText = $('').text(tooltipText); } // Create tooltip tooltip.append(tooltipText) .appendTo($('body')) .attr('id', tooltipId); // Create backdrop backdrop = $(''); backdrop.appendTo(tooltip); return tooltip; }; tooltipEl = renderTooltipEl(); // Destroy previously binded events origin.off('mouseenter.tooltip mouseleave.tooltip'); // Mouse In var started = false, timeoutRef; origin.on({'mouseenter.tooltip': function(e) { var showTooltip = function() { setAttributes(); started = true; tooltipEl.velocity('stop'); backdrop.velocity('stop'); tooltipEl.css({ display: 'block', left: '0px', top: '0px' }); // Tooltip positioning var originWidth = origin.outerWidth(); var originHeight = origin.outerHeight(); var tooltipHeight = tooltipEl.outerHeight(); var tooltipWidth = tooltipEl.outerWidth(); var tooltipVerticalMovement = '0px'; var tooltipHorizontalMovement = '0px'; var scaleXFactor = 8; var scaleYFactor = 8; var targetTop, targetLeft, newCoordinates; if (tooltipPosition === "top") { // Top Position targetTop = origin.offset().top - tooltipHeight - margin; targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2; newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); tooltipVerticalMovement = '-10px'; backdrop.css({ bottom: 0, left: 0, borderRadius: '14px 14px 0 0', transformOrigin: '50% 100%', marginTop: tooltipHeight, marginLeft: (tooltipWidth/2) - (backdrop.width()/2) }); } // Left Position else if (tooltipPosition === "left") { targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2; targetLeft = origin.offset().left - tooltipWidth - margin; newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); tooltipHorizontalMovement = '-10px'; backdrop.css({ top: '-7px', right: 0, width: '14px', height: '14px', borderRadius: '14px 0 0 14px', transformOrigin: '95% 50%', marginTop: tooltipHeight/2, marginLeft: tooltipWidth }); } // Right Position else if (tooltipPosition === "right") { targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2; targetLeft = origin.offset().left + originWidth + margin; newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); tooltipHorizontalMovement = '+10px'; backdrop.css({ top: '-7px', left: 0, width: '14px', height: '14px', borderRadius: '0 14px 14px 0', transformOrigin: '5% 50%', marginTop: tooltipHeight/2, marginLeft: '0px' }); } else { // Bottom Position targetTop = origin.offset().top + origin.outerHeight() + margin; targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2; newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); tooltipVerticalMovement = '+10px'; backdrop.css({ top: 0, left: 0, marginLeft: (tooltipWidth/2) - (backdrop.width()/2) }); } // Set tooptip css placement tooltipEl.css({ top: newCoordinates.y, left: newCoordinates.x }); // Calculate Scale to fill scaleXFactor = Math.SQRT2 * tooltipWidth / parseInt(backdrop.css('width')); scaleYFactor = Math.SQRT2 * tooltipHeight / parseInt(backdrop.css('height')); tooltipEl.velocity({ marginTop: tooltipVerticalMovement, marginLeft: tooltipHorizontalMovement}, { duration: 350, queue: false }) .velocity({opacity: 1}, {duration: 300, delay: 50, queue: false}); backdrop.css({ display: 'block' }) .velocity({opacity:1},{duration: 55, delay: 0, queue: false}) .velocity({scaleX: scaleXFactor, scaleY: scaleYFactor}, {duration: 300, delay: 0, queue: false, easing: 'easeInOutQuad'}); }; timeoutRef = setTimeout(showTooltip, tooltipDelay); // End Interval // Mouse Out }, 'mouseleave.tooltip': function(){ // Reset State started = false; clearTimeout(timeoutRef); // Animate back setTimeout(function() { if (started !== true) { tooltipEl.velocity({ opacity: 0, marginTop: 0, marginLeft: 0}, { duration: 225, queue: false}); backdrop.velocity({opacity: 0, scaleX: 1, scaleY: 1}, { duration:225, queue: false, complete: function(){ backdrop.css('display', 'none'); tooltipEl.css('display', 'none'); started = false;} }); } },225); } }); }); }; var repositionWithinScreen = function(x, y, width, height) { var newX = x; var newY = y; if (newX < 0) { newX = 4; } else if (newX + width > window.innerWidth) { newX -= newX + width - window.innerWidth; } if (newY < 0) { newY = 4; } else if (newY + height > window.innerHeight + $(window).scrollTop) { newY -= newY + height - window.innerHeight; } return {x: newX, y: newY}; }; $(document).on('turbolinks:load', function(){ $('.tooltipped').tooltip(); }); }( jQuery ));