jquery.toolbar.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /**
  2. * Toolbar.js
  3. *
  4. * @fileoverview jQuery plugin that creates tooltip style toolbars.
  5. * @link http://paulkinzett.github.com/toolbar/
  6. * @author Paul Kinzett (http://kinzett.co.nz/)
  7. * @version 1.1.0
  8. * @requires jQuery 1.7+
  9. *
  10. * @license jQuery Toolbar Plugin v1.1.0
  11. * http://paulkinzett.github.com/toolbar/
  12. * Copyright 2013 - 2015 Paul Kinzett (http://kinzett.co.nz/)
  13. * Released under the MIT license.
  14. * <https://raw.github.com/paulkinzett/toolbar/master/LICENSE.txt>
  15. */
  16. if ( typeof Object.create !== 'function' ) {
  17. Object.create = function( obj ) {
  18. function F() {}
  19. F.prototype = obj;
  20. return new F();
  21. };
  22. }
  23. (function( $, window, document, undefined ) {
  24. var ToolBar = {
  25. init: function( options, elem ) {
  26. var self = this;
  27. self.elem = elem;
  28. self.$elem = $( elem );
  29. self.options = $.extend( {}, $.fn.toolbar.options, options );
  30. self.metadata = self.$elem.data();
  31. self.overrideOptions();
  32. self.toolbar = $('<div class="tool-container" />')
  33. .addClass('tool-'+self.options.position)
  34. .addClass('toolbar-'+self.options.style)
  35. .append('<div class="tool-items" />')
  36. .append('<div class="arrow" />')
  37. .appendTo('body')
  38. .css('opacity', 0)
  39. .hide();
  40. self.toolbar_arrow = self.toolbar.find('.arrow');
  41. self.initializeToolbar();
  42. },
  43. overrideOptions: function() {
  44. var self = this;
  45. $.each( self.options, function( $option ) {
  46. if (typeof(self.$elem.data('toolbar-'+$option)) != "undefined") {
  47. self.options[$option] = self.$elem.data('toolbar-'+$option);
  48. }
  49. });
  50. },
  51. initializeToolbar: function() {
  52. var self = this;
  53. self.populateContent();
  54. self.setTrigger();
  55. self.toolbarWidth = self.toolbar.width();
  56. },
  57. setTrigger: function() {
  58. var self = this;
  59. if (self.options.event != 'click') {
  60. var moveTime;
  61. function decideTimeout () {
  62. if (self.$elem.hasClass('pressed')) {
  63. moveTime = setTimeout(function() {
  64. self.hide();
  65. }, 150);
  66. } else {
  67. clearTimeout(moveTime);
  68. };
  69. };
  70. self.$elem.on({
  71. mouseenter: function(event) {
  72. if (self.$elem.hasClass('pressed')) {
  73. clearTimeout(moveTime);
  74. } else {
  75. self.show();
  76. }
  77. }
  78. });
  79. self.$elem.parent().on({
  80. mouseleave: function(event){ decideTimeout(); }
  81. });
  82. $('.tool-container').on({
  83. mouseenter: function(event){ clearTimeout(moveTime); },
  84. mouseleave: function(event){ decideTimeout(); }
  85. });
  86. }
  87. if (self.options.event == 'click') {
  88. self.$elem.on('click', function(event) {
  89. event.preventDefault();
  90. if(self.$elem.hasClass('pressed')) {
  91. self.hide();
  92. } else {
  93. self.show();
  94. }
  95. });
  96. if (self.options.hideOnClick) {
  97. $('html').on("click.toolbar", function ( event ) {
  98. if (event.target != self.elem &&
  99. self.$elem.has(event.target).length === 0 &&
  100. self.toolbar.has(event.target).length === 0 &&
  101. self.toolbar.is(":visible")) {
  102. self.hide();
  103. }
  104. });
  105. }
  106. }
  107. if (self.options.hover) {
  108. var moveTime;
  109. function decideTimeout () {
  110. if (self.$elem.hasClass('pressed')) {
  111. moveTime = setTimeout(function() {
  112. self.hide();
  113. }, 150);
  114. } else {
  115. clearTimeout(moveTime);
  116. };
  117. };
  118. self.$elem.on({
  119. mouseenter: function(event) {
  120. if (self.$elem.hasClass('pressed')) {
  121. clearTimeout(moveTime);
  122. } else {
  123. self.show();
  124. }
  125. }
  126. });
  127. self.$elem.parent().on({
  128. mouseleave: function(event){ decideTimeout(); }
  129. });
  130. $('.tool-container').on({
  131. mouseenter: function(event){ clearTimeout(moveTime); },
  132. mouseleave: function(event){ decideTimeout(); }
  133. });
  134. }
  135. $(window).resize(function( event ) {
  136. event.stopPropagation();
  137. if ( self.toolbar.is(":visible") ) {
  138. self.toolbarCss = self.getCoordinates(self.options.position, 20);
  139. self.collisionDetection();
  140. self.toolbar.css( self.toolbarCss );
  141. self.toolbar_arrow.css( self.arrowCss );
  142. }
  143. });
  144. },
  145. populateContent: function() {
  146. var self = this;
  147. var location = self.toolbar.find('.tool-items');
  148. var content = $(self.options.content).clone( true ).find('a').addClass('tool-item');
  149. location.html(content);
  150. location.find('.tool-item').on('click', function(event) {
  151. event.preventDefault();
  152. self.$elem.trigger('toolbarItemClick', this);
  153. });
  154. },
  155. calculatePosition: function() {
  156. var self = this;
  157. self.arrowCss = {};
  158. self.toolbarCss = self.getCoordinates(self.options.position, self.options.adjustment);
  159. self.toolbarCss.position = 'absolute';
  160. self.toolbarCss.zIndex = self.options.zIndex;
  161. self.collisionDetection();
  162. self.toolbar.css(self.toolbarCss);
  163. self.toolbar_arrow.css(self.arrowCss);
  164. },
  165. getCoordinates: function( position, adjustment ) {
  166. var self = this;
  167. self.coordinates = self.$elem.offset();
  168. if (self.options.adjustment && self.options.adjustment[self.options.position]) {
  169. adjustment = self.options.adjustment[self.options.position] + adjustment;
  170. }
  171. switch(self.options.position) {
  172. case 'top':
  173. return {
  174. left: self.coordinates.left-(self.toolbar.width()/2)+(self.$elem.outerWidth()/2),
  175. top: self.coordinates.top-self.$elem.outerHeight()-adjustment,
  176. right: 'auto'
  177. };
  178. case 'left':
  179. return {
  180. left: self.coordinates.left-(self.toolbar.width()/2)-(self.$elem.outerWidth()/2)-adjustment,
  181. top: self.coordinates.top-(self.toolbar.height()/2)+(self.$elem.outerHeight()/2),
  182. right: 'auto'
  183. };
  184. case 'right':
  185. return {
  186. left: self.coordinates.left+(self.toolbar.width()/2)+(self.$elem.outerWidth()/2)+adjustment,
  187. top: self.coordinates.top-(self.toolbar.height()/2)+(self.$elem.outerHeight()/2),
  188. right: 'auto'
  189. };
  190. case 'bottom':
  191. return {
  192. left: self.coordinates.left-(self.toolbar.width()/2)+(self.$elem.outerWidth()/2),
  193. top: self.coordinates.top+self.$elem.outerHeight()+adjustment,
  194. right: 'auto'
  195. };
  196. }
  197. },
  198. collisionDetection: function() {
  199. var self = this;
  200. var edgeOffset = 20;
  201. if(self.options.position == 'top' || self.options.position == 'bottom') {
  202. self.arrowCss = {left: '50%', right: '50%'};
  203. if( self.toolbarCss.left < edgeOffset ) {
  204. self.toolbarCss.left = edgeOffset;
  205. self.arrowCss.left = self.$elem.offset().left + self.$elem.width()/2-(edgeOffset);
  206. }
  207. else if(($(window).width() - (self.toolbarCss.left + self.toolbarWidth)) < edgeOffset) {
  208. self.toolbarCss.right = edgeOffset;
  209. self.toolbarCss.left = 'auto';
  210. self.arrowCss.left = 'auto';
  211. self.arrowCss.right = ($(window).width()-self.$elem.offset().left)-(self.$elem.width()/2)-(edgeOffset)-5;
  212. }
  213. }
  214. },
  215. show: function() {
  216. var self = this;
  217. self.$elem.addClass('pressed');
  218. self.calculatePosition();
  219. self.toolbar.show().css({'opacity': 1}).addClass('animate-'+self.options.animation);
  220. self.$elem.trigger('toolbarShown');
  221. },
  222. hide: function() {
  223. var self = this;
  224. var animation = {'opacity': 0};
  225. self.$elem.removeClass('pressed');
  226. switch(self.options.position) {
  227. case 'top':
  228. animation.top = '+=20';
  229. break;
  230. case 'left':
  231. animation.left = '+=20';
  232. break;
  233. case 'right':
  234. animation.left = '-=20';
  235. break;
  236. case 'bottom':
  237. animation.top = '-=20';
  238. break;
  239. }
  240. self.toolbar.animate(animation, 200, function() {
  241. self.toolbar.hide();
  242. });
  243. self.$elem.trigger('toolbarHidden');
  244. },
  245. getToolbarElement: function () {
  246. return this.toolbar.find('.tool-items');
  247. }
  248. };
  249. $.fn.toolbar = function( options ) {
  250. if ($.isPlainObject( options )) {
  251. return this.each(function() {
  252. var toolbarObj = Object.create( ToolBar );
  253. toolbarObj.init( options, this );
  254. $(this).data('toolbarObj', toolbarObj);
  255. });
  256. } else if ( typeof options === 'string' && options.indexOf('_') !== 0 ) {
  257. var toolbarObj = $(this).data('toolbarObj');
  258. var method = toolbarObj[options];
  259. return method.apply(toolbarObj, $.makeArray(arguments).slice(1));
  260. }
  261. };
  262. $.fn.toolbar.options = {
  263. content: '#myContent',
  264. position: 'top',
  265. hideOnClick: false,
  266. zIndex: 120,
  267. hover: false,
  268. style: 'default',
  269. animation: 'standard',
  270. adjustment: 10
  271. };
  272. }) ( jQuery, window, document );